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

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 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
It is also based on my RFC patches, which can be seen at:
https://lists.nongnu.org/archive/html/qemu-devel/2014-09/msg01638.html

This patch series makes some changes to the armv7m_init function
that allows the code to be reused with the Netduino 2 and the
Stellaris machines.

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

Changes from RFC:
 - Code cleanup thanks to Peter C's comments
 - Split the Makefile configs to device level
 - Changes to armv7m_init with interupt and memory passing
    - See the individual patches for more details


Alistair Francis (8):
  stm32f205_timer: Add the stm32f205 Timer
  stm32f205_USART: Add the stm32f205 USART Controller
  stm32f205_SYSCFG: Add the stm32f205 SYSCFG
  target_arm: Remove memory region init from armv7m_init
  target_arm: Parameterise the irq lines for armv7m_init
  target_arm: Change the reset values based on the ELF entry
  stm32f205: Add the stm32f205 SoC
  netduino2: Add the Netduino 2 Machine

 default-configs/arm-softmmu.mak    |   4 +
 hw/arm/Makefile.objs               |   2 +
 hw/arm/armv7m.c                    |  46 +++---
 hw/arm/netduino2.c                 |  54 +++++++
 hw/arm/stellaris.c                 |  25 ++-
 hw/arm/stm32f205_soc.c             | 155 +++++++++++++++++++
 hw/char/Makefile.objs              |   1 +
 hw/char/stm32f205_usart.c          | 213 ++++++++++++++++++++++++++
 hw/misc/Makefile.objs              |   1 +
 hw/misc/stm32f205_syscfg.c         | 160 +++++++++++++++++++
 hw/timer/Makefile.objs             |   1 +
 hw/timer/stm32f205_timer.c         | 305 +++++++++++++++++++++++++++++++++++++
 include/hw/arm/arm.h               |   2 +-
 include/hw/arm/stm32f205_soc.h     |  69 +++++++++
 include/hw/char/stm32f205_usart.h  |  67 ++++++++
 include/hw/misc/stm32f205_syscfg.h |  61 ++++++++
 include/hw/timer/stm32f205_timer.h |  97 ++++++++++++
 17 files changed, 1236 insertions(+), 27 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] 20+ messages in thread

* [Qemu-devel] [Patch v1 1/8] stm32f205_timer: Add the stm32f205 Timer
  2014-09-14  8:18 [Qemu-devel] [Patch v1 0/8] Netduino 2 Machine Model Alistair Francis
@ 2014-09-14  8:18 ` Alistair Francis
  2014-09-15 15:01   ` Peter Crosthwaite
  2014-09-14  8:18 ` [Qemu-devel] [Patch v1 2/8] stm32f205_USART: Add the stm32f205 USART Controller Alistair Francis
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 20+ messages in thread
From: Alistair Francis @ 2014-09-14  8:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, peter.crosthwaite, konstanty, martin.galvan

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

Signed-off-by: Alistair Francis <alistair23@gmail.com>
---
Changes from RFC:
 - Small changes to functionality and style. Thanks to Peter C
 - Rename to make the timer more generic
 - Split the config settings to device level

 default-configs/arm-softmmu.mak    |   1 +
 hw/timer/Makefile.objs             |   1 +
 hw/timer/stm32f205_timer.c         | 305 +++++++++++++++++++++++++++++++++++++
 include/hw/timer/stm32f205_timer.h |  97 ++++++++++++
 4 files changed, 404 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..cf23b24 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_STM32F205_TIMER=y
 
 CONFIG_VERSATILE_PCI=y
 CONFIG_VERSATILE_I2C=y
diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index 2c86c3d..6c1661e 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_STM32F205_TIMER) += 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..c4a84eb
--- /dev/null
+++ b/hw/timer/stm32f205_timer.c
@@ -0,0 +1,305 @@
+/*
+ * STM32F205 Timer
+ *
+ * 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 STM_TIMER_ERR_DEBUG
+#define STM_TIMER_ERR_DEBUG 0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+    if (STM_TIMER_ERR_DEBUG >= lvl) { \
+        qemu_log("stm32f205_timer: %s:" fmt, __func__, ## args); \
+    } \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+static void stm32f205_timer_interrupt(void *opaque)
+{
+    STM32f205TimerState *s = opaque;
+
+    DB_PRINT("Interrupt in: %s\n", __func__);
+
+    if (s->tim_dier & TIM_DIER_UIE && s->tim_cr1 & TIM_CR1_CEN) {
+        s->tim_sr |= 1;
+        qemu_irq_pulse(s->irq);
+    }
+}
+
+static void stm32f205_timer_set_alarm(STM32f205TimerState *s)
+{
+    uint32_t ticks;
+    int64_t now;
+
+    DB_PRINT("Alarm raised in: %s at 0x%x\n", __func__, s->tim_cr1);
+
+    now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+    ticks = s->tim_arr - (s->tick_offset + (now / get_ticks_per_sec())) *
+            (s->tim_psc + 1);
+
+    DB_PRINT("Alarm set in %d ticks\n", ticks);
+
+    if (ticks == 0) {
+        timer_del(s->timer);
+        stm32f205_timer_interrupt(s);
+    } else {
+        timer_mod(s->timer, (now + (int64_t) ticks));
+        DB_PRINT("Wait Time: %u\n", (uint32_t) (now + ticks));
+    }
+}
+
+static void stm32f205_timer_reset(DeviceState *dev)
+{
+    STM32f205TimerState *s = STM32F205TIMER(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 stm32f205_timer_read(void *opaque, hwaddr offset,
+                           unsigned size)
+{
+    STM32f205TimerState *s = opaque;
+
+    DB_PRINT("Read 0x%"HWADDR_PRIx"\n", 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,
+                      "STM32F205_timer_write: Bad offset %x\n", (int) offset);
+    }
+
+    return 0;
+}
+
+static void stm32f205_timer_write(void *opaque, hwaddr offset,
+                        uint64_t val64, unsigned size)
+{
+    STM32f205TimerState *s = opaque;
+    uint32_t value = val64;
+
+    DB_PRINT("Write 0x%x, 0x%"HWADDR_PRIx"\n", value, 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;
+        stm32f205_timer_set_alarm(s);
+        return;
+    case TIM_EGR:
+        s->tim_egr = value;
+        if (s->tim_egr & 1) {
+            /* Re-init the counter */
+            stm32f205_timer_reset(DEVICE(s));
+        }
+        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;
+        stm32f205_timer_set_alarm(s);
+        return;
+    case TIM_PSC:
+        s->tim_psc = value;
+        return;
+    case TIM_ARR:
+        s->tim_arr = value;
+        stm32f205_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,
+                      "STM32F205_timer_write: Bad offset %x\n", (int) offset);
+    }
+}
+
+static const MemoryRegionOps stm32f205_timer_ops = {
+    .read = stm32f205_timer_read,
+    .write = stm32f205_timer_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void stm32f205_timer_init(Object *obj)
+{
+    STM32f205TimerState *s = STM32F205TIMER(obj);
+    struct tm tm;
+
+    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
+
+    memory_region_init_io(&s->iomem, obj, &stm32f205_timer_ops, s,
+                          "stm32f205_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(QEMU_CLOCK_VIRTUAL) / get_ticks_per_sec();
+
+    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, stm32f205_timer_interrupt, s);
+}
+
+static const VMStateDescription vmstate_stm32f205_timer = {
+    .name = "stm32f205_timer",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .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 stm32f205_timer_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->vmsd = &vmstate_stm32f205_timer;
+    dc->reset = stm32f205_timer_reset;
+}
+
+static const TypeInfo stm32f205_timer_info = {
+    .name          = TYPE_STM32F205_TIMER,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(STM32f205TimerState),
+    .instance_init = stm32f205_timer_init,
+    .class_init    = stm32f205_timer_class_init,
+};
+
+static void stm32f205_timer_register_types(void)
+{
+    type_register_static(&stm32f205_timer_info);
+}
+
+type_init(stm32f205_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..c26ae57
--- /dev/null
+++ b/include/hw/timer/stm32f205_timer.h
@@ -0,0 +1,97 @@
+/*
+ * STM32F205 Timer
+ *
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef HW_STM_TIMER_H
+#define HW_STM_TIMER_H
+
+#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 TIM_CCER_CC2E   (1 << 4)
+#define TIM_CCMR1_OC2M2 (1 << 14)
+#define TIM_CCMR1_OC2M1 (1 << 13)
+
+#define TIM_DIER_UIE  1
+
+#define TYPE_STM32F205_TIMER "stm32f205-timer"
+#define STM32F205TIMER(obj) OBJECT_CHECK(STM32f205TimerState, \
+                            (obj), TYPE_STM32F205_TIMER)
+
+typedef struct STM32f205TimerState {
+    /* <private> */
+    SysBusDevice parent_obj;
+
+    /* <public> */
+    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;
+
+#endif
-- 
1.9.1

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

* [Qemu-devel] [Patch v1 2/8] stm32f205_USART: Add the stm32f205 USART Controller
  2014-09-14  8:18 [Qemu-devel] [Patch v1 0/8] Netduino 2 Machine Model Alistair Francis
  2014-09-14  8:18 ` [Qemu-devel] [Patch v1 1/8] stm32f205_timer: Add the stm32f205 Timer Alistair Francis
@ 2014-09-14  8:18 ` Alistair Francis
  2014-09-15 15:11   ` Peter Crosthwaite
  2014-09-14  8:18 ` [Qemu-devel] [Patch v1 3/8] stm32f205_SYSCFG: Add the stm32f205 SYSCFG Alistair Francis
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 20+ messages in thread
From: Alistair Francis @ 2014-09-14  8:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, peter.crosthwaite, konstanty, martin.galvan

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

Signed-off-by: Alistair Francis <alistair23@gmail.com>
---
Changes from RFC:
 - Small changes thanks to Peter C
 - USART now implements QEMU blocking functions
 - Split the config settings to device level

 default-configs/arm-softmmu.mak   |   1 +
 hw/char/Makefile.objs             |   1 +
 hw/char/stm32f205_usart.c         | 213 ++++++++++++++++++++++++++++++++++++++
 include/hw/char/stm32f205_usart.h |  67 ++++++++++++
 4 files changed, 282 insertions(+)
 create mode 100644 hw/char/stm32f205_usart.c
 create mode 100644 include/hw/char/stm32f205_usart.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index cf23b24..422dec0 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -79,6 +79,7 @@ CONFIG_REALVIEW=y
 CONFIG_ZAURUS=y
 CONFIG_ZYNQ=y
 CONFIG_STM32F205_TIMER=y
+CONFIG_STM32F205_USART=y
 
 CONFIG_VERSATILE_PCI=y
 CONFIG_VERSATILE_I2C=y
diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
index 317385d..c7b3ce4 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_STM32F205_USART) += 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..1274e69
--- /dev/null
+++ b/hw/char/stm32f205_usart.c
@@ -0,0 +1,213 @@
+/*
+ * STM32F205 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) { \
+        qemu_log("stm32f205_usart: %s:" fmt, __func__, ## args); \
+    } \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+static int stm32f205_usart_can_receive(void *opaque)
+{
+    STM32f205UsartState *s = opaque;
+
+    if (s->usart_cr1 & USART_CR1_UE && s->usart_cr1 & USART_CR1_RE &&
+        !(s->usart_sr & USART_SR_RXNE)) {
+        return 1;
+    }
+
+    return 0;
+}
+
+static void stm32f205_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 stm32f205_usart_reset(DeviceState *dev)
+{
+    STM32f205UsartState *s = STM32F205_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 stm32f205_usart_read(void *opaque, hwaddr addr,
+                                       unsigned int size)
+{
+    STM32f205UsartState *s = opaque;
+    uint64_t retvalue;
+
+    DB_PRINT("Read 0x%"HWADDR_PRIx"\n", addr);
+
+    switch (addr) {
+    case USART_SR:
+        retvalue = s->usart_sr;
+        s->usart_sr &= ~USART_SR_TC;
+        if (s->chr) {
+            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;
+        s->usart_sr &= ~USART_SR_RXNE;
+        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,
+                      "STM32F205_usart_read: Bad offset " \
+                      "0x%"HWADDR_PRIx"\n", addr);
+        return 0;
+    }
+
+    return 0;
+}
+
+static void stm32f205_usart_write(void *opaque, hwaddr addr,
+                       uint64_t val64, unsigned int size)
+{
+    STM32f205UsartState *s = opaque;
+    uint32_t value = val64;
+    unsigned char ch;
+
+    DB_PRINT("Write 0x%x, 0x%"HWADDR_PRIx"\n", value, 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_all(s->chr, &ch, 1);
+            }
+            s->usart_sr |= USART_SR_TC;
+            s->usart_sr &= ~USART_SR_TXE;
+        }
+        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,
+                      "STM32F205_usart_write: Bad offset " \
+                      "0x%"HWADDR_PRIx"\n", addr);
+    }
+}
+
+static const MemoryRegionOps stm32f205_usart_ops = {
+    .read = stm32f205_usart_read,
+    .write = stm32f205_usart_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void stm32f205_usart_init(Object *obj)
+{
+    STM32f205UsartState *s = STM32F205_USART(obj);
+
+    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
+
+    memory_region_init_io(&s->mmio, obj, &stm32f205_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, stm32f205_usart_can_receive,
+                              stm32f205_usart_receive, NULL, s);
+    }
+}
+
+static void stm32f205_usart_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->reset = stm32f205_usart_reset;
+}
+
+static const TypeInfo stm32f205_usart_info = {
+    .name          = TYPE_STM32F205_USART,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(STM32f205UsartState),
+    .instance_init = stm32f205_usart_init,
+    .class_init    = stm32f205_usart_class_init,
+};
+
+static void stm32f205_usart_register_types(void)
+{
+    type_register_static(&stm32f205_usart_info);
+}
+
+type_init(stm32f205_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..a08cd04
--- /dev/null
+++ b/include/hw/char/stm32f205_usart.h
@@ -0,0 +1,67 @@
+/*
+ * STM32F205 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 USART_CR1_RE  (1 << 2)
+
+#define TYPE_STM32F205_USART "stm32f205-usart"
+#define STM32F205_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;
-- 
1.9.1

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

* [Qemu-devel] [Patch v1 3/8] stm32f205_SYSCFG: Add the stm32f205 SYSCFG
  2014-09-14  8:18 [Qemu-devel] [Patch v1 0/8] Netduino 2 Machine Model Alistair Francis
  2014-09-14  8:18 ` [Qemu-devel] [Patch v1 1/8] stm32f205_timer: Add the stm32f205 Timer Alistair Francis
  2014-09-14  8:18 ` [Qemu-devel] [Patch v1 2/8] stm32f205_USART: Add the stm32f205 USART Controller Alistair Francis
@ 2014-09-14  8:18 ` Alistair Francis
  2014-09-14  8:18 ` [Qemu-devel] [Patch v1 4/8] target_arm: Remove memory region init from armv7m_init Alistair Francis
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 20+ messages in thread
From: Alistair Francis @ 2014-09-14  8:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, peter.crosthwaite, konstanty, martin.galvan

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>
---
Changes from RFC:
 - Split the config settings to device level

 default-configs/arm-softmmu.mak    |   1 +
 hw/misc/Makefile.objs              |   1 +
 hw/misc/stm32f205_syscfg.c         | 160 +++++++++++++++++++++++++++++++++++++
 include/hw/misc/stm32f205_syscfg.h |  61 ++++++++++++++
 4 files changed, 223 insertions(+)
 create mode 100644 hw/misc/stm32f205_syscfg.c
 create mode 100644 include/hw/misc/stm32f205_syscfg.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 422dec0..a2ea8f7 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -80,6 +80,7 @@ CONFIG_ZAURUS=y
 CONFIG_ZYNQ=y
 CONFIG_STM32F205_TIMER=y
 CONFIG_STM32F205_USART=y
+CONFIG_STM32F205_SYSCFG=y
 
 CONFIG_VERSATILE_PCI=y
 CONFIG_VERSATILE_I2C=y
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 979e532..63f03bd 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_STM32F205_SYSCFG) += 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..9c0eb07
--- /dev/null
+++ b/hw/misc/stm32f205_syscfg.c
@@ -0,0 +1,160 @@
+/*
+ * STM32F205 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) { \
+        qemu_log("stm32f205_syscfg: %s:" fmt, __func__, ## args); \
+    } \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+static void stm32f205_syscfg_reset(DeviceState *dev)
+{
+    STM32f205SyscfgState *s = STM32F205_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 stm32f205_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,
+                      "STM32F205_syscfg_read: Bad offset %x\n", (int)addr);
+        return 0;
+    }
+
+    return 0;
+}
+
+static void stm32f205_syscfg_write(void *opaque, hwaddr addr,
+                       uint64_t val64, unsigned int size)
+{
+    STM32f205SyscfgState *s = opaque;
+    uint32_t value = val64;
+
+    DB_PRINT("0x%x, 0x%x\n", value, (uint) addr);
+
+    switch (addr) {
+    case SYSCFG_MEMRMP:
+        qemu_log_mask(LOG_UNIMP,
+                      "STM32F205_syscfg_write: Changeing the memory mapping " \
+                      "isn't supported in QEMU\n");
+        return;
+    case SYSCFG_PMC:
+        qemu_log_mask(LOG_UNIMP,
+                      "STM32F205_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,
+                      "STM32F205_syscfg_write: Bad offset %x\n", (int)addr);
+    }
+}
+
+static const MemoryRegionOps stm32f205_syscfg_ops = {
+    .read = stm32f205_syscfg_read,
+    .write = stm32f205_syscfg_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void stm32f205_syscfg_init(Object *obj)
+{
+    STM32f205SyscfgState *s = STM32F205_SYSCFG(obj);
+
+    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
+
+    memory_region_init_io(&s->mmio, obj, &stm32f205_syscfg_ops, s,
+                          TYPE_STM32F205_SYSCFG, 0x2000);
+    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
+}
+
+static void stm32f205_syscfg_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->reset = stm32f205_syscfg_reset;
+}
+
+static const TypeInfo stm32f205_syscfg_info = {
+    .name          = TYPE_STM32F205_SYSCFG,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(STM32f205SyscfgState),
+    .instance_init = stm32f205_syscfg_init,
+    .class_init    = stm32f205_syscfg_class_init,
+};
+
+static void stm32f205_syscfg_register_types(void)
+{
+    type_register_static(&stm32f205_syscfg_info);
+}
+
+type_init(stm32f205_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..9c5556f
--- /dev/null
+++ b/include/hw/misc/stm32f205_syscfg.h
@@ -0,0 +1,61 @@
+/*
+ * STM32F205 SYSCFG
+ *
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef HW_STM_SYSCFG_H
+#define HW_STM_SYSCFG_H
+
+#include "hw/sysbus.h"
+#include "hw/hw.h"
+
+#define SYSCFG_MEMRMP  0x00
+#define SYSCFG_PMC     0x04
+#define SYSCFG_EXTICR1 0x08
+#define SYSCFG_EXTICR2 0x0C
+#define SYSCFG_EXTICR3 0x10
+#define SYSCFG_EXTICR4 0x14
+#define SYSCFG_CMPCR   0x20
+
+#define TYPE_STM32F205_SYSCFG "stm32f205-syscfg"
+#define STM32F205_SYSCFG(obj) \
+    OBJECT_CHECK(STM32f205SyscfgState, (obj), TYPE_STM32F205_SYSCFG)
+
+typedef struct {
+    /* <private> */
+    SysBusDevice parent_obj;
+
+    /* <public> */
+    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] 20+ messages in thread

* [Qemu-devel] [Patch v1 4/8] target_arm: Remove memory region init from armv7m_init
  2014-09-14  8:18 [Qemu-devel] [Patch v1 0/8] Netduino 2 Machine Model Alistair Francis
                   ` (2 preceding siblings ...)
  2014-09-14  8:18 ` [Qemu-devel] [Patch v1 3/8] stm32f205_SYSCFG: Add the stm32f205 SYSCFG Alistair Francis
@ 2014-09-14  8:18 ` Alistair Francis
  2014-09-15 15:20   ` Peter Crosthwaite
  2014-09-14  8:18 ` [Qemu-devel] [Patch v1 5/8] target_arm: Parameterise the irq lines for armv7m_init Alistair Francis
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 20+ messages in thread
From: Alistair Francis @ 2014-09-14  8:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, peter.crosthwaite, konstanty, martin.galvan

This patch moves the memory region init code from the
armv7m_init function to the stellaris_init function

Signed-off-by: Alistair Francis <alistair23@gmail.com>
---
 hw/arm/armv7m.c    | 15 +--------------
 hw/arm/stellaris.c | 23 +++++++++++++++++++----
 2 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index aedef13..5c1f7b3 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -163,7 +163,7 @@ static void armv7m_reset(void *opaque)
 }
 
 /* Init CPU and memory for a v7-M based board.
-   flash_size and sram_size are in kb.
+   flash_size and sram_size are in bytes.
    Returns the NVIC array.  */
 
 qemu_irq *armv7m_init(MemoryRegion *system_memory,
@@ -180,13 +180,8 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory,
     uint64_t lowaddr;
     int i;
     int big_endian;
-    MemoryRegion *sram = g_new(MemoryRegion, 1);
-    MemoryRegion *flash = g_new(MemoryRegion, 1);
     MemoryRegion *hack = g_new(MemoryRegion, 1);
 
-    flash_size *= 1024;
-    sram_size *= 1024;
-
     if (cpu_model == NULL) {
 	cpu_model = "cortex-m3";
     }
@@ -209,14 +204,6 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory,
     code_size = ram_size - sram_size;
 #endif
 
-    /* Flash programming is done via the SCU, so pretend it is ROM.  */
-    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_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");
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
index 64bd4b4..3c8e9d1 100644
--- a/hw/arm/stellaris.c
+++ b/hw/arm/stellaris.c
@@ -1220,10 +1220,25 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
     int i;
     int j;
 
-    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);
+    MemoryRegion *sram = g_new(MemoryRegion, 1);
+    MemoryRegion *flash = g_new(MemoryRegion, 1);
+    MemoryRegion *system_memory = get_system_memory();
+
+    flash_size = (((board->dc0 & 0xffff) + 1) << 1) * 1024;
+    sram_size = ((board->dc0 >> 18) + 1) * 1024;
+
+    /* Flash programming is done via the SCU, so pretend it is ROM.  */
+    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_init_ram(sram, NULL, "armv7m.sram", sram_size);
+    vmstate_register_ram_global(sram);
+    memory_region_add_subregion(system_memory, 0x20000000, sram);
+
+    pic = armv7m_init(system_memory, flash_size, sram_size,
+                      kernel_filename, cpu_model);
 
     if (board->dc1 & (1 << 16)) {
         dev = sysbus_create_varargs(TYPE_STELLARIS_ADC, 0x40038000,
-- 
1.9.1

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

* [Qemu-devel] [Patch v1 5/8] target_arm: Parameterise the irq lines for armv7m_init
  2014-09-14  8:18 [Qemu-devel] [Patch v1 0/8] Netduino 2 Machine Model Alistair Francis
                   ` (3 preceding siblings ...)
  2014-09-14  8:18 ` [Qemu-devel] [Patch v1 4/8] target_arm: Remove memory region init from armv7m_init Alistair Francis
@ 2014-09-14  8:18 ` Alistair Francis
  2014-09-15 15:23   ` Peter Crosthwaite
  2014-09-14  8:19 ` [Qemu-devel] [Patch v1 6/8] target_arm: Change the reset values based on the ELF entry Alistair Francis
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 20+ messages in thread
From: Alistair Francis @ 2014-09-14  8:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, peter.crosthwaite, konstanty, martin.galvan

This patch allows the board to specifiy the number of NVIC interrupt
lines when using armv7m_init.

Signed-off-by: Alistair Francis <alistair23@gmail.com>
---
 hw/arm/armv7m.c      | 7 ++++---
 hw/arm/stellaris.c   | 4 +++-
 include/hw/arm/arm.h | 2 +-
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index 5c1f7b3..5e684a0 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -167,14 +167,14 @@ 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, 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;
@@ -207,11 +207,12 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory,
     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);
     }
 
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
index 3c8e9d1..e4da1fb 100644
--- a/hw/arm/stellaris.c
+++ b/hw/arm/stellaris.c
@@ -29,6 +29,8 @@
 #define BP_OLED_SSI  0x02
 #define BP_GAMEPAD   0x04
 
+#define NUM_IRQ_LINES 64
+
 typedef const struct {
     const char *name;
     uint32_t did0;
@@ -1238,7 +1240,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
     memory_region_add_subregion(system_memory, 0x20000000, sram);
 
     pic = armv7m_init(system_memory, flash_size, sram_size,
-                      kernel_filename, cpu_model);
+                      NUM_IRQ_LINES, 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..3e7c463 100644
--- a/include/hw/arm/arm.h
+++ b/include/hw/arm/arm.h
@@ -16,7 +16,7 @@
 
 /* armv7m.c */
 qemu_irq *armv7m_init(MemoryRegion *system_memory,
-                      int flash_size, int sram_size,
+                      int flash_size, 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] 20+ messages in thread

* [Qemu-devel] [Patch v1 6/8] target_arm: Change the reset values based on the ELF entry
  2014-09-14  8:18 [Qemu-devel] [Patch v1 0/8] Netduino 2 Machine Model Alistair Francis
                   ` (4 preceding siblings ...)
  2014-09-14  8:18 ` [Qemu-devel] [Patch v1 5/8] target_arm: Parameterise the irq lines for armv7m_init Alistair Francis
@ 2014-09-14  8:19 ` Alistair Francis
  2014-09-15 15:27   ` Peter Crosthwaite
  2014-09-14  8:19 ` [Qemu-devel] [Patch v1 7/8] stm32f205: Add the stm32f205 SoC Alistair Francis
  2014-09-14  8:19 ` [Qemu-devel] [Patch v1 8/8] netduino2: Add the Netduino 2 Machine Alistair Francis
  7 siblings, 1 reply; 20+ messages in thread
From: Alistair Francis @ 2014-09-14  8:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, peter.crosthwaite, konstanty, martin.galvan

The Netduino 2 machine won't run unless the reset_pc is based
on the ELF entry point.

Signed-off-by: Alistair Francis <alistair23@gmail.com>
---
 hw/arm/armv7m.c | 24 +++++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index 5e684a0..816b651 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -155,11 +155,19 @@ static void armv7m_bitband_init(void)
 
 /* Board init.  */
 
-static void armv7m_reset(void *opaque)
-{
-    ARMCPU *cpu = opaque;
+typedef struct ARMV7MResetArgs {
+    ARMCPU *cpu;
+    uint32_t reset_pc;
+} ARMV7MResetArgs;
+
+ static void armv7m_reset(void *opaque)
+ {
+    ARMV7MResetArgs *args = opaque;
+
+    cpu_reset(CPU(args->cpu));
 
-    cpu_reset(CPU(cpu));
+    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.
@@ -181,6 +189,7 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory,
     int i;
     int big_endian;
     MemoryRegion *hack = g_new(MemoryRegion, 1);
+    ARMV7MResetArgs reset_args;
 
     if (cpu_model == NULL) {
 	cpu_model = "cortex-m3";
@@ -247,7 +256,12 @@ 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,
+    };
+    qemu_register_reset(armv7m_reset,
+                        g_memdup(&reset_args, sizeof(reset_args)));
     return pic;
 }
 
-- 
1.9.1

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

* [Qemu-devel] [Patch v1 7/8] stm32f205: Add the stm32f205 SoC
  2014-09-14  8:18 [Qemu-devel] [Patch v1 0/8] Netduino 2 Machine Model Alistair Francis
                   ` (5 preceding siblings ...)
  2014-09-14  8:19 ` [Qemu-devel] [Patch v1 6/8] target_arm: Change the reset values based on the ELF entry Alistair Francis
@ 2014-09-14  8:19 ` Alistair Francis
  2014-09-14  8:19 ` [Qemu-devel] [Patch v1 8/8] netduino2: Add the Netduino 2 Machine Alistair Francis
  7 siblings, 0 replies; 20+ messages in thread
From: Alistair Francis @ 2014-09-14  8:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, peter.crosthwaite, konstanty, martin.galvan

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>
---
Changes from RFC:
 - Small changes thanks to Peter C
 - Split the config settings to device level

 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs            |   1 +
 hw/arm/stm32f205_soc.c          | 155 ++++++++++++++++++++++++++++++++++++++++
 include/hw/arm/stm32f205_soc.h  |  69 ++++++++++++++++++
 4 files changed, 226 insertions(+)
 create mode 100644 hw/arm/stm32f205_soc.c
 create mode 100644 include/hw/arm/stm32f205_soc.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index a2ea8f7..8068100 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -81,6 +81,7 @@ CONFIG_ZYNQ=y
 CONFIG_STM32F205_TIMER=y
 CONFIG_STM32F205_USART=y
 CONFIG_STM32F205_SYSCFG=y
+CONFIG_STM32F205_SOC=y
 
 CONFIG_VERSATILE_PCI=y
 CONFIG_VERSATILE_I2C=y
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 6088e53..9769317 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -8,3 +8,4 @@ obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
 obj-$(CONFIG_DIGIC) += digic.o
 obj-y += omap1.o omap2.o strongarm.o
 obj-$(CONFIG_ALLWINNER_A10) += allwinner-a10.o cubieboard.o
+obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c
new file mode 100644
index 0000000..3fa0af6
--- /dev/null
+++ b/hw/arm/stm32f205_soc.c
@@ -0,0 +1,155 @@
+/*
+ * STM32F205 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"
+
+/* At the moment only Timer 2 to 5 are modelled */
+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};
+
+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)
+{
+    STM32F205State *s = STM32F205_SOC(dev_soc);
+    DeviceState *syscfgdev, *usartdev, *timerdev;
+    SysBusDevice *syscfgbusdev, *usartbusdev, *timerbusdev;
+    qemu_irq *pic;;
+    Error *err = NULL;
+    int i;
+
+    MemoryRegion *system_memory = get_system_memory();
+    MemoryRegion *sram = g_new(MemoryRegion, 1);
+    MemoryRegion *flash = g_new(MemoryRegion, 1);
+    MemoryRegion *flash_alias = g_new(MemoryRegion, 1);
+
+    memory_region_init_ram(flash, NULL, "netduino.flash", FLASH_SIZE);
+    memory_region_init_alias(flash_alias, NULL, "netduino.flash.alias",
+                             flash, 0, FLASH_SIZE);
+
+    vmstate_register_ram_global(flash);
+
+    memory_region_set_readonly(flash, true);
+    memory_region_set_readonly(flash_alias, true);
+
+    memory_region_add_subregion(system_memory, FLASH_BASE_ADDRESS, flash);
+    memory_region_add_subregion(system_memory, 0, flash_alias);
+
+    memory_region_init_ram(sram, NULL, "netduino.sram", SRAM_SIZE);
+    vmstate_register_ram_global(sram);
+    memory_region_add_subregion(system_memory, SRAM_BASE_ADDRESS, sram);
+
+    pic = armv7m_init(get_system_memory(),
+                      FLASH_SIZE, SRAM_SIZE, 96,
+                      s->kernel_filename, s->cpu_model);
+
+    /* System configuration controller */
+    syscfgdev = DEVICE(&s->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 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_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..addc555
--- /dev/null
+++ b/include/hw/arm/stm32f205_soc.h
@@ -0,0 +1,69 @@
+/*
+ * STM32F205 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)
+
+#define STM_NUM_USARTS 5
+#define STM_NUM_TIMERS 5
+
+#define FLASH_BASE_ADDRESS 0x08000000
+#define FLASH_SIZE (1024 * 1024)
+#define SRAM_BASE_ADDRESS 0x20000000
+#define SRAM_SIZE (128 * 1024)
+
+typedef struct STM32F205State {
+    /*< private >*/
+    SysBusDevice parent_obj;
+    /*< public >*/
+
+    char *kernel_filename;
+    char *cpu_model;
+
+    STM32f205SyscfgState syscfg;
+    STM32f205UsartState usart[STM_NUM_USARTS];
+    STM32f205TimerState timer[STM_NUM_TIMERS];
+} STM32F205State;
+
+#endif
-- 
1.9.1

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

* [Qemu-devel] [Patch v1 8/8] netduino2: Add the Netduino 2 Machine
  2014-09-14  8:18 [Qemu-devel] [Patch v1 0/8] Netduino 2 Machine Model Alistair Francis
                   ` (6 preceding siblings ...)
  2014-09-14  8:19 ` [Qemu-devel] [Patch v1 7/8] stm32f205: Add the stm32f205 SoC Alistair Francis
@ 2014-09-14  8:19 ` Alistair Francis
  7 siblings, 0 replies; 20+ messages in thread
From: Alistair Francis @ 2014-09-14  8:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, peter.crosthwaite, konstanty, martin.galvan

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>
---
Changes from RFC:
 - Remove CPU passthrough

 hw/arm/Makefile.objs |  1 +
 hw/arm/netduino2.c   | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+)
 create mode 100644 hw/arm/netduino2.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 9769317..2577f68 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -3,6 +3,7 @@ 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 += netduino2.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..305983f
--- /dev/null
+++ b/hw/arm/netduino2.c
@@ -0,0 +1,54 @@
+/*
+ * 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;
+    Error *err = NULL;
+
+    dev = qdev_create(NULL, TYPE_STM32F205_SOC);
+    if (machine->kernel_filename) {
+        qdev_prop_set_string(dev, "kernel-filename", machine->kernel_filename);
+    }
+    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] 20+ messages in thread

* Re: [Qemu-devel] [Patch v1 1/8] stm32f205_timer: Add the stm32f205 Timer
  2014-09-14  8:18 ` [Qemu-devel] [Patch v1 1/8] stm32f205_timer: Add the stm32f205 Timer Alistair Francis
@ 2014-09-15 15:01   ` Peter Crosthwaite
  2014-09-19  2:00     ` Alistair Francis
  0 siblings, 1 reply; 20+ messages in thread
From: Peter Crosthwaite @ 2014-09-15 15:01 UTC (permalink / raw)
  To: Alistair Francis
  Cc: Peter Maydell, Martin Galvan, qemu-devel@nongnu.org Developers,
	Konstanty Bialkowski

On Sun, Sep 14, 2014 at 6:18 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>
> ---
> Changes from RFC:
>  - Small changes to functionality and style. Thanks to Peter C
>  - Rename to make the timer more generic
>  - Split the config settings to device level
>
>  default-configs/arm-softmmu.mak    |   1 +
>  hw/timer/Makefile.objs             |   1 +
>  hw/timer/stm32f205_timer.c         | 305 +++++++++++++++++++++++++++++++++++++
>  include/hw/timer/stm32f205_timer.h |  97 ++++++++++++
>  4 files changed, 404 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..cf23b24 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_STM32F205_TIMER=y
>
>  CONFIG_VERSATILE_PCI=y
>  CONFIG_VERSATILE_I2C=y
> diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
> index 2c86c3d..6c1661e 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_STM32F205_TIMER) += stm32f205_timer.o
>

The grouping of this with the random SoC configs is a little strange.
I suggest just creating your own blank-line separated grouping like
with allwinner currently at the bottom.

>  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..c4a84eb
> --- /dev/null
> +++ b/hw/timer/stm32f205_timer.c
> @@ -0,0 +1,305 @@
> +/*
> + * STM32F205 Timer
> + *
> + * 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 STM_TIMER_ERR_DEBUG
> +#define STM_TIMER_ERR_DEBUG 0
> +#endif
> +
> +#define DB_PRINT_L(lvl, fmt, args...) do { \
> +    if (STM_TIMER_ERR_DEBUG >= lvl) { \
> +        qemu_log("stm32f205_timer: %s:" fmt, __func__, ## args); \
> +    } \
> +} while (0);
> +
> +#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
> +
> +static void stm32f205_timer_interrupt(void *opaque)
> +{
> +    STM32f205TimerState *s = opaque;
> +
> +    DB_PRINT("Interrupt in: %s\n", __func__);
> +
> +    if (s->tim_dier & TIM_DIER_UIE && s->tim_cr1 & TIM_CR1_CEN) {
> +        s->tim_sr |= 1;
> +        qemu_irq_pulse(s->irq);
> +    }
> +}
> +
> +static void stm32f205_timer_set_alarm(STM32f205TimerState *s)
> +{
> +    uint32_t ticks;
> +    int64_t now;
> +
> +    DB_PRINT("Alarm raised in: %s at 0x%x\n", __func__, s->tim_cr1);
> +

You already %s __func__ as part of the DB_PRINT so no need for the dup.

> +    now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> +    ticks = s->tim_arr - (s->tick_offset + (now / get_ticks_per_sec())) *
> +            (s->tim_psc + 1);

I'm having trouble with the dimensional analysis of this. tim_arr is
in terms of counter cycles but ticks must be in terms of ns (with it's
addition to now below). So you have equating of cycles to time
implying fixed frequency scaling. However you attempt to model the
prescaling with your use of tim_psc?

> +
> +    DB_PRINT("Alarm set in %d ticks\n", ticks);
> +
> +    if (ticks == 0) {
> +        timer_del(s->timer);
> +        stm32f205_timer_interrupt(s);
> +    } else {
> +        timer_mod(s->timer, (now + (int64_t) ticks));
> +        DB_PRINT("Wait Time: %u\n", (uint32_t) (now + ticks));

Better to use a PRId64 and drop the cast so the debug messages still
look good after now rolls over 4G.

> +    }
> +}
> +
> +static void stm32f205_timer_reset(DeviceState *dev)
> +{
> +    STM32f205TimerState *s = STM32F205TIMER(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 stm32f205_timer_read(void *opaque, hwaddr offset,
> +                           unsigned size)
> +{
> +    STM32f205TimerState *s = opaque;
> +
> +    DB_PRINT("Read 0x%"HWADDR_PRIx"\n", 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,
> +                      "STM32F205_timer_write: Bad offset %x\n", (int) offset);
> +    }
> +
> +    return 0;
> +}
> +
> +static void stm32f205_timer_write(void *opaque, hwaddr offset,
> +                        uint64_t val64, unsigned size)
> +{
> +    STM32f205TimerState *s = opaque;
> +    uint32_t value = val64;
> +
> +    DB_PRINT("Write 0x%x, 0x%"HWADDR_PRIx"\n", value, 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;

Took some getting my head around the &= but TRM does say set by
hardware and cleared by software. Worth a comment?

> +        stm32f205_timer_set_alarm(s);

This doesn't look right. I think you might be trying to implement
periodic timing by reloading when the guest clears the ISR. This is
guest dependent and will also lose time - unless the TRM says that
timer halts based on ISR? (which I would find quite strange).

The reload logic should probably happen from the timer callback itself.

You may need to look into some of the other timers and how they
implement accurate periodic timing. You can look at ptimer based
implementations of which there a fair few. I recently did some work on
arm_mptimer which is a periodic capable timer that uses regular QEMU
timers which I consider a good simple example of a QEMU timer that
doesn't use ptimer.

> +        return;
> +    case TIM_EGR:
> +        s->tim_egr = value;
> +        if (s->tim_egr & 1) {
> +            /* Re-init the counter */
> +            stm32f205_timer_reset(DEVICE(s));
> +        }
> +        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;
> +        stm32f205_timer_set_alarm(s);
> +        return;
> +    case TIM_PSC:
> +        s->tim_psc = value;
> +        return;
> +    case TIM_ARR:
> +        s->tim_arr = value;
> +        stm32f205_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,
> +                      "STM32F205_timer_write: Bad offset %x\n", (int) offset);

Missed a HWADDR_PRIx.

> +    }
> +}
> +
> +static const MemoryRegionOps stm32f205_timer_ops = {
> +    .read = stm32f205_timer_read,
> +    .write = stm32f205_timer_write,
> +    .endianness = DEVICE_NATIVE_ENDIAN,
> +};
> +
> +static void stm32f205_timer_init(Object *obj)
> +{
> +    STM32f205TimerState *s = STM32F205TIMER(obj);
> +    struct tm tm;
> +
> +    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
> +
> +    memory_region_init_io(&s->iomem, obj, &stm32f205_timer_ops, s,
> +                          "stm32f205_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(QEMU_CLOCK_VIRTUAL) / get_ticks_per_sec();
> +

This is still trying to be an RTC of sorts. You don't need the
mktimegm stuff. I think you need to refactor tick_offset as according
to this it is in terms of seconds, but that doesn't make a lot of
sense for this timer which should trade in high frequency clock cycles
or ns I think.

Regards,
Peter

> +    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, stm32f205_timer_interrupt, s);
> +}
> +
> +static const VMStateDescription vmstate_stm32f205_timer = {
> +    .name = "stm32f205_timer",
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .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 stm32f205_timer_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +
> +    dc->vmsd = &vmstate_stm32f205_timer;
> +    dc->reset = stm32f205_timer_reset;
> +}
> +
> +static const TypeInfo stm32f205_timer_info = {
> +    .name          = TYPE_STM32F205_TIMER,
> +    .parent        = TYPE_SYS_BUS_DEVICE,
> +    .instance_size = sizeof(STM32f205TimerState),
> +    .instance_init = stm32f205_timer_init,
> +    .class_init    = stm32f205_timer_class_init,
> +};
> +
> +static void stm32f205_timer_register_types(void)
> +{
> +    type_register_static(&stm32f205_timer_info);
> +}
> +
> +type_init(stm32f205_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..c26ae57
> --- /dev/null
> +++ b/include/hw/timer/stm32f205_timer.h
> @@ -0,0 +1,97 @@
> +/*
> + * STM32F205 Timer
> + *
> + * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a copy
> + * of this software and associated documentation files (the "Software"), to deal
> + * in the Software without restriction, including without limitation the rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + */
> +
> +#ifndef HW_STM_TIMER_H
> +#define HW_STM_TIMER_H
> +
> +#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 TIM_CCER_CC2E   (1 << 4)
> +#define TIM_CCMR1_OC2M2 (1 << 14)
> +#define TIM_CCMR1_OC2M1 (1 << 13)
> +
> +#define TIM_DIER_UIE  1
> +
> +#define TYPE_STM32F205_TIMER "stm32f205-timer"
> +#define STM32F205TIMER(obj) OBJECT_CHECK(STM32f205TimerState, \
> +                            (obj), TYPE_STM32F205_TIMER)
> +
> +typedef struct STM32f205TimerState {
> +    /* <private> */
> +    SysBusDevice parent_obj;
> +
> +    /* <public> */
> +    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;
> +
> +#endif
> --
> 1.9.1
>
>

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

* Re: [Qemu-devel] [Patch v1 2/8] stm32f205_USART: Add the stm32f205 USART Controller
  2014-09-14  8:18 ` [Qemu-devel] [Patch v1 2/8] stm32f205_USART: Add the stm32f205 USART Controller Alistair Francis
@ 2014-09-15 15:11   ` Peter Crosthwaite
  2014-09-19  2:22     ` Alistair Francis
  0 siblings, 1 reply; 20+ messages in thread
From: Peter Crosthwaite @ 2014-09-15 15:11 UTC (permalink / raw)
  To: Alistair Francis
  Cc: Peter Maydell, Martin Galvan, qemu-devel@nongnu.org Developers,
	Konstanty Bialkowski

On Sun, Sep 14, 2014 at 6:18 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>
> ---
> Changes from RFC:
>  - Small changes thanks to Peter C
>  - USART now implements QEMU blocking functions
>  - Split the config settings to device level
>
>  default-configs/arm-softmmu.mak   |   1 +
>  hw/char/Makefile.objs             |   1 +
>  hw/char/stm32f205_usart.c         | 213 ++++++++++++++++++++++++++++++++++++++
>  include/hw/char/stm32f205_usart.h |  67 ++++++++++++
>  4 files changed, 282 insertions(+)
>  create mode 100644 hw/char/stm32f205_usart.c
>  create mode 100644 include/hw/char/stm32f205_usart.h
>
> diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
> index cf23b24..422dec0 100644
> --- a/default-configs/arm-softmmu.mak
> +++ b/default-configs/arm-softmmu.mak
> @@ -79,6 +79,7 @@ CONFIG_REALVIEW=y
>  CONFIG_ZAURUS=y
>  CONFIG_ZYNQ=y
>  CONFIG_STM32F205_TIMER=y
> +CONFIG_STM32F205_USART=y
>
>  CONFIG_VERSATILE_PCI=y
>  CONFIG_VERSATILE_I2C=y
> diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
> index 317385d..c7b3ce4 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_STM32F205_USART) += 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..1274e69
> --- /dev/null
> +++ b/hw/char/stm32f205_usart.c
> @@ -0,0 +1,213 @@
> +/*
> + * STM32F205 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) { \
> +        qemu_log("stm32f205_usart: %s:" fmt, __func__, ## args); \
> +    } \
> +} while (0);
> +
> +#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
> +
> +static int stm32f205_usart_can_receive(void *opaque)
> +{
> +    STM32f205UsartState *s = opaque;
> +
> +    if (s->usart_cr1 & USART_CR1_UE && s->usart_cr1 & USART_CR1_RE &&

So this is still gating based on the master enable. I think these
first two terms in the && need to be dropped ...

> +        !(s->usart_sr & USART_SR_RXNE)) {
> +        return 1;
> +    }
> +
> +    return 0;
> +}
> +
> +static void stm32f205_usart_receive(void *opaque, const uint8_t *buf, int size)
> +{
> +    STM32f205UsartState *s = opaque;
> +
> +    s->usart_dr = *buf;
> +

and here:

if (!s->usart_cr1 & USART_CR1_UE && s->usart_cr1 & USART_CR1_RE) {
   return; /* not enabled - drop chars */
}

This means the UART will drop chars when its disabled, which would be
consistent with real HW (there is no buffering when the sender sends
chars to a disabled UART).

> +    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 stm32f205_usart_reset(DeviceState *dev)
> +{
> +    STM32f205UsartState *s = STM32F205_USART(dev);
> +
> +    s->usart_sr = 0x00C00000;

Just define a macro for this field and set it for self documentation.

> +    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 stm32f205_usart_read(void *opaque, hwaddr addr,
> +                                       unsigned int size)
> +{
> +    STM32f205UsartState *s = opaque;
> +    uint64_t retvalue;
> +
> +    DB_PRINT("Read 0x%"HWADDR_PRIx"\n", addr);
> +
> +    switch (addr) {
> +    case USART_SR:
> +        retvalue = s->usart_sr;
> +        s->usart_sr &= ~USART_SR_TC;
> +        if (s->chr) {
> +            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);

PRIx32 to match type of usart_dr.

> +        s->usart_sr |= USART_SR_TXE;
> +        s->usart_sr &= ~USART_SR_RXNE;
> +        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,
> +                      "STM32F205_usart_read: Bad offset " \
> +                      "0x%"HWADDR_PRIx"\n", addr);
> +        return 0;
> +    }
> +
> +    return 0;
> +}
> +
> +static void stm32f205_usart_write(void *opaque, hwaddr addr,
> +                       uint64_t val64, unsigned int size)
> +{
> +    STM32f205UsartState *s = opaque;
> +    uint32_t value = val64;
> +    unsigned char ch;
> +
> +    DB_PRINT("Write 0x%x, 0x%"HWADDR_PRIx"\n", value, addr);
> +

PRIx64 for value.

Regards,
Peter

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

* Re: [Qemu-devel] [Patch v1 4/8] target_arm: Remove memory region init from armv7m_init
  2014-09-14  8:18 ` [Qemu-devel] [Patch v1 4/8] target_arm: Remove memory region init from armv7m_init Alistair Francis
@ 2014-09-15 15:20   ` Peter Crosthwaite
  2014-09-15 15:36     ` Paolo Bonzini
  2014-09-16  2:37     ` Alistair Francis
  0 siblings, 2 replies; 20+ messages in thread
From: Peter Crosthwaite @ 2014-09-15 15:20 UTC (permalink / raw)
  To: Alistair Francis, Paolo Bonzini
  Cc: Peter Maydell, Martin Galvan, qemu-devel@nongnu.org Developers,
	Konstanty Bialkowski

On Sun, Sep 14, 2014 at 6:18 PM, Alistair Francis <alistair23@gmail.com> wrote:
> This patch moves the memory region init code from the
> armv7m_init function to the stellaris_init function
>
> Signed-off-by: Alistair Francis <alistair23@gmail.com>
> ---
>  hw/arm/armv7m.c    | 15 +--------------
>  hw/arm/stellaris.c | 23 +++++++++++++++++++----
>  2 files changed, 20 insertions(+), 18 deletions(-)
>
> diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
> index aedef13..5c1f7b3 100644
> --- a/hw/arm/armv7m.c
> +++ b/hw/arm/armv7m.c
> @@ -163,7 +163,7 @@ static void armv7m_reset(void *opaque)
>  }
>
>  /* Init CPU and memory for a v7-M based board.
> -   flash_size and sram_size are in kb.
> +   flash_size and sram_size are in bytes.
>     Returns the NVIC array.  */
>
>  qemu_irq *armv7m_init(MemoryRegion *system_memory,
> @@ -180,13 +180,8 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory,
>      uint64_t lowaddr;
>      int i;
>      int big_endian;
> -    MemoryRegion *sram = g_new(MemoryRegion, 1);
> -    MemoryRegion *flash = g_new(MemoryRegion, 1);
>      MemoryRegion *hack = g_new(MemoryRegion, 1);
>
> -    flash_size *= 1024;
> -    sram_size *= 1024;
> -
>      if (cpu_model == NULL) {
>         cpu_model = "cortex-m3";
>      }
> @@ -209,14 +204,6 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory,
>      code_size = ram_size - sram_size;
>  #endif
>
> -    /* Flash programming is done via the SCU, so pretend it is ROM.  */
> -    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_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");
> diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
> index 64bd4b4..3c8e9d1 100644
> --- a/hw/arm/stellaris.c
> +++ b/hw/arm/stellaris.c
> @@ -1220,10 +1220,25 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
>      int i;
>      int j;
>
> -    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);
> +    MemoryRegion *sram = g_new(MemoryRegion, 1);
> +    MemoryRegion *flash = g_new(MemoryRegion, 1);
> +    MemoryRegion *system_memory = get_system_memory();
> +
> +    flash_size = (((board->dc0 & 0xffff) + 1) << 1) * 1024;
> +    sram_size = ((board->dc0 >> 18) + 1) * 1024;
> +
> +    /* Flash programming is done via the SCU, so pretend it is ROM.  */
> +    memory_region_init_ram(flash, NULL, "armv7m.flash", flash_size);

You can give this a better name, such as "stellaris.flash" now that we
are not in armv7m anymore.

Paolo, do you have any advice as to whether we should attempt to
parent this MR to the machine or something or just stay NULL
(considering we are in non-qdevified code?).

> +    vmstate_register_ram_global(flash);
> +    memory_region_set_readonly(flash, true);
> +    memory_region_add_subregion(system_memory, 0, flash);
> +
> +    memory_region_init_ram(sram, NULL, "armv7m.sram", sram_size);

Ditto.

> +    vmstate_register_ram_global(sram);
> +    memory_region_add_subregion(system_memory, 0x20000000, sram);
> +
> +    pic = armv7m_init(system_memory, flash_size, sram_size,
> +                      kernel_filename, cpu_model);
>

Can you drop the flash_size and sram_size args to armv7m? They should
be dead now.

Regards,
Peter

>      if (board->dc1 & (1 << 16)) {
>          dev = sysbus_create_varargs(TYPE_STELLARIS_ADC, 0x40038000,
> --
> 1.9.1
>
>

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

* Re: [Qemu-devel] [Patch v1 5/8] target_arm: Parameterise the irq lines for armv7m_init
  2014-09-14  8:18 ` [Qemu-devel] [Patch v1 5/8] target_arm: Parameterise the irq lines for armv7m_init Alistair Francis
@ 2014-09-15 15:23   ` Peter Crosthwaite
  2014-09-16  2:43     ` Alistair Francis
  0 siblings, 1 reply; 20+ messages in thread
From: Peter Crosthwaite @ 2014-09-15 15:23 UTC (permalink / raw)
  To: Alistair Francis
  Cc: Peter Maydell, Martin Galvan, qemu-devel@nongnu.org Developers,
	Konstanty Bialkowski

On Sun, Sep 14, 2014 at 6:18 PM, Alistair Francis <alistair23@gmail.com> wrote:
> This patch allows the board to specifiy the number of NVIC interrupt
> lines when using armv7m_init.
>
> Signed-off-by: Alistair Francis <alistair23@gmail.com>
> ---
>  hw/arm/armv7m.c      | 7 ++++---
>  hw/arm/stellaris.c   | 4 +++-
>  include/hw/arm/arm.h | 2 +-
>  3 files changed, 8 insertions(+), 5 deletions(-)
>
> diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
> index 5c1f7b3..5e684a0 100644
> --- a/hw/arm/armv7m.c
> +++ b/hw/arm/armv7m.c
> @@ -167,14 +167,14 @@ 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, int sram_size, int num_irq,

This will change slightly based on previous patch comment, but otherwise.

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

>                        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;
> @@ -207,11 +207,12 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory,
>      armv7m_bitband_init();
>
>      nvic = qdev_create(NULL, "armv7m_nvic");
> +    qdev_prop_set_uint32(nvic, "num-irq", num_irq);

Curious, was this previously relying on the default for nvic being 64?
(hence this is appearing as purely additive).

Regards,
Peter

>      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);
>      }
>
> diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
> index 3c8e9d1..e4da1fb 100644
> --- a/hw/arm/stellaris.c
> +++ b/hw/arm/stellaris.c
> @@ -29,6 +29,8 @@
>  #define BP_OLED_SSI  0x02
>  #define BP_GAMEPAD   0x04
>
> +#define NUM_IRQ_LINES 64
> +
>  typedef const struct {
>      const char *name;
>      uint32_t did0;
> @@ -1238,7 +1240,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
>      memory_region_add_subregion(system_memory, 0x20000000, sram);
>
>      pic = armv7m_init(system_memory, flash_size, sram_size,
> -                      kernel_filename, cpu_model);
> +                      NUM_IRQ_LINES, 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..3e7c463 100644
> --- a/include/hw/arm/arm.h
> +++ b/include/hw/arm/arm.h
> @@ -16,7 +16,7 @@
>
>  /* armv7m.c */
>  qemu_irq *armv7m_init(MemoryRegion *system_memory,
> -                      int flash_size, int sram_size,
> +                      int flash_size, 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] 20+ messages in thread

* Re: [Qemu-devel] [Patch v1 6/8] target_arm: Change the reset values based on the ELF entry
  2014-09-14  8:19 ` [Qemu-devel] [Patch v1 6/8] target_arm: Change the reset values based on the ELF entry Alistair Francis
@ 2014-09-15 15:27   ` Peter Crosthwaite
  2014-09-16  2:40     ` Alistair Francis
  0 siblings, 1 reply; 20+ messages in thread
From: Peter Crosthwaite @ 2014-09-15 15:27 UTC (permalink / raw)
  To: Alistair Francis
  Cc: Peter Maydell, Martin Galvan, qemu-devel@nongnu.org Developers,
	Konstanty Bialkowski

On Sun, Sep 14, 2014 at 6:19 PM, Alistair Francis <alistair23@gmail.com> wrote:
> The Netduino 2 machine won't run unless the reset_pc is based
> on the ELF entry point.
>
> Signed-off-by: Alistair Francis <alistair23@gmail.com>

Looks based on one of my early attempts at same problem so:

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>

> ---
>  hw/arm/armv7m.c | 24 +++++++++++++++++++-----
>  1 file changed, 19 insertions(+), 5 deletions(-)
>
> diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
> index 5e684a0..816b651 100644
> --- a/hw/arm/armv7m.c
> +++ b/hw/arm/armv7m.c
> @@ -155,11 +155,19 @@ static void armv7m_bitband_init(void)
>
>  /* Board init.  */
>
> -static void armv7m_reset(void *opaque)
> -{
> -    ARMCPU *cpu = opaque;
> +typedef struct ARMV7MResetArgs {
> +    ARMCPU *cpu;
> +    uint32_t reset_pc;
> +} ARMV7MResetArgs;
> +
> + static void armv7m_reset(void *opaque)
> + {
> +    ARMV7MResetArgs *args = opaque;
> +
> +    cpu_reset(CPU(args->cpu));
>
> -    cpu_reset(CPU(cpu));
> +    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.
> @@ -181,6 +189,7 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory,
>      int i;
>      int big_endian;
>      MemoryRegion *hack = g_new(MemoryRegion, 1);
> +    ARMV7MResetArgs reset_args;
Malloc straight away rather than the gmemdup.

ARMV7MResetArgs *reset_args = g_new0(ARMV7MResetArgs, 1);

>
>      if (cpu_model == NULL) {
>         cpu_model = "cortex-m3";
> @@ -247,7 +256,12 @@ 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,
> +    };
> +    qemu_register_reset(armv7m_reset,
> +                        g_memdup(&reset_args, sizeof(reset_args)));


Regards,
Peter

>      return pic;
>  }
>
> --
> 1.9.1
>
>

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

* Re: [Qemu-devel] [Patch v1 4/8] target_arm: Remove memory region init from armv7m_init
  2014-09-15 15:20   ` Peter Crosthwaite
@ 2014-09-15 15:36     ` Paolo Bonzini
  2014-09-16  2:37     ` Alistair Francis
  1 sibling, 0 replies; 20+ messages in thread
From: Paolo Bonzini @ 2014-09-15 15:36 UTC (permalink / raw)
  To: Peter Crosthwaite, Alistair Francis
  Cc: Peter Maydell, Martin Galvan, qemu-devel@nongnu.org Developers,
	Konstanty Bialkowski

Il 15/09/2014 17:20, Peter Crosthwaite ha scritto:
>> > +    /* Flash programming is done via the SCU, so pretend it is ROM.  */
>> > +    memory_region_init_ram(flash, NULL, "armv7m.flash", flash_size);
> You can give this a better name, such as "stellaris.flash" now that we
> are not in armv7m anymore.
> 
> Paolo, do you have any advice as to whether we should attempt to
> parent this MR to the machine or something or just stay NULL
> (considering we are in non-qdevified code?).

The machine is the default owner anyway.

Paolo

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

* Re: [Qemu-devel] [Patch v1 4/8] target_arm: Remove memory region init from armv7m_init
  2014-09-15 15:20   ` Peter Crosthwaite
  2014-09-15 15:36     ` Paolo Bonzini
@ 2014-09-16  2:37     ` Alistair Francis
  1 sibling, 0 replies; 20+ messages in thread
From: Alistair Francis @ 2014-09-16  2:37 UTC (permalink / raw)
  To: Peter Crosthwaite
  Cc: Konstanty Bialkowski, Paolo Bonzini, Martin Galvan,
	qemu-devel@nongnu.org Developers, Peter Maydell

On Tue, Sep 16, 2014 at 1:20 AM, Peter Crosthwaite
<peter.crosthwaite@xilinx.com> wrote:
> On Sun, Sep 14, 2014 at 6:18 PM, Alistair Francis <alistair23@gmail.com> wrote:
>> This patch moves the memory region init code from the
>> armv7m_init function to the stellaris_init function
>>
>> Signed-off-by: Alistair Francis <alistair23@gmail.com>
>> ---
>>  hw/arm/armv7m.c    | 15 +--------------
>>  hw/arm/stellaris.c | 23 +++++++++++++++++++----
>>  2 files changed, 20 insertions(+), 18 deletions(-)
>>
>> diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
>> index aedef13..5c1f7b3 100644
>> --- a/hw/arm/armv7m.c
>> +++ b/hw/arm/armv7m.c
>> @@ -163,7 +163,7 @@ static void armv7m_reset(void *opaque)
>>  }
>>
>>  /* Init CPU and memory for a v7-M based board.
>> -   flash_size and sram_size are in kb.
>> +   flash_size and sram_size are in bytes.
>>     Returns the NVIC array.  */
>>
>>  qemu_irq *armv7m_init(MemoryRegion *system_memory,
>> @@ -180,13 +180,8 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory,
>>      uint64_t lowaddr;
>>      int i;
>>      int big_endian;
>> -    MemoryRegion *sram = g_new(MemoryRegion, 1);
>> -    MemoryRegion *flash = g_new(MemoryRegion, 1);
>>      MemoryRegion *hack = g_new(MemoryRegion, 1);
>>
>> -    flash_size *= 1024;
>> -    sram_size *= 1024;
>> -
>>      if (cpu_model == NULL) {
>>         cpu_model = "cortex-m3";
>>      }
>> @@ -209,14 +204,6 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory,
>>      code_size = ram_size - sram_size;
>>  #endif
>>
>> -    /* Flash programming is done via the SCU, so pretend it is ROM.  */
>> -    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_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");
>> diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
>> index 64bd4b4..3c8e9d1 100644
>> --- a/hw/arm/stellaris.c
>> +++ b/hw/arm/stellaris.c
>> @@ -1220,10 +1220,25 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
>>      int i;
>>      int j;
>>
>> -    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);
>> +    MemoryRegion *sram = g_new(MemoryRegion, 1);
>> +    MemoryRegion *flash = g_new(MemoryRegion, 1);
>> +    MemoryRegion *system_memory = get_system_memory();
>> +
>> +    flash_size = (((board->dc0 & 0xffff) + 1) << 1) * 1024;
>> +    sram_size = ((board->dc0 >> 18) + 1) * 1024;
>> +
>> +    /* Flash programming is done via the SCU, so pretend it is ROM.  */
>> +    memory_region_init_ram(flash, NULL, "armv7m.flash", flash_size);
>
> You can give this a better name, such as "stellaris.flash" now that we
> are not in armv7m anymore.

Will fix

>
> Paolo, do you have any advice as to whether we should attempt to
> parent this MR to the machine or something or just stay NULL
> (considering we are in non-qdevified code?).
>
>> +    vmstate_register_ram_global(flash);
>> +    memory_region_set_readonly(flash, true);
>> +    memory_region_add_subregion(system_memory, 0, flash);
>> +
>> +    memory_region_init_ram(sram, NULL, "armv7m.sram", sram_size);
>
> Ditto.
>
>> +    vmstate_register_ram_global(sram);
>> +    memory_region_add_subregion(system_memory, 0x20000000, sram);
>> +
>> +    pic = armv7m_init(system_memory, flash_size, sram_size,
>> +                      kernel_filename, cpu_model);
>>
>
> Can you drop the flash_size and sram_size args to armv7m? They should
> be dead now.

Both are still required. The load_image_targphys() requires the flash size and
there is some code that uses sram_size, although it is constantly #if disabled.
I'm not sure why it's there, but it would have to be removed if the
sram_size is.
It's something to do with greater then 32MB of SRAM overwriting the
bitband area.

>
> Regards,
> Peter
>
>>      if (board->dc1 & (1 << 16)) {
>>          dev = sysbus_create_varargs(TYPE_STELLARIS_ADC, 0x40038000,
>> --
>> 1.9.1
>>
>>

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

* Re: [Qemu-devel] [Patch v1 6/8] target_arm: Change the reset values based on the ELF entry
  2014-09-15 15:27   ` Peter Crosthwaite
@ 2014-09-16  2:40     ` Alistair Francis
  0 siblings, 0 replies; 20+ messages in thread
From: Alistair Francis @ 2014-09-16  2:40 UTC (permalink / raw)
  To: Peter Crosthwaite
  Cc: Peter Maydell, Martin Galvan, qemu-devel@nongnu.org Developers,
	Konstanty Bialkowski

On Tue, Sep 16, 2014 at 1:27 AM, Peter Crosthwaite
<peter.crosthwaite@xilinx.com> wrote:
> On Sun, Sep 14, 2014 at 6:19 PM, Alistair Francis <alistair23@gmail.com> wrote:
>> The Netduino 2 machine won't run unless the reset_pc is based
>> on the ELF entry point.
>>
>> Signed-off-by: Alistair Francis <alistair23@gmail.com>
>
> Looks based on one of my early attempts at same problem so:
>
> Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
>

Sorry, I forgot about that

>> ---
>>  hw/arm/armv7m.c | 24 +++++++++++++++++++-----
>>  1 file changed, 19 insertions(+), 5 deletions(-)
>>
>> diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
>> index 5e684a0..816b651 100644
>> --- a/hw/arm/armv7m.c
>> +++ b/hw/arm/armv7m.c
>> @@ -155,11 +155,19 @@ static void armv7m_bitband_init(void)
>>
>>  /* Board init.  */
>>
>> -static void armv7m_reset(void *opaque)
>> -{
>> -    ARMCPU *cpu = opaque;
>> +typedef struct ARMV7MResetArgs {
>> +    ARMCPU *cpu;
>> +    uint32_t reset_pc;
>> +} ARMV7MResetArgs;
>> +
>> + static void armv7m_reset(void *opaque)
>> + {
>> +    ARMV7MResetArgs *args = opaque;
>> +
>> +    cpu_reset(CPU(args->cpu));
>>
>> -    cpu_reset(CPU(cpu));
>> +    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.
>> @@ -181,6 +189,7 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory,
>>      int i;
>>      int big_endian;
>>      MemoryRegion *hack = g_new(MemoryRegion, 1);
>> +    ARMV7MResetArgs reset_args;
> Malloc straight away rather than the gmemdup.
>
> ARMV7MResetArgs *reset_args = g_new0(ARMV7MResetArgs, 1);
>

Will fix

Thanks,

Alistair

>>
>>      if (cpu_model == NULL) {
>>         cpu_model = "cortex-m3";
>> @@ -247,7 +256,12 @@ 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,
>> +    };
>> +    qemu_register_reset(armv7m_reset,
>> +                        g_memdup(&reset_args, sizeof(reset_args)));
>
>
> Regards,
> Peter
>
>>      return pic;
>>  }
>>
>> --
>> 1.9.1
>>
>>

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

* Re: [Qemu-devel] [Patch v1 5/8] target_arm: Parameterise the irq lines for armv7m_init
  2014-09-15 15:23   ` Peter Crosthwaite
@ 2014-09-16  2:43     ` Alistair Francis
  0 siblings, 0 replies; 20+ messages in thread
From: Alistair Francis @ 2014-09-16  2:43 UTC (permalink / raw)
  To: Peter Crosthwaite
  Cc: Peter Maydell, Martin Galvan, qemu-devel@nongnu.org Developers,
	Konstanty Bialkowski

On Tue, Sep 16, 2014 at 1:23 AM, Peter Crosthwaite
<peter.crosthwaite@xilinx.com> wrote:
> On Sun, Sep 14, 2014 at 6:18 PM, Alistair Francis <alistair23@gmail.com> wrote:
>> This patch allows the board to specifiy the number of NVIC interrupt
>> lines when using armv7m_init.
>>
>> Signed-off-by: Alistair Francis <alistair23@gmail.com>
>> ---
>>  hw/arm/armv7m.c      | 7 ++++---
>>  hw/arm/stellaris.c   | 4 +++-
>>  include/hw/arm/arm.h | 2 +-
>>  3 files changed, 8 insertions(+), 5 deletions(-)
>>
>> diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
>> index 5c1f7b3..5e684a0 100644
>> --- a/hw/arm/armv7m.c
>> +++ b/hw/arm/armv7m.c
>> @@ -167,14 +167,14 @@ 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, int sram_size, int num_irq,
>
> This will change slightly based on previous patch comment, but otherwise.
>
> Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

Thanks, but they are both still required as I explained in the other reply

>
>>                        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;
>> @@ -207,11 +207,12 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory,
>>      armv7m_bitband_init();
>>
>>      nvic = qdev_create(NULL, "armv7m_nvic");
>> +    qdev_prop_set_uint32(nvic, "num-irq", num_irq);
>
> Curious, was this previously relying on the default for nvic being 64?
> (hence this is appearing as purely additive).

Yep, it just used the default value

Thanks,

Alistair

>
> Regards,
> Peter
>
>>      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);
>>      }
>>
>> diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
>> index 3c8e9d1..e4da1fb 100644
>> --- a/hw/arm/stellaris.c
>> +++ b/hw/arm/stellaris.c
>> @@ -29,6 +29,8 @@
>>  #define BP_OLED_SSI  0x02
>>  #define BP_GAMEPAD   0x04
>>
>> +#define NUM_IRQ_LINES 64
>> +
>>  typedef const struct {
>>      const char *name;
>>      uint32_t did0;
>> @@ -1238,7 +1240,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
>>      memory_region_add_subregion(system_memory, 0x20000000, sram);
>>
>>      pic = armv7m_init(system_memory, flash_size, sram_size,
>> -                      kernel_filename, cpu_model);
>> +                      NUM_IRQ_LINES, 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..3e7c463 100644
>> --- a/include/hw/arm/arm.h
>> +++ b/include/hw/arm/arm.h
>> @@ -16,7 +16,7 @@
>>
>>  /* armv7m.c */
>>  qemu_irq *armv7m_init(MemoryRegion *system_memory,
>> -                      int flash_size, int sram_size,
>> +                      int flash_size, 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] 20+ messages in thread

* Re: [Qemu-devel] [Patch v1 1/8] stm32f205_timer: Add the stm32f205 Timer
  2014-09-15 15:01   ` Peter Crosthwaite
@ 2014-09-19  2:00     ` Alistair Francis
  0 siblings, 0 replies; 20+ messages in thread
From: Alistair Francis @ 2014-09-19  2:00 UTC (permalink / raw)
  To: Peter Crosthwaite
  Cc: Peter Maydell, Martin Galvan, qemu-devel@nongnu.org Developers,
	Konstanty Bialkowski

On Tue, Sep 16, 2014 at 1:01 AM, Peter Crosthwaite
<peter.crosthwaite@xilinx.com> wrote:
> On Sun, Sep 14, 2014 at 6:18 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>
>> ---
>> Changes from RFC:
>>  - Small changes to functionality and style. Thanks to Peter C
>>  - Rename to make the timer more generic
>>  - Split the config settings to device level
>>
>>  default-configs/arm-softmmu.mak    |   1 +
>>  hw/timer/Makefile.objs             |   1 +
>>  hw/timer/stm32f205_timer.c         | 305 +++++++++++++++++++++++++++++++++++++
>>  include/hw/timer/stm32f205_timer.h |  97 ++++++++++++
>>  4 files changed, 404 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..cf23b24 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_STM32F205_TIMER=y
>>
>>  CONFIG_VERSATILE_PCI=y
>>  CONFIG_VERSATILE_I2C=y
>> diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
>> index 2c86c3d..6c1661e 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_STM32F205_TIMER) += stm32f205_timer.o
>>
>
> The grouping of this with the random SoC configs is a little strange.
> I suggest just creating your own blank-line separated grouping like
> with allwinner currently at the bottom.
>

Will fix

>>  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..c4a84eb
>> --- /dev/null
>> +++ b/hw/timer/stm32f205_timer.c
>> @@ -0,0 +1,305 @@
>> +/*
>> + * STM32F205 Timer
>> + *
>> + * 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 STM_TIMER_ERR_DEBUG
>> +#define STM_TIMER_ERR_DEBUG 0
>> +#endif
>> +
>> +#define DB_PRINT_L(lvl, fmt, args...) do { \
>> +    if (STM_TIMER_ERR_DEBUG >= lvl) { \
>> +        qemu_log("stm32f205_timer: %s:" fmt, __func__, ## args); \
>> +    } \
>> +} while (0);
>> +
>> +#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
>> +
>> +static void stm32f205_timer_interrupt(void *opaque)
>> +{
>> +    STM32f205TimerState *s = opaque;
>> +
>> +    DB_PRINT("Interrupt in: %s\n", __func__);
>> +
>> +    if (s->tim_dier & TIM_DIER_UIE && s->tim_cr1 & TIM_CR1_CEN) {
>> +        s->tim_sr |= 1;
>> +        qemu_irq_pulse(s->irq);
>> +    }
>> +}
>> +
>> +static void stm32f205_timer_set_alarm(STM32f205TimerState *s)
>> +{
>> +    uint32_t ticks;
>> +    int64_t now;
>> +
>> +    DB_PRINT("Alarm raised in: %s at 0x%x\n", __func__, s->tim_cr1);
>> +
>
> You already %s __func__ as part of the DB_PRINT so no need for the dup.
>

Yep

>> +    now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
>> +    ticks = s->tim_arr - (s->tick_offset + (now / get_ticks_per_sec())) *
>> +            (s->tim_psc + 1);
>
> I'm having trouble with the dimensional analysis of this. tim_arr is
> in terms of counter cycles but ticks must be in terms of ns (with it's
> addition to now below). So you have equating of cycles to time
> implying fixed frequency scaling. However you attempt to model the
> prescaling with your use of tim_psc?
>

I think I have fixed it, will update in the respin.

>> +
>> +    DB_PRINT("Alarm set in %d ticks\n", ticks);
>> +
>> +    if (ticks == 0) {
>> +        timer_del(s->timer);
>> +        stm32f205_timer_interrupt(s);
>> +    } else {
>> +        timer_mod(s->timer, (now + (int64_t) ticks));
>> +        DB_PRINT("Wait Time: %u\n", (uint32_t) (now + ticks));
>
> Better to use a PRId64 and drop the cast so the debug messages still
> look good after now rolls over 4G.

Will fix

>
>> +    }
>> +}
>> +
>> +static void stm32f205_timer_reset(DeviceState *dev)
>> +{
>> +    STM32f205TimerState *s = STM32F205TIMER(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 stm32f205_timer_read(void *opaque, hwaddr offset,
>> +                           unsigned size)
>> +{
>> +    STM32f205TimerState *s = opaque;
>> +
>> +    DB_PRINT("Read 0x%"HWADDR_PRIx"\n", 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,
>> +                      "STM32F205_timer_write: Bad offset %x\n", (int) offset);
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>> +static void stm32f205_timer_write(void *opaque, hwaddr offset,
>> +                        uint64_t val64, unsigned size)
>> +{
>> +    STM32f205TimerState *s = opaque;
>> +    uint32_t value = val64;
>> +
>> +    DB_PRINT("Write 0x%x, 0x%"HWADDR_PRIx"\n", value, 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;
>
> Took some getting my head around the &= but TRM does say set by
> hardware and cleared by software. Worth a comment?

I'll add a comment.

>
>> +        stm32f205_timer_set_alarm(s);
>
> This doesn't look right. I think you might be trying to implement
> periodic timing by reloading when the guest clears the ISR. This is
> guest dependent and will also lose time - unless the TRM says that
> timer halts based on ISR? (which I would find quite strange).
>
> The reload logic should probably happen from the timer callback itself.

Ok, I have moved it to the interrupt function.

>
> You may need to look into some of the other timers and how they
> implement accurate periodic timing. You can look at ptimer based
> implementations of which there a fair few. I recently did some work on
> arm_mptimer which is a periodic capable timer that uses regular QEMU
> timers which I consider a good simple example of a QEMU timer that
> doesn't use ptimer.
>
>> +        return;
>> +    case TIM_EGR:
>> +        s->tim_egr = value;
>> +        if (s->tim_egr & 1) {
>> +            /* Re-init the counter */
>> +            stm32f205_timer_reset(DEVICE(s));
>> +        }
>> +        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;
>> +        stm32f205_timer_set_alarm(s);
>> +        return;
>> +    case TIM_PSC:
>> +        s->tim_psc = value;
>> +        return;
>> +    case TIM_ARR:
>> +        s->tim_arr = value;
>> +        stm32f205_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,
>> +                      "STM32F205_timer_write: Bad offset %x\n", (int) offset);
>
> Missed a HWADDR_PRIx.
>
>> +    }
>> +}
>> +
>> +static const MemoryRegionOps stm32f205_timer_ops = {
>> +    .read = stm32f205_timer_read,
>> +    .write = stm32f205_timer_write,
>> +    .endianness = DEVICE_NATIVE_ENDIAN,
>> +};
>> +
>> +static void stm32f205_timer_init(Object *obj)
>> +{
>> +    STM32f205TimerState *s = STM32F205TIMER(obj);
>> +    struct tm tm;
>> +
>> +    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
>> +
>> +    memory_region_init_io(&s->iomem, obj, &stm32f205_timer_ops, s,
>> +                          "stm32f205_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(QEMU_CLOCK_VIRTUAL) / get_ticks_per_sec();
>> +
>
> This is still trying to be an RTC of sorts. You don't need the
> mktimegm stuff. I think you need to refactor tick_offset as according
> to this it is in terms of seconds, but that doesn't make a lot of
> sense for this timer which should trade in high frequency clock cycles
> or ns I think.

I forgot to take that out, will removed.

Thanks,

Alistair

>
> Regards,
> Peter
>
>> +    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, stm32f205_timer_interrupt, s);
>> +}
>> +
>> +static const VMStateDescription vmstate_stm32f205_timer = {
>> +    .name = "stm32f205_timer",
>> +    .version_id = 1,
>> +    .minimum_version_id = 1,
>> +    .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 stm32f205_timer_class_init(ObjectClass *klass, void *data)
>> +{
>> +    DeviceClass *dc = DEVICE_CLASS(klass);
>> +
>> +    dc->vmsd = &vmstate_stm32f205_timer;
>> +    dc->reset = stm32f205_timer_reset;
>> +}
>> +
>> +static const TypeInfo stm32f205_timer_info = {
>> +    .name          = TYPE_STM32F205_TIMER,
>> +    .parent        = TYPE_SYS_BUS_DEVICE,
>> +    .instance_size = sizeof(STM32f205TimerState),
>> +    .instance_init = stm32f205_timer_init,
>> +    .class_init    = stm32f205_timer_class_init,
>> +};
>> +
>> +static void stm32f205_timer_register_types(void)
>> +{
>> +    type_register_static(&stm32f205_timer_info);
>> +}
>> +
>> +type_init(stm32f205_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..c26ae57
>> --- /dev/null
>> +++ b/include/hw/timer/stm32f205_timer.h
>> @@ -0,0 +1,97 @@
>> +/*
>> + * STM32F205 Timer
>> + *
>> + * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
>> + *
>> + * Permission is hereby granted, free of charge, to any person obtaining a copy
>> + * of this software and associated documentation files (the "Software"), to deal
>> + * in the Software without restriction, including without limitation the rights
>> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
>> + * copies of the Software, and to permit persons to whom the Software is
>> + * furnished to do so, subject to the following conditions:
>> + *
>> + * The above copyright notice and this permission notice shall be included in
>> + * all copies or substantial portions of the Software.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
>> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
>> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
>> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
>> + * THE SOFTWARE.
>> + */
>> +
>> +#ifndef HW_STM_TIMER_H
>> +#define HW_STM_TIMER_H
>> +
>> +#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 TIM_CCER_CC2E   (1 << 4)
>> +#define TIM_CCMR1_OC2M2 (1 << 14)
>> +#define TIM_CCMR1_OC2M1 (1 << 13)
>> +
>> +#define TIM_DIER_UIE  1
>> +
>> +#define TYPE_STM32F205_TIMER "stm32f205-timer"
>> +#define STM32F205TIMER(obj) OBJECT_CHECK(STM32f205TimerState, \
>> +                            (obj), TYPE_STM32F205_TIMER)
>> +
>> +typedef struct STM32f205TimerState {
>> +    /* <private> */
>> +    SysBusDevice parent_obj;
>> +
>> +    /* <public> */
>> +    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;
>> +
>> +#endif
>> --
>> 1.9.1
>>
>>

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

* Re: [Qemu-devel] [Patch v1 2/8] stm32f205_USART: Add the stm32f205 USART Controller
  2014-09-15 15:11   ` Peter Crosthwaite
@ 2014-09-19  2:22     ` Alistair Francis
  0 siblings, 0 replies; 20+ messages in thread
From: Alistair Francis @ 2014-09-19  2:22 UTC (permalink / raw)
  To: Peter Crosthwaite
  Cc: Peter Maydell, Martin Galvan, qemu-devel@nongnu.org Developers,
	Konstanty Bialkowski

On Tue, Sep 16, 2014 at 1:11 AM, Peter Crosthwaite
<peter.crosthwaite@xilinx.com> wrote:
> On Sun, Sep 14, 2014 at 6:18 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>
>> ---
>> Changes from RFC:
>>  - Small changes thanks to Peter C
>>  - USART now implements QEMU blocking functions
>>  - Split the config settings to device level
>>
>>  default-configs/arm-softmmu.mak   |   1 +
>>  hw/char/Makefile.objs             |   1 +
>>  hw/char/stm32f205_usart.c         | 213 ++++++++++++++++++++++++++++++++++++++
>>  include/hw/char/stm32f205_usart.h |  67 ++++++++++++
>>  4 files changed, 282 insertions(+)
>>  create mode 100644 hw/char/stm32f205_usart.c
>>  create mode 100644 include/hw/char/stm32f205_usart.h
>>
>> diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
>> index cf23b24..422dec0 100644
>> --- a/default-configs/arm-softmmu.mak
>> +++ b/default-configs/arm-softmmu.mak
>> @@ -79,6 +79,7 @@ CONFIG_REALVIEW=y
>>  CONFIG_ZAURUS=y
>>  CONFIG_ZYNQ=y
>>  CONFIG_STM32F205_TIMER=y
>> +CONFIG_STM32F205_USART=y
>>
>>  CONFIG_VERSATILE_PCI=y
>>  CONFIG_VERSATILE_I2C=y
>> diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
>> index 317385d..c7b3ce4 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_STM32F205_USART) += 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..1274e69
>> --- /dev/null
>> +++ b/hw/char/stm32f205_usart.c
>> @@ -0,0 +1,213 @@
>> +/*
>> + * STM32F205 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) { \
>> +        qemu_log("stm32f205_usart: %s:" fmt, __func__, ## args); \
>> +    } \
>> +} while (0);
>> +
>> +#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
>> +
>> +static int stm32f205_usart_can_receive(void *opaque)
>> +{
>> +    STM32f205UsartState *s = opaque;
>> +
>> +    if (s->usart_cr1 & USART_CR1_UE && s->usart_cr1 & USART_CR1_RE &&
>
> So this is still gating based on the master enable. I think these
> first two terms in the && need to be dropped ...
>
>> +        !(s->usart_sr & USART_SR_RXNE)) {
>> +        return 1;
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>> +static void stm32f205_usart_receive(void *opaque, const uint8_t *buf, int size)
>> +{
>> +    STM32f205UsartState *s = opaque;
>> +
>> +    s->usart_dr = *buf;
>> +
>
> and here:
>
> if (!s->usart_cr1 & USART_CR1_UE && s->usart_cr1 & USART_CR1_RE) {
>    return; /* not enabled - drop chars */
> }
>
> This means the UART will drop chars when its disabled, which would be
> consistent with real HW (there is no buffering when the sender sends
> chars to a disabled UART).

This makes sense, will fix it

Thanks,

Alistair

>
>> +    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 stm32f205_usart_reset(DeviceState *dev)
>> +{
>> +    STM32f205UsartState *s = STM32F205_USART(dev);
>> +
>> +    s->usart_sr = 0x00C00000;
>
> Just define a macro for this field and set it for self documentation.
>
>> +    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 stm32f205_usart_read(void *opaque, hwaddr addr,
>> +                                       unsigned int size)
>> +{
>> +    STM32f205UsartState *s = opaque;
>> +    uint64_t retvalue;
>> +
>> +    DB_PRINT("Read 0x%"HWADDR_PRIx"\n", addr);
>> +
>> +    switch (addr) {
>> +    case USART_SR:
>> +        retvalue = s->usart_sr;
>> +        s->usart_sr &= ~USART_SR_TC;
>> +        if (s->chr) {
>> +            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);
>
> PRIx32 to match type of usart_dr.
>
>> +        s->usart_sr |= USART_SR_TXE;
>> +        s->usart_sr &= ~USART_SR_RXNE;
>> +        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,
>> +                      "STM32F205_usart_read: Bad offset " \
>> +                      "0x%"HWADDR_PRIx"\n", addr);
>> +        return 0;
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>> +static void stm32f205_usart_write(void *opaque, hwaddr addr,
>> +                       uint64_t val64, unsigned int size)
>> +{
>> +    STM32f205UsartState *s = opaque;
>> +    uint32_t value = val64;
>> +    unsigned char ch;
>> +
>> +    DB_PRINT("Write 0x%x, 0x%"HWADDR_PRIx"\n", value, addr);
>> +
>
> PRIx64 for value.
>
> Regards,
> Peter

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

end of thread, other threads:[~2014-09-19  2:23 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-14  8:18 [Qemu-devel] [Patch v1 0/8] Netduino 2 Machine Model Alistair Francis
2014-09-14  8:18 ` [Qemu-devel] [Patch v1 1/8] stm32f205_timer: Add the stm32f205 Timer Alistair Francis
2014-09-15 15:01   ` Peter Crosthwaite
2014-09-19  2:00     ` Alistair Francis
2014-09-14  8:18 ` [Qemu-devel] [Patch v1 2/8] stm32f205_USART: Add the stm32f205 USART Controller Alistair Francis
2014-09-15 15:11   ` Peter Crosthwaite
2014-09-19  2:22     ` Alistair Francis
2014-09-14  8:18 ` [Qemu-devel] [Patch v1 3/8] stm32f205_SYSCFG: Add the stm32f205 SYSCFG Alistair Francis
2014-09-14  8:18 ` [Qemu-devel] [Patch v1 4/8] target_arm: Remove memory region init from armv7m_init Alistair Francis
2014-09-15 15:20   ` Peter Crosthwaite
2014-09-15 15:36     ` Paolo Bonzini
2014-09-16  2:37     ` Alistair Francis
2014-09-14  8:18 ` [Qemu-devel] [Patch v1 5/8] target_arm: Parameterise the irq lines for armv7m_init Alistair Francis
2014-09-15 15:23   ` Peter Crosthwaite
2014-09-16  2:43     ` Alistair Francis
2014-09-14  8:19 ` [Qemu-devel] [Patch v1 6/8] target_arm: Change the reset values based on the ELF entry Alistair Francis
2014-09-15 15:27   ` Peter Crosthwaite
2014-09-16  2:40     ` Alistair Francis
2014-09-14  8:19 ` [Qemu-devel] [Patch v1 7/8] stm32f205: Add the stm32f205 SoC Alistair Francis
2014-09-14  8:19 ` [Qemu-devel] [Patch v1 8/8] netduino2: Add the Netduino 2 Machine 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.