All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v10 0/5]  Netduino 2 Machine Model
@ 2015-01-29 12:31 Alistair Francis
  2015-01-29 12:31 ` [Qemu-devel] [PATCH v10 1/5] stm32f2xx_timer: Add the stm32f2xx Timer Alistair Francis
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: Alistair Francis @ 2015-01-29 12:31 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.9

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

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

V9/V10:
 - Correct timer device based on Peter C's comments
V8:
 - Update the timer device based on Peter C's comments
 - Update the USART device based on Peter C's comments
V7:
 - Rebase to QEMU 2.2
V6:
 - Rename the three devices to STM32FXX*
 - Correct the timer to use ns
 - Correct the number of devices that are inited
 - Rename memory regions


Alistair Francis (5):
  stm32f2xx_timer: Add the stm32f2xx Timer
  stm32f2xx_USART: Add the stm32f2xx USART Controller
  stm32f2xx_SYSCFG: Add the stm32f2xx SYSCFG
  stm32f205: Add the stm32f205 SoC
  netduino2: Add the Netduino 2 Machine

 default-configs/arm-softmmu.mak    |   4 +
 hw/arm/Makefile.objs               |   2 +
 hw/arm/netduino2.c                 |  54 +++++++
 hw/arm/stm32f205_soc.c             | 157 ++++++++++++++++++
 hw/char/Makefile.objs              |   1 +
 hw/char/stm32f2xx_usart.c          | 229 ++++++++++++++++++++++++++
 hw/misc/Makefile.objs              |   1 +
 hw/misc/stm32f2xx_syscfg.c         | 160 ++++++++++++++++++
 hw/timer/Makefile.objs             |   2 +
 hw/timer/stm32f2xx_timer.c         | 324 +++++++++++++++++++++++++++++++++++++
 include/hw/arm/stm32f205_soc.h     |  69 ++++++++
 include/hw/char/stm32f2xx_usart.h  |  69 ++++++++
 include/hw/misc/stm32f2xx_syscfg.h |  61 +++++++
 include/hw/timer/stm32f2xx_timer.h | 101 ++++++++++++
 14 files changed, 1234 insertions(+)
 create mode 100644 hw/arm/netduino2.c
 create mode 100644 hw/arm/stm32f205_soc.c
 create mode 100644 hw/char/stm32f2xx_usart.c
 create mode 100644 hw/misc/stm32f2xx_syscfg.c
 create mode 100644 hw/timer/stm32f2xx_timer.c
 create mode 100644 include/hw/arm/stm32f205_soc.h
 create mode 100644 include/hw/char/stm32f2xx_usart.h
 create mode 100644 include/hw/misc/stm32f2xx_syscfg.h
 create mode 100644 include/hw/timer/stm32f2xx_timer.h

-- 
2.1.0

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

* [Qemu-devel] [PATCH v10 1/5] stm32f2xx_timer: Add the stm32f2xx Timer
  2015-01-29 12:31 [Qemu-devel] [PATCH v10 0/5] Netduino 2 Machine Model Alistair Francis
@ 2015-01-29 12:31 ` Alistair Francis
  2015-02-10  6:22   ` Peter Crosthwaite
  2015-01-29 12:31 ` [Qemu-devel] [PATCH v10 2/5] stm32f2xx_USART: Add the stm32f2xx USART Controller Alistair Francis
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Alistair Francis @ 2015-01-29 12:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, peter.crosthwaite, konstanty, martin.galvan

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

Signed-off-by: Alistair Francis <alistair@alistair23.me>
Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---
V10:
 - Correct the units based on a patch by Peter C
V9:
 - Convert tick_offset to now be updated on more events
    - This is similar to what I did with the ARM PCCNT regiseter
V8:
 - Fix tick_offset to allow now to wrap around
 - Remove the calls to get_ticks_per_sec()
 - Pre-scale the guest visable time
V6:
 - Rename to STM32F2XX
 - Change the timer calculations to use ns
 - Update the value to timer_mod to ensure it is in ns
 - Account for reloadable/resetable timer
    - Thanks to Peter C for pointing this out

 default-configs/arm-softmmu.mak    |   1 +
 hw/timer/Makefile.objs             |   2 +
 hw/timer/stm32f2xx_timer.c         | 324 +++++++++++++++++++++++++++++++++++++
 include/hw/timer/stm32f2xx_timer.h | 101 ++++++++++++
 4 files changed, 428 insertions(+)
 create mode 100644 hw/timer/stm32f2xx_timer.c
 create mode 100644 include/hw/timer/stm32f2xx_timer.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index f3513fa..faea100 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_STM32F2XX_TIMER=y
 
 CONFIG_VERSATILE_PCI=y
 CONFIG_VERSATILE_I2C=y
diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index 2c86c3d..133bd0d 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -31,3 +31,5 @@ obj-$(CONFIG_DIGIC) += digic-timer.o
 obj-$(CONFIG_MC146818RTC) += mc146818rtc.o
 
 obj-$(CONFIG_ALLWINNER_A10_PIT) += allwinner-a10-pit.o
+
+common-obj-$(CONFIG_STM32F2XX_TIMER) += stm32f2xx_timer.o
diff --git a/hw/timer/stm32f2xx_timer.c b/hw/timer/stm32f2xx_timer.c
new file mode 100644
index 0000000..72de746
--- /dev/null
+++ b/hw/timer/stm32f2xx_timer.c
@@ -0,0 +1,324 @@
+/*
+ * STM32F2XX 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/stm32f2xx_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("%s: " fmt, __func__, ## args); \
+    } \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+static void stm32f2xx_timer_set_alarm(STM32F2XXTimerState *s, int64_t now);
+
+static void stm32f2xx_timer_interrupt(void *opaque)
+{
+    STM32F2XXTimerState *s = opaque;
+
+    DB_PRINT("Interrupt\n");
+
+    if (s->tim_dier & TIM_DIER_UIE && s->tim_cr1 & TIM_CR1_CEN) {
+        s->tim_sr |= 1;
+        qemu_irq_pulse(s->irq);
+        stm32f2xx_timer_set_alarm(s, s->hit_time);
+    }
+}
+
+static inline int64_t stm32f2xx_ns_to_ticks(STM32F2XXTimerState *s, int64_t t)
+{
+    return muldiv64(t, s->freq_hz, 1000000000ULL) / (s->tim_psc + 1);
+}
+
+static void stm32f2xx_timer_set_alarm(STM32F2XXTimerState *s, int64_t now)
+{
+    uint64_t ticks;
+    int64_t now_ticks;
+
+    if (s->tim_arr == 0) {
+        return;
+    }
+
+    DB_PRINT("Alarm set at: 0x%x\n", s->tim_cr1);
+
+    now_ticks = stm32f2xx_ns_to_ticks(s, now);
+    ticks = s->tim_arr - (now_ticks - s->tick_offset);
+
+    DB_PRINT("Alarm set in %d ticks\n", (int) ticks);
+
+    s->hit_time = muldiv64((ticks + (uint64_t) now_ticks) * (s->tim_psc + 1),
+                               1000000000ULL, s->freq_hz);
+
+    timer_mod(s->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->hit_time);
+    DB_PRINT("Wait Time: %" PRId64 " ticks\n", s->hit_time);
+}
+
+static void stm32f2xx_timer_reset(DeviceState *dev)
+{
+    STM32F2XXTimerState *s = STM32F2XXTIMER(dev);
+    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+
+    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_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;
+
+    s->tick_offset = stm32f2xx_ns_to_ticks(s, now);
+}
+
+static uint64_t stm32f2xx_timer_read(void *opaque, hwaddr offset,
+                           unsigned size)
+{
+    STM32F2XXTimerState *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 stm32f2xx_ns_to_ticks(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)) -
+               s->tick_offset;
+    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,
+                      "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, offset);
+    }
+
+    return 0;
+}
+
+static void stm32f2xx_timer_write(void *opaque, hwaddr offset,
+                        uint64_t val64, unsigned size)
+{
+    STM32F2XXTimerState *s = opaque;
+    uint32_t value = val64;
+    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+    uint32_t timer_val = 0;
+
+    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:
+        /* This is set by hardware and cleared by software */
+        s->tim_sr &= value;
+        return;
+    case TIM_EGR:
+        s->tim_egr = value;
+        if (s->tim_egr & TIM_EGR_UG) {
+            timer_val = 0;
+            break;
+        }
+        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_PSC:
+        timer_val = stm32f2xx_ns_to_ticks(s, now) - s->tick_offset;
+        s->tim_psc = value;
+        value = timer_val;
+        break;
+    case TIM_CNT:
+        timer_val = value;
+        break;
+    case TIM_ARR:
+        s->tim_arr = value;
+        stm32f2xx_timer_set_alarm(s, now);
+        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,
+                      "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, offset);
+    }
+
+    s->tick_offset = stm32f2xx_ns_to_ticks(s, now) - timer_val;
+    stm32f2xx_timer_set_alarm(s, now);
+}
+
+static const MemoryRegionOps stm32f2xx_timer_ops = {
+    .read = stm32f2xx_timer_read,
+    .write = stm32f2xx_timer_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static const VMStateDescription vmstate_stm32f2xx_timer = {
+    .name = TYPE_STM32F2XX_TIMER,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_INT64(tick_offset, STM32F2XXTimerState),
+        VMSTATE_UINT32(tim_cr1, STM32F2XXTimerState),
+        VMSTATE_UINT32(tim_cr2, STM32F2XXTimerState),
+        VMSTATE_UINT32(tim_smcr, STM32F2XXTimerState),
+        VMSTATE_UINT32(tim_dier, STM32F2XXTimerState),
+        VMSTATE_UINT32(tim_sr, STM32F2XXTimerState),
+        VMSTATE_UINT32(tim_egr, STM32F2XXTimerState),
+        VMSTATE_UINT32(tim_ccmr1, STM32F2XXTimerState),
+        VMSTATE_UINT32(tim_ccmr2, STM32F2XXTimerState),
+        VMSTATE_UINT32(tim_ccer, STM32F2XXTimerState),
+        VMSTATE_UINT32(tim_psc, STM32F2XXTimerState),
+        VMSTATE_UINT32(tim_arr, STM32F2XXTimerState),
+        VMSTATE_UINT32(tim_ccr1, STM32F2XXTimerState),
+        VMSTATE_UINT32(tim_ccr2, STM32F2XXTimerState),
+        VMSTATE_UINT32(tim_ccr3, STM32F2XXTimerState),
+        VMSTATE_UINT32(tim_ccr4, STM32F2XXTimerState),
+        VMSTATE_UINT32(tim_dcr, STM32F2XXTimerState),
+        VMSTATE_UINT32(tim_dmar, STM32F2XXTimerState),
+        VMSTATE_UINT32(tim_or, STM32F2XXTimerState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static Property stm32f2xx_timer_properties[] = {
+    DEFINE_PROP_UINT64("clock-frequency", struct STM32F2XXTimerState,
+                       freq_hz, 1000000000),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void stm32f2xx_timer_init(Object *obj)
+{
+    STM32F2XXTimerState *s = STM32F2XXTIMER(obj);
+
+    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
+
+    memory_region_init_io(&s->iomem, obj, &stm32f2xx_timer_ops, s,
+                          "stm32f2xx_timer", 0x4000);
+    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
+
+    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, stm32f2xx_timer_interrupt, s);
+}
+
+static void stm32f2xx_timer_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->reset = stm32f2xx_timer_reset;
+    dc->props = stm32f2xx_timer_properties;
+    dc->vmsd = &vmstate_stm32f2xx_timer;
+}
+
+static const TypeInfo stm32f2xx_timer_info = {
+    .name          = TYPE_STM32F2XX_TIMER,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(STM32F2XXTimerState),
+    .instance_init = stm32f2xx_timer_init,
+    .class_init    = stm32f2xx_timer_class_init,
+};
+
+static void stm32f2xx_timer_register_types(void)
+{
+    type_register_static(&stm32f2xx_timer_info);
+}
+
+type_init(stm32f2xx_timer_register_types)
diff --git a/include/hw/timer/stm32f2xx_timer.h b/include/hw/timer/stm32f2xx_timer.h
new file mode 100644
index 0000000..7362d70
--- /dev/null
+++ b/include/hw/timer/stm32f2xx_timer.h
@@ -0,0 +1,101 @@
+/*
+ * STM32F2XX 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_EGR_UG 1
+
+#define TIM_CCER_CC2E   (1 << 4)
+#define TIM_CCMR1_OC2M2 (1 << 14)
+#define TIM_CCMR1_OC2M1 (1 << 13)
+#define TIM_CCMR1_OC2M0 (1 << 12)
+#define TIM_CCMR1_OC2PE (1 << 11)
+
+#define TIM_DIER_UIE  1
+
+#define TYPE_STM32F2XX_TIMER "stm32f2xx-timer"
+#define STM32F2XXTIMER(obj) OBJECT_CHECK(STM32F2XXTimerState, \
+                            (obj), TYPE_STM32F2XX_TIMER)
+
+typedef struct STM32F2XXTimerState {
+    /* <private> */
+    SysBusDevice parent_obj;
+
+    /* <public> */
+    MemoryRegion iomem;
+    QEMUTimer *timer;
+    qemu_irq irq;
+
+    int64_t tick_offset;
+    uint64_t hit_time;
+    uint64_t freq_hz;
+
+    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_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;
+} STM32F2XXTimerState;
+
+#endif
-- 
2.1.0

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

* [Qemu-devel] [PATCH v10 2/5] stm32f2xx_USART: Add the stm32f2xx USART Controller
  2015-01-29 12:31 [Qemu-devel] [PATCH v10 0/5] Netduino 2 Machine Model Alistair Francis
  2015-01-29 12:31 ` [Qemu-devel] [PATCH v10 1/5] stm32f2xx_timer: Add the stm32f2xx Timer Alistair Francis
@ 2015-01-29 12:31 ` Alistair Francis
  2015-02-10  5:49   ` Peter Crosthwaite
  2015-01-29 12:31 ` [Qemu-devel] [PATCH v10 3/5] stm32f2xx_SYSCFG: Add the stm32f2xx SYSCFG Alistair Francis
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Alistair Francis @ 2015-01-29 12:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, peter.crosthwaite, konstanty, martin.galvan

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

Signed-off-by: Alistair Francis <alistair@alistair23.me>
---
V8:
 - Clear IRQ on reset
 - Lower IRQ on data read/status clear
 - Set IRQ if enabled while data is avaliable
V6:
 - Rename to STM32F2XX
 - Fix up unimplemented printing
 - Add a qemu_chr_accept()

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

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index faea100..1348104 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_STM32F2XX_TIMER=y
+CONFIG_STM32F2XX_USART=y
 
 CONFIG_VERSATILE_PCI=y
 CONFIG_VERSATILE_I2C=y
diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
index 317385d..5931cc8 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_STM32F2XX_USART) += stm32f2xx_usart.o
 
 common-obj-$(CONFIG_ETRAXFS) += etraxfs_ser.o
 common-obj-$(CONFIG_ISA_DEBUG) += debugcon.o
diff --git a/hw/char/stm32f2xx_usart.c b/hw/char/stm32f2xx_usart.c
new file mode 100644
index 0000000..260b053
--- /dev/null
+++ b/hw/char/stm32f2xx_usart.c
@@ -0,0 +1,229 @@
+/*
+ * STM32F2XX 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/stm32f2xx_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("%s: " fmt, __func__, ## args); \
+    } \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+static int stm32f2xx_usart_can_receive(void *opaque)
+{
+    STM32F2XXUsartState *s = opaque;
+
+    if (!(s->usart_sr & USART_SR_RXNE)) {
+        return 1;
+    }
+
+    return 0;
+}
+
+static void stm32f2xx_usart_receive(void *opaque, const uint8_t *buf, int size)
+{
+    STM32F2XXUsartState *s = opaque;
+
+    s->usart_dr = *buf;
+
+    if (!(s->usart_cr1 & USART_CR1_UE && s->usart_cr1 & USART_CR1_RE)) {
+        /* USART not enabled - drop the chars */
+        DB_PRINT("Dropping the chars\n");
+        return;
+    }
+
+    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 stm32f2xx_usart_reset(DeviceState *dev)
+{
+    STM32F2XXUsartState *s = STM32F2XX_USART(dev);
+
+    s->usart_sr = USART_SR_RESET;
+    s->usart_dr = 0x00000000;
+    s->usart_brr = 0x00000000;
+    s->usart_cr1 = 0x00000000;
+    s->usart_cr2 = 0x00000000;
+    s->usart_cr3 = 0x00000000;
+    s->usart_gtpr = 0x00000000;
+
+    qemu_set_irq(s->irq, 0);
+}
+
+static uint64_t stm32f2xx_usart_read(void *opaque, hwaddr addr,
+                                       unsigned int size)
+{
+    STM32F2XXUsartState *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%" PRIx32 ", %c\n", s->usart_dr, (char) s->usart_dr);
+        s->usart_sr |= USART_SR_TXE;
+        s->usart_sr &= ~USART_SR_RXNE;
+        if (s->chr) {
+            qemu_chr_accept_input(s->chr);
+        }
+        qemu_set_irq(s->irq, 0);
+        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,
+                      "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
+        return 0;
+    }
+
+    return 0;
+}
+
+static void stm32f2xx_usart_write(void *opaque, hwaddr addr,
+                                  uint64_t val64, unsigned int size)
+{
+    STM32F2XXUsartState *s = opaque;
+    uint32_t value = val64;
+    unsigned char ch;
+
+    DB_PRINT("Write 0x%" PRIx32 ", 0x%"HWADDR_PRIx"\n", value, addr);
+
+    switch (addr) {
+    case USART_SR:
+        if (value <= 0x3FF) {
+            s->usart_sr = value;
+        } else {
+            s->usart_sr &= value;
+        }
+        if (!(s->usart_sr & USART_SR_RXNE)) {
+            qemu_set_irq(s->irq, 0);
+        }
+        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;
+            if (s->usart_cr1 & USART_CR1_RXNEIE &&
+                s->usart_sr & USART_SR_RXNE) {
+                qemu_set_irq(s->irq, 1);
+            }
+        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,
+                      "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
+    }
+}
+
+static const MemoryRegionOps stm32f2xx_usart_ops = {
+    .read = stm32f2xx_usart_read,
+    .write = stm32f2xx_usart_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void stm32f2xx_usart_init(Object *obj)
+{
+    STM32F2XXUsartState *s = STM32F2XX_USART(obj);
+
+    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
+
+    memory_region_init_io(&s->mmio, obj, &stm32f2xx_usart_ops, s,
+                          TYPE_STM32F2XX_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, stm32f2xx_usart_can_receive,
+                              stm32f2xx_usart_receive, NULL, s);
+    }
+}
+
+static void stm32f2xx_usart_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->reset = stm32f2xx_usart_reset;
+}
+
+static const TypeInfo stm32f2xx_usart_info = {
+    .name          = TYPE_STM32F2XX_USART,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(STM32F2XXUsartState),
+    .instance_init = stm32f2xx_usart_init,
+    .class_init    = stm32f2xx_usart_class_init,
+};
+
+static void stm32f2xx_usart_register_types(void)
+{
+    type_register_static(&stm32f2xx_usart_info);
+}
+
+type_init(stm32f2xx_usart_register_types)
diff --git a/include/hw/char/stm32f2xx_usart.h b/include/hw/char/stm32f2xx_usart.h
new file mode 100644
index 0000000..c9fad3c
--- /dev/null
+++ b/include/hw/char/stm32f2xx_usart.h
@@ -0,0 +1,69 @@
+/*
+ * STM32F2XX 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_RESET 0x00C00000
+
+#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_STM32F2XX_USART "stm32f2xx-usart"
+#define STM32F2XX_USART(obj) \
+    OBJECT_CHECK(STM32F2XXUsartState, (obj), TYPE_STM32F2XX_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;
+} STM32F2XXUsartState;
-- 
2.1.0

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

* [Qemu-devel] [PATCH v10 3/5] stm32f2xx_SYSCFG: Add the stm32f2xx SYSCFG
  2015-01-29 12:31 [Qemu-devel] [PATCH v10 0/5] Netduino 2 Machine Model Alistair Francis
  2015-01-29 12:31 ` [Qemu-devel] [PATCH v10 1/5] stm32f2xx_timer: Add the stm32f2xx Timer Alistair Francis
  2015-01-29 12:31 ` [Qemu-devel] [PATCH v10 2/5] stm32f2xx_USART: Add the stm32f2xx USART Controller Alistair Francis
@ 2015-01-29 12:31 ` Alistair Francis
  2015-01-29 12:31 ` [Qemu-devel] [PATCH v10 4/5] stm32f205: Add the stm32f205 SoC Alistair Francis
  2015-01-29 12:31 ` [Qemu-devel] [PATCH v10 5/5] netduino2: Add the Netduino 2 Machine Alistair Francis
  4 siblings, 0 replies; 11+ messages in thread
From: Alistair Francis @ 2015-01-29 12:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, peter.crosthwaite, konstanty, martin.galvan

This patch adds the stm32f2xx 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 <alistair@alistair23.me>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---
V6:
 - Rename to STM32F2XX
 - Remove all casts from debug printing

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

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 1348104..a5aab7f 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -80,6 +80,7 @@ CONFIG_ZAURUS=y
 CONFIG_ZYNQ=y
 CONFIG_STM32F2XX_TIMER=y
 CONFIG_STM32F2XX_USART=y
+CONFIG_STM32F2XX_SYSCFG=y
 
 CONFIG_VERSATILE_PCI=y
 CONFIG_VERSATILE_I2C=y
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 029a56f..049c1a0 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -38,6 +38,7 @@ 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_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o
 
 obj-$(CONFIG_PVPANIC) += pvpanic.o
 obj-$(CONFIG_EDU) += edu.o
diff --git a/hw/misc/stm32f2xx_syscfg.c b/hw/misc/stm32f2xx_syscfg.c
new file mode 100644
index 0000000..4ae4042
--- /dev/null
+++ b/hw/misc/stm32f2xx_syscfg.c
@@ -0,0 +1,160 @@
+/*
+ * STM32F2XX 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/stm32f2xx_syscfg.h"
+
+#ifndef STM_SYSCFG_ERR_DEBUG
+#define STM_SYSCFG_ERR_DEBUG 0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+    if (STM_SYSCFG_ERR_DEBUG >= lvl) { \
+        qemu_log("%s: " fmt, __func__, ## args); \
+    } \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+static void stm32f2xx_syscfg_reset(DeviceState *dev)
+{
+    STM32F2XXSyscfgState *s = STM32F2XX_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 stm32f2xx_syscfg_read(void *opaque, hwaddr addr,
+                                     unsigned int size)
+{
+    STM32F2XXSyscfgState *s = opaque;
+
+    DB_PRINT("0x%"HWADDR_PRIx"\n", 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,
+                      "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
+        return 0;
+    }
+
+    return 0;
+}
+
+static void stm32f2xx_syscfg_write(void *opaque, hwaddr addr,
+                       uint64_t val64, unsigned int size)
+{
+    STM32F2XXSyscfgState *s = opaque;
+    uint32_t value = val64;
+
+    DB_PRINT("0x%x, 0x%"HWADDR_PRIx"\n", value, addr);
+
+    switch (addr) {
+    case SYSCFG_MEMRMP:
+        qemu_log_mask(LOG_UNIMP,
+                      "%s: Changeing the memory mapping isn't supported " \
+                      "in QEMU\n", __func__);
+        return;
+    case SYSCFG_PMC:
+        qemu_log_mask(LOG_UNIMP,
+                      "%s: Changeing the memory mapping isn't supported " \
+                      "in QEMU\n", __func__);
+        return;
+    case SYSCFG_EXTICR1:
+        s->syscfg_exticr1 = (value & 0xFFFF);
+        return;
+    case SYSCFG_EXTICR2:
+        s->syscfg_exticr2 = (value & 0xFFFF);
+        return;
+    case SYSCFG_EXTICR3:
+        s->syscfg_exticr3 = (value & 0xFFFF);
+        return;
+    case SYSCFG_EXTICR4:
+        s->syscfg_exticr4 = (value & 0xFFFF);
+        return;
+    case SYSCFG_CMPCR:
+        s->syscfg_cmpcr = value;
+        return;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
+    }
+}
+
+static const MemoryRegionOps stm32f2xx_syscfg_ops = {
+    .read = stm32f2xx_syscfg_read,
+    .write = stm32f2xx_syscfg_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void stm32f2xx_syscfg_init(Object *obj)
+{
+    STM32F2XXSyscfgState *s = STM32F2XX_SYSCFG(obj);
+
+    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
+
+    memory_region_init_io(&s->mmio, obj, &stm32f2xx_syscfg_ops, s,
+                          TYPE_STM32F2XX_SYSCFG, 0x400);
+    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
+}
+
+static void stm32f2xx_syscfg_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->reset = stm32f2xx_syscfg_reset;
+}
+
+static const TypeInfo stm32f2xx_syscfg_info = {
+    .name          = TYPE_STM32F2XX_SYSCFG,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(STM32F2XXSyscfgState),
+    .instance_init = stm32f2xx_syscfg_init,
+    .class_init    = stm32f2xx_syscfg_class_init,
+};
+
+static void stm32f2xx_syscfg_register_types(void)
+{
+    type_register_static(&stm32f2xx_syscfg_info);
+}
+
+type_init(stm32f2xx_syscfg_register_types)
diff --git a/include/hw/misc/stm32f2xx_syscfg.h b/include/hw/misc/stm32f2xx_syscfg.h
new file mode 100644
index 0000000..f3349e9
--- /dev/null
+++ b/include/hw/misc/stm32f2xx_syscfg.h
@@ -0,0 +1,61 @@
+/*
+ * STM32F2XX 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_STM32F2XX_SYSCFG "stm32f2xx-syscfg"
+#define STM32F2XX_SYSCFG(obj) \
+    OBJECT_CHECK(STM32F2XXSyscfgState, (obj), TYPE_STM32F2XX_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;
+} STM32F2XXSyscfgState;
+
+#endif
-- 
2.1.0

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

* [Qemu-devel] [PATCH v10 4/5] stm32f205: Add the stm32f205 SoC
  2015-01-29 12:31 [Qemu-devel] [PATCH v10 0/5] Netduino 2 Machine Model Alistair Francis
                   ` (2 preceding siblings ...)
  2015-01-29 12:31 ` [Qemu-devel] [PATCH v10 3/5] stm32f2xx_SYSCFG: Add the stm32f2xx SYSCFG Alistair Francis
@ 2015-01-29 12:31 ` Alistair Francis
  2015-02-10  6:14   ` Peter Crosthwaite
  2015-01-29 12:31 ` [Qemu-devel] [PATCH v10 5/5] netduino2: Add the Netduino 2 Machine Alistair Francis
  4 siblings, 1 reply; 11+ messages in thread
From: Alistair Francis @ 2015-01-29 12:31 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 <alistair@alistair23.me>
---
V6:
 - Correct the number of USART/UART devices
 - Use macros to define how many devices are inited
 - Update the memory regions name from netduino.* to
   STM32F205.*

 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs            |   1 +
 hw/arm/stm32f205_soc.c          | 157 ++++++++++++++++++++++++++++++++++++++++
 include/hw/arm/stm32f205_soc.h  |  69 ++++++++++++++++++
 4 files changed, 228 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 a5aab7f..9ac755e 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -81,6 +81,7 @@ CONFIG_ZYNQ=y
 CONFIG_STM32F2XX_TIMER=y
 CONFIG_STM32F2XX_USART=y
 CONFIG_STM32F2XX_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..186e15d
--- /dev/null
+++ b/hw/arm/stm32f205_soc.c
@@ -0,0 +1,157 @@
+/*
+ * 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[STM_NUM_TIMERS] = { 0x40000000, 0x40000400,
+    0x40000800, 0x40000C00 };
+static const uint32_t usart_addr[STM_NUM_USARTS] = { 0x40011000, 0x40004400,
+    0x40004800, 0x40004C00, 0x40005000, 0x40011400 };
+
+static const int timer_irq[STM_NUM_TIMERS] = {28, 29, 30, 50};
+static const int usart_irq[STM_NUM_USARTS] = {37, 38, 39, 52, 53, 71};
+
+static void stm32f205_soc_initfn(Object *obj)
+{
+    STM32F205State *s = STM32F205_SOC(obj);
+    int i;
+
+    object_initialize(&s->syscfg, sizeof(s->syscfg), TYPE_STM32F2XX_SYSCFG);
+    qdev_set_parent_bus(DEVICE(&s->syscfg), sysbus_get_default());
+
+    for (i = 0; i < STM_NUM_USARTS; i++) {
+        object_initialize(&s->usart[i], sizeof(s->usart[i]),
+                          TYPE_STM32F2XX_USART);
+        qdev_set_parent_bus(DEVICE(&s->usart[i]), sysbus_get_default());
+    }
+
+    for (i = 0; i < STM_NUM_TIMERS; i++) {
+        object_initialize(&s->timer[i], sizeof(s->timer[i]),
+                          TYPE_STM32F2XX_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, "STM32F205.flash", FLASH_SIZE,
+                           &error_abort);
+    memory_region_init_alias(flash_alias, NULL, "STM32F205.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, "STM32F205.sram", SRAM_SIZE,
+                           &error_abort);
+    vmstate_register_ram_global(sram);
+    memory_region_add_subregion(system_memory, SRAM_BASE_ADDRESS, sram);
+
+    pic = armv7m_init(get_system_memory(), FLASH_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 < STM_NUM_USARTS; 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 < STM_NUM_TIMERS; i++) {
+        timerdev = DEVICE(&(s->timer[i]));
+        qdev_prop_set_uint64(timerdev, "clock-frequency", 1000000000);
+        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..4b71c40
--- /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/stm32f2xx_syscfg.h"
+#include "hw/timer/stm32f2xx_timer.h"
+#include "hw/char/stm32f2xx_usart.h"
+
+#define TYPE_STM32F205_SOC "stm32f205_soc"
+#define STM32F205_SOC(obj) \
+    OBJECT_CHECK(STM32F205State, (obj), TYPE_STM32F205_SOC)
+
+#define STM_NUM_USARTS 6
+#define STM_NUM_TIMERS 4
+
+#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;
+
+    STM32F2XXSyscfgState syscfg;
+    STM32F2XXUsartState usart[STM_NUM_USARTS];
+    STM32F2XXTimerState timer[STM_NUM_TIMERS];
+} STM32F205State;
+
+#endif
-- 
2.1.0

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

* [Qemu-devel] [PATCH v10 5/5] netduino2: Add the Netduino 2 Machine
  2015-01-29 12:31 [Qemu-devel] [PATCH v10 0/5] Netduino 2 Machine Model Alistair Francis
                   ` (3 preceding siblings ...)
  2015-01-29 12:31 ` [Qemu-devel] [PATCH v10 4/5] stm32f205: Add the stm32f205 SoC Alistair Francis
@ 2015-01-29 12:31 ` Alistair Francis
  2015-02-10  6:03   ` Peter Crosthwaite
  4 siblings, 1 reply; 11+ messages in thread
From: Alistair Francis @ 2015-01-29 12:31 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 <alistair@alistair23.me>
---

 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);
-- 
2.1.0

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

* Re: [Qemu-devel] [PATCH v10 2/5] stm32f2xx_USART: Add the stm32f2xx USART Controller
  2015-01-29 12:31 ` [Qemu-devel] [PATCH v10 2/5] stm32f2xx_USART: Add the stm32f2xx USART Controller Alistair Francis
@ 2015-02-10  5:49   ` Peter Crosthwaite
  0 siblings, 0 replies; 11+ messages in thread
From: Peter Crosthwaite @ 2015-02-10  5:49 UTC (permalink / raw)
  To: Alistair Francis
  Cc: Peter Maydell, Martin Galvan, qemu-devel@nongnu.org Developers,
	Konstanty Bialkowski

On Thu, Jan 29, 2015 at 4:31 AM, Alistair Francis <alistair23@gmail.com> wrote:
> This patch adds the stm32f2xx USART controller
> (UART also uses the same controller).
>
> Signed-off-by: Alistair Francis <alistair@alistair23.me>

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

> ---
> V8:
>  - Clear IRQ on reset
>  - Lower IRQ on data read/status clear
>  - Set IRQ if enabled while data is avaliable
> V6:
>  - Rename to STM32F2XX
>  - Fix up unimplemented printing
>  - Add a qemu_chr_accept()
>
>  default-configs/arm-softmmu.mak   |   1 +
>  hw/char/Makefile.objs             |   1 +
>  hw/char/stm32f2xx_usart.c         | 229 ++++++++++++++++++++++++++++++++++++++
>  include/hw/char/stm32f2xx_usart.h |  69 ++++++++++++
>  4 files changed, 300 insertions(+)
>  create mode 100644 hw/char/stm32f2xx_usart.c
>  create mode 100644 include/hw/char/stm32f2xx_usart.h
>
> diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
> index faea100..1348104 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_STM32F2XX_TIMER=y
> +CONFIG_STM32F2XX_USART=y
>
>  CONFIG_VERSATILE_PCI=y
>  CONFIG_VERSATILE_I2C=y
> diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
> index 317385d..5931cc8 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_STM32F2XX_USART) += stm32f2xx_usart.o
>
>  common-obj-$(CONFIG_ETRAXFS) += etraxfs_ser.o
>  common-obj-$(CONFIG_ISA_DEBUG) += debugcon.o
> diff --git a/hw/char/stm32f2xx_usart.c b/hw/char/stm32f2xx_usart.c
> new file mode 100644
> index 0000000..260b053
> --- /dev/null
> +++ b/hw/char/stm32f2xx_usart.c
> @@ -0,0 +1,229 @@
> +/*
> + * STM32F2XX 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/stm32f2xx_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("%s: " fmt, __func__, ## args); \
> +    } \
> +} while (0);
> +
> +#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
> +
> +static int stm32f2xx_usart_can_receive(void *opaque)
> +{
> +    STM32F2XXUsartState *s = opaque;
> +
> +    if (!(s->usart_sr & USART_SR_RXNE)) {
> +        return 1;
> +    }
> +
> +    return 0;
> +}
> +
> +static void stm32f2xx_usart_receive(void *opaque, const uint8_t *buf, int size)
> +{
> +    STM32F2XXUsartState *s = opaque;
> +
> +    s->usart_dr = *buf;
> +
> +    if (!(s->usart_cr1 & USART_CR1_UE && s->usart_cr1 & USART_CR1_RE)) {
> +        /* USART not enabled - drop the chars */
> +        DB_PRINT("Dropping the chars\n");
> +        return;
> +    }
> +
> +    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 stm32f2xx_usart_reset(DeviceState *dev)
> +{
> +    STM32F2XXUsartState *s = STM32F2XX_USART(dev);
> +
> +    s->usart_sr = USART_SR_RESET;
> +    s->usart_dr = 0x00000000;
> +    s->usart_brr = 0x00000000;
> +    s->usart_cr1 = 0x00000000;
> +    s->usart_cr2 = 0x00000000;
> +    s->usart_cr3 = 0x00000000;
> +    s->usart_gtpr = 0x00000000;
> +
> +    qemu_set_irq(s->irq, 0);
> +}
> +
> +static uint64_t stm32f2xx_usart_read(void *opaque, hwaddr addr,
> +                                       unsigned int size)
> +{
> +    STM32F2XXUsartState *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%" PRIx32 ", %c\n", s->usart_dr, (char) s->usart_dr);
> +        s->usart_sr |= USART_SR_TXE;
> +        s->usart_sr &= ~USART_SR_RXNE;
> +        if (s->chr) {
> +            qemu_chr_accept_input(s->chr);
> +        }
> +        qemu_set_irq(s->irq, 0);
> +        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,
> +                      "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
> +        return 0;
> +    }
> +
> +    return 0;
> +}
> +
> +static void stm32f2xx_usart_write(void *opaque, hwaddr addr,
> +                                  uint64_t val64, unsigned int size)
> +{
> +    STM32F2XXUsartState *s = opaque;
> +    uint32_t value = val64;
> +    unsigned char ch;
> +
> +    DB_PRINT("Write 0x%" PRIx32 ", 0x%"HWADDR_PRIx"\n", value, addr);
> +
> +    switch (addr) {
> +    case USART_SR:
> +        if (value <= 0x3FF) {
> +            s->usart_sr = value;
> +        } else {
> +            s->usart_sr &= value;
> +        }
> +        if (!(s->usart_sr & USART_SR_RXNE)) {
> +            qemu_set_irq(s->irq, 0);
> +        }
> +        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;
> +            if (s->usart_cr1 & USART_CR1_RXNEIE &&
> +                s->usart_sr & USART_SR_RXNE) {
> +                qemu_set_irq(s->irq, 1);
> +            }
> +        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,
> +                      "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
> +    }
> +}
> +
> +static const MemoryRegionOps stm32f2xx_usart_ops = {
> +    .read = stm32f2xx_usart_read,
> +    .write = stm32f2xx_usart_write,
> +    .endianness = DEVICE_NATIVE_ENDIAN,
> +};
> +
> +static void stm32f2xx_usart_init(Object *obj)
> +{
> +    STM32F2XXUsartState *s = STM32F2XX_USART(obj);
> +
> +    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
> +
> +    memory_region_init_io(&s->mmio, obj, &stm32f2xx_usart_ops, s,
> +                          TYPE_STM32F2XX_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, stm32f2xx_usart_can_receive,
> +                              stm32f2xx_usart_receive, NULL, s);
> +    }
> +}
> +
> +static void stm32f2xx_usart_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +
> +    dc->reset = stm32f2xx_usart_reset;
> +}
> +
> +static const TypeInfo stm32f2xx_usart_info = {
> +    .name          = TYPE_STM32F2XX_USART,
> +    .parent        = TYPE_SYS_BUS_DEVICE,
> +    .instance_size = sizeof(STM32F2XXUsartState),
> +    .instance_init = stm32f2xx_usart_init,
> +    .class_init    = stm32f2xx_usart_class_init,
> +};
> +
> +static void stm32f2xx_usart_register_types(void)
> +{
> +    type_register_static(&stm32f2xx_usart_info);
> +}
> +
> +type_init(stm32f2xx_usart_register_types)
> diff --git a/include/hw/char/stm32f2xx_usart.h b/include/hw/char/stm32f2xx_usart.h
> new file mode 100644
> index 0000000..c9fad3c
> --- /dev/null
> +++ b/include/hw/char/stm32f2xx_usart.h
> @@ -0,0 +1,69 @@
> +/*
> + * STM32F2XX 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_RESET 0x00C00000
> +
> +#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_STM32F2XX_USART "stm32f2xx-usart"
> +#define STM32F2XX_USART(obj) \
> +    OBJECT_CHECK(STM32F2XXUsartState, (obj), TYPE_STM32F2XX_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;
> +} STM32F2XXUsartState;
> --
> 2.1.0
>
>

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

* Re: [Qemu-devel] [PATCH v10 5/5] netduino2: Add the Netduino 2 Machine
  2015-01-29 12:31 ` [Qemu-devel] [PATCH v10 5/5] netduino2: Add the Netduino 2 Machine Alistair Francis
@ 2015-02-10  6:03   ` Peter Crosthwaite
  0 siblings, 0 replies; 11+ messages in thread
From: Peter Crosthwaite @ 2015-02-10  6:03 UTC (permalink / raw)
  To: Alistair Francis
  Cc: Peter Maydell, Martin Galvan, qemu-devel@nongnu.org Developers,
	Konstanty Bialkowski

On Thu, Jan 29, 2015 at 4:31 AM, Alistair Francis <alistair23@gmail.com> wrote:
> 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 <alistair@alistair23.me>

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

> ---
>
>  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);
> --
> 2.1.0
>
>

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

* Re: [Qemu-devel] [PATCH v10 4/5] stm32f205: Add the stm32f205 SoC
  2015-01-29 12:31 ` [Qemu-devel] [PATCH v10 4/5] stm32f205: Add the stm32f205 SoC Alistair Francis
@ 2015-02-10  6:14   ` Peter Crosthwaite
  2015-02-17 10:35     ` Alistair Francis
  0 siblings, 1 reply; 11+ messages in thread
From: Peter Crosthwaite @ 2015-02-10  6:14 UTC (permalink / raw)
  To: Alistair Francis
  Cc: Peter Maydell, Martin Galvan, qemu-devel@nongnu.org Developers,
	Konstanty Bialkowski

On Thu, Jan 29, 2015 at 4:31 AM, Alistair Francis <alistair23@gmail.com> wrote:
> This patch adds the stm32f205 SoC. This will be used by the
> Netduino 2 to create a machine.
>
> Signed-off-by: Alistair Francis <alistair@alistair23.me>
> ---
> V6:
>  - Correct the number of USART/UART devices
>  - Use macros to define how many devices are inited
>  - Update the memory regions name from netduino.* to
>    STM32F205.*
>
>  default-configs/arm-softmmu.mak |   1 +
>  hw/arm/Makefile.objs            |   1 +
>  hw/arm/stm32f205_soc.c          | 157 ++++++++++++++++++++++++++++++++++++++++
>  include/hw/arm/stm32f205_soc.h  |  69 ++++++++++++++++++
>  4 files changed, 228 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 a5aab7f..9ac755e 100644
> --- a/default-configs/arm-softmmu.mak
> +++ b/default-configs/arm-softmmu.mak
> @@ -81,6 +81,7 @@ CONFIG_ZYNQ=y
>  CONFIG_STM32F2XX_TIMER=y
>  CONFIG_STM32F2XX_USART=y
>  CONFIG_STM32F2XX_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..186e15d
> --- /dev/null
> +++ b/hw/arm/stm32f205_soc.c
> @@ -0,0 +1,157 @@
> +/*
> + * 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[STM_NUM_TIMERS] = { 0x40000000, 0x40000400,
> +    0x40000800, 0x40000C00 };
> +static const uint32_t usart_addr[STM_NUM_USARTS] = { 0x40011000, 0x40004400,
> +    0x40004800, 0x40004C00, 0x40005000, 0x40011400 };
> +
> +static const int timer_irq[STM_NUM_TIMERS] = {28, 29, 30, 50};
> +static const int usart_irq[STM_NUM_USARTS] = {37, 38, 39, 52, 53, 71};
> +
> +static void stm32f205_soc_initfn(Object *obj)
> +{
> +    STM32F205State *s = STM32F205_SOC(obj);
> +    int i;
> +
> +    object_initialize(&s->syscfg, sizeof(s->syscfg), TYPE_STM32F2XX_SYSCFG);
> +    qdev_set_parent_bus(DEVICE(&s->syscfg), sysbus_get_default());
> +
> +    for (i = 0; i < STM_NUM_USARTS; i++) {
> +        object_initialize(&s->usart[i], sizeof(s->usart[i]),
> +                          TYPE_STM32F2XX_USART);
> +        qdev_set_parent_bus(DEVICE(&s->usart[i]), sysbus_get_default());
> +    }
> +
> +    for (i = 0; i < STM_NUM_TIMERS; i++) {
> +        object_initialize(&s->timer[i], sizeof(s->timer[i]),
> +                          TYPE_STM32F2XX_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, "STM32F205.flash", FLASH_SIZE,
> +                           &error_abort);
> +    memory_region_init_alias(flash_alias, NULL, "STM32F205.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, "STM32F205.sram", SRAM_SIZE,
> +                           &error_abort);
> +    vmstate_register_ram_global(sram);
> +    memory_region_add_subregion(system_memory, SRAM_BASE_ADDRESS, sram);
> +
> +    pic = armv7m_init(get_system_memory(), FLASH_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 < STM_NUM_USARTS; 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 < STM_NUM_TIMERS; i++) {
> +        timerdev = DEVICE(&(s->timer[i]));
> +        qdev_prop_set_uint64(timerdev, "clock-frequency", 1000000000);
> +        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..4b71c40
> --- /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"

Is this needed?

> +#include "hw/devices.h"
> +#include "qemu/timer.h"
> +#include "net/net.h"

Is this needed?

> +#include "elf.h"
> +#include "hw/loader.h"

And these.

I think the headers need to be audited for unneeded ones.

> +#include "hw/boards.h"
> +#include "exec/address-spaces.h"
> +#include "qemu/error-report.h"

Also as a general rule, you should limit the header included headers
to the ones that are needed by the header itself. Headers like this
that are only needed for the operation of the C file, can be included
in C files.

> +#include "sysemu/qtest.h"
> +#include "hw/misc/stm32f2xx_syscfg.h"
> +#include "hw/timer/stm32f2xx_timer.h"
> +#include "hw/char/stm32f2xx_usart.h"
> +
> +#define TYPE_STM32F205_SOC "stm32f205_soc"
> +#define STM32F205_SOC(obj) \
> +    OBJECT_CHECK(STM32F205State, (obj), TYPE_STM32F205_SOC)
> +
> +#define STM_NUM_USARTS 6
> +#define STM_NUM_TIMERS 4
> +
> +#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;

What sets this? Can you delete it and just pass NULL to ARMv7 init?

Regards,
Peter

> +
> +    STM32F2XXSyscfgState syscfg;
> +    STM32F2XXUsartState usart[STM_NUM_USARTS];
> +    STM32F2XXTimerState timer[STM_NUM_TIMERS];
> +} STM32F205State;
> +
> +#endif
> --
> 2.1.0
>
>

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

* Re: [Qemu-devel] [PATCH v10 1/5] stm32f2xx_timer: Add the stm32f2xx Timer
  2015-01-29 12:31 ` [Qemu-devel] [PATCH v10 1/5] stm32f2xx_timer: Add the stm32f2xx Timer Alistair Francis
@ 2015-02-10  6:22   ` Peter Crosthwaite
  0 siblings, 0 replies; 11+ messages in thread
From: Peter Crosthwaite @ 2015-02-10  6:22 UTC (permalink / raw)
  To: Alistair Francis
  Cc: Peter Maydell, Martin Galvan, qemu-devel@nongnu.org Developers,
	Konstanty Bialkowski

On Thu, Jan 29, 2015 at 4:31 AM, Alistair Francis <alistair23@gmail.com> wrote:
> This patch adds the stm32f2xx timers: TIM2, TIM3, TIM4 and TIM5
> to QEMU.
>
> Signed-off-by: Alistair Francis <alistair@alistair23.me>
> Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
> ---
> V10:
>  - Correct the units based on a patch by Peter C
> V9:
>  - Convert tick_offset to now be updated on more events
>     - This is similar to what I did with the ARM PCCNT regiseter
> V8:
>  - Fix tick_offset to allow now to wrap around
>  - Remove the calls to get_ticks_per_sec()
>  - Pre-scale the guest visable time
> V6:
>  - Rename to STM32F2XX
>  - Change the timer calculations to use ns
>  - Update the value to timer_mod to ensure it is in ns
>  - Account for reloadable/resetable timer
>     - Thanks to Peter C for pointing this out
>
>  default-configs/arm-softmmu.mak    |   1 +
>  hw/timer/Makefile.objs             |   2 +
>  hw/timer/stm32f2xx_timer.c         | 324 +++++++++++++++++++++++++++++++++++++
>  include/hw/timer/stm32f2xx_timer.h | 101 ++++++++++++
>  4 files changed, 428 insertions(+)
>  create mode 100644 hw/timer/stm32f2xx_timer.c
>  create mode 100644 include/hw/timer/stm32f2xx_timer.h
>
> diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
> index f3513fa..faea100 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_STM32F2XX_TIMER=y
>
>  CONFIG_VERSATILE_PCI=y
>  CONFIG_VERSATILE_I2C=y
> diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
> index 2c86c3d..133bd0d 100644
> --- a/hw/timer/Makefile.objs
> +++ b/hw/timer/Makefile.objs
> @@ -31,3 +31,5 @@ obj-$(CONFIG_DIGIC) += digic-timer.o
>  obj-$(CONFIG_MC146818RTC) += mc146818rtc.o
>
>  obj-$(CONFIG_ALLWINNER_A10_PIT) += allwinner-a10-pit.o
> +
> +common-obj-$(CONFIG_STM32F2XX_TIMER) += stm32f2xx_timer.o
> diff --git a/hw/timer/stm32f2xx_timer.c b/hw/timer/stm32f2xx_timer.c
> new file mode 100644
> index 0000000..72de746
> --- /dev/null
> +++ b/hw/timer/stm32f2xx_timer.c
> @@ -0,0 +1,324 @@
> +/*
> + * STM32F2XX 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/stm32f2xx_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("%s: " fmt, __func__, ## args); \
> +    } \
> +} while (0);
> +
> +#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
> +
> +static void stm32f2xx_timer_set_alarm(STM32F2XXTimerState *s, int64_t now);
> +
> +static void stm32f2xx_timer_interrupt(void *opaque)
> +{
> +    STM32F2XXTimerState *s = opaque;
> +
> +    DB_PRINT("Interrupt\n");
> +
> +    if (s->tim_dier & TIM_DIER_UIE && s->tim_cr1 & TIM_CR1_CEN) {
> +        s->tim_sr |= 1;
> +        qemu_irq_pulse(s->irq);
> +        stm32f2xx_timer_set_alarm(s, s->hit_time);
> +    }
> +}
> +
> +static inline int64_t stm32f2xx_ns_to_ticks(STM32F2XXTimerState *s, int64_t t)
> +{
> +    return muldiv64(t, s->freq_hz, 1000000000ULL) / (s->tim_psc + 1);
> +}
> +
> +static void stm32f2xx_timer_set_alarm(STM32F2XXTimerState *s, int64_t now)
> +{
> +    uint64_t ticks;
> +    int64_t now_ticks;
> +
> +    if (s->tim_arr == 0) {
> +        return;
> +    }
> +
> +    DB_PRINT("Alarm set at: 0x%x\n", s->tim_cr1);
> +
> +    now_ticks = stm32f2xx_ns_to_ticks(s, now);
> +    ticks = s->tim_arr - (now_ticks - s->tick_offset);
> +
> +    DB_PRINT("Alarm set in %d ticks\n", (int) ticks);
> +
> +    s->hit_time = muldiv64((ticks + (uint64_t) now_ticks) * (s->tim_psc + 1),
> +                               1000000000ULL, s->freq_hz);
> +
> +    timer_mod(s->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->hit_time);
> +    DB_PRINT("Wait Time: %" PRId64 " ticks\n", s->hit_time);
> +}
> +
> +static void stm32f2xx_timer_reset(DeviceState *dev)
> +{
> +    STM32F2XXTimerState *s = STM32F2XXTIMER(dev);
> +    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> +
> +    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_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;
> +
> +    s->tick_offset = stm32f2xx_ns_to_ticks(s, now);
> +}
> +
> +static uint64_t stm32f2xx_timer_read(void *opaque, hwaddr offset,
> +                           unsigned size)
> +{
> +    STM32F2XXTimerState *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 stm32f2xx_ns_to_ticks(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)) -
> +               s->tick_offset;
> +    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,
> +                      "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, offset);
> +    }
> +
> +    return 0;
> +}
> +
> +static void stm32f2xx_timer_write(void *opaque, hwaddr offset,
> +                        uint64_t val64, unsigned size)
> +{
> +    STM32F2XXTimerState *s = opaque;
> +    uint32_t value = val64;
> +    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> +    uint32_t timer_val = 0;
> +
> +    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:
> +        /* This is set by hardware and cleared by software */
> +        s->tim_sr &= value;
> +        return;
> +    case TIM_EGR:
> +        s->tim_egr = value;
> +        if (s->tim_egr & TIM_EGR_UG) {
> +            timer_val = 0;
> +            break;
> +        }
> +        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_PSC:
> +        timer_val = stm32f2xx_ns_to_ticks(s, now) - s->tick_offset;
> +        s->tim_psc = value;
> +        value = timer_val;
> +        break;
> +    case TIM_CNT:
> +        timer_val = value;
> +        break;
> +    case TIM_ARR:
> +        s->tim_arr = value;
> +        stm32f2xx_timer_set_alarm(s, now);
> +        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,
> +                      "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, offset);

return;

> +    }

The flow control is a little tricky here and deserves a comment.

"If we get here, a register write has affected the timer in a way that
requires a refresh of both tick_offset and the alarm".

Otherwise

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

Regards,
Peter

> +
> +    s->tick_offset = stm32f2xx_ns_to_ticks(s, now) - timer_val;
> +    stm32f2xx_timer_set_alarm(s, now);
> +}
> +
> +static const MemoryRegionOps stm32f2xx_timer_ops = {
> +    .read = stm32f2xx_timer_read,
> +    .write = stm32f2xx_timer_write,
> +    .endianness = DEVICE_NATIVE_ENDIAN,
> +};
> +
> +static const VMStateDescription vmstate_stm32f2xx_timer = {
> +    .name = TYPE_STM32F2XX_TIMER,
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .fields = (VMStateField[]) {
> +        VMSTATE_INT64(tick_offset, STM32F2XXTimerState),
> +        VMSTATE_UINT32(tim_cr1, STM32F2XXTimerState),
> +        VMSTATE_UINT32(tim_cr2, STM32F2XXTimerState),
> +        VMSTATE_UINT32(tim_smcr, STM32F2XXTimerState),
> +        VMSTATE_UINT32(tim_dier, STM32F2XXTimerState),
> +        VMSTATE_UINT32(tim_sr, STM32F2XXTimerState),
> +        VMSTATE_UINT32(tim_egr, STM32F2XXTimerState),
> +        VMSTATE_UINT32(tim_ccmr1, STM32F2XXTimerState),
> +        VMSTATE_UINT32(tim_ccmr2, STM32F2XXTimerState),
> +        VMSTATE_UINT32(tim_ccer, STM32F2XXTimerState),
> +        VMSTATE_UINT32(tim_psc, STM32F2XXTimerState),
> +        VMSTATE_UINT32(tim_arr, STM32F2XXTimerState),
> +        VMSTATE_UINT32(tim_ccr1, STM32F2XXTimerState),
> +        VMSTATE_UINT32(tim_ccr2, STM32F2XXTimerState),
> +        VMSTATE_UINT32(tim_ccr3, STM32F2XXTimerState),
> +        VMSTATE_UINT32(tim_ccr4, STM32F2XXTimerState),
> +        VMSTATE_UINT32(tim_dcr, STM32F2XXTimerState),
> +        VMSTATE_UINT32(tim_dmar, STM32F2XXTimerState),
> +        VMSTATE_UINT32(tim_or, STM32F2XXTimerState),
> +        VMSTATE_END_OF_LIST()
> +    }
> +};
> +
> +static Property stm32f2xx_timer_properties[] = {
> +    DEFINE_PROP_UINT64("clock-frequency", struct STM32F2XXTimerState,
> +                       freq_hz, 1000000000),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void stm32f2xx_timer_init(Object *obj)
> +{
> +    STM32F2XXTimerState *s = STM32F2XXTIMER(obj);
> +
> +    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
> +
> +    memory_region_init_io(&s->iomem, obj, &stm32f2xx_timer_ops, s,
> +                          "stm32f2xx_timer", 0x4000);
> +    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
> +
> +    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, stm32f2xx_timer_interrupt, s);
> +}
> +
> +static void stm32f2xx_timer_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +
> +    dc->reset = stm32f2xx_timer_reset;
> +    dc->props = stm32f2xx_timer_properties;
> +    dc->vmsd = &vmstate_stm32f2xx_timer;
> +}
> +
> +static const TypeInfo stm32f2xx_timer_info = {
> +    .name          = TYPE_STM32F2XX_TIMER,
> +    .parent        = TYPE_SYS_BUS_DEVICE,
> +    .instance_size = sizeof(STM32F2XXTimerState),
> +    .instance_init = stm32f2xx_timer_init,
> +    .class_init    = stm32f2xx_timer_class_init,
> +};
> +
> +static void stm32f2xx_timer_register_types(void)
> +{
> +    type_register_static(&stm32f2xx_timer_info);
> +}
> +
> +type_init(stm32f2xx_timer_register_types)
> diff --git a/include/hw/timer/stm32f2xx_timer.h b/include/hw/timer/stm32f2xx_timer.h
> new file mode 100644
> index 0000000..7362d70
> --- /dev/null
> +++ b/include/hw/timer/stm32f2xx_timer.h
> @@ -0,0 +1,101 @@
> +/*
> + * STM32F2XX 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_EGR_UG 1
> +
> +#define TIM_CCER_CC2E   (1 << 4)
> +#define TIM_CCMR1_OC2M2 (1 << 14)
> +#define TIM_CCMR1_OC2M1 (1 << 13)
> +#define TIM_CCMR1_OC2M0 (1 << 12)
> +#define TIM_CCMR1_OC2PE (1 << 11)
> +
> +#define TIM_DIER_UIE  1
> +
> +#define TYPE_STM32F2XX_TIMER "stm32f2xx-timer"
> +#define STM32F2XXTIMER(obj) OBJECT_CHECK(STM32F2XXTimerState, \
> +                            (obj), TYPE_STM32F2XX_TIMER)
> +
> +typedef struct STM32F2XXTimerState {
> +    /* <private> */
> +    SysBusDevice parent_obj;
> +
> +    /* <public> */
> +    MemoryRegion iomem;
> +    QEMUTimer *timer;
> +    qemu_irq irq;
> +
> +    int64_t tick_offset;
> +    uint64_t hit_time;
> +    uint64_t freq_hz;
> +
> +    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_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;
> +} STM32F2XXTimerState;
> +
> +#endif
> --
> 2.1.0
>
>

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

* Re: [Qemu-devel] [PATCH v10 4/5] stm32f205: Add the stm32f205 SoC
  2015-02-10  6:14   ` Peter Crosthwaite
@ 2015-02-17 10:35     ` Alistair Francis
  0 siblings, 0 replies; 11+ messages in thread
From: Alistair Francis @ 2015-02-17 10:35 UTC (permalink / raw)
  To: Peter Crosthwaite
  Cc: Peter Maydell, Martin Galvan, qemu-devel@nongnu.org Developers,
	Konstanty Bialkowski

On Tue, Feb 10, 2015 at 4:14 PM, Peter Crosthwaite
<peter.crosthwaite@xilinx.com> wrote:
> On Thu, Jan 29, 2015 at 4:31 AM, Alistair Francis <alistair23@gmail.com> wrote:
>> This patch adds the stm32f205 SoC. This will be used by the
>> Netduino 2 to create a machine.
>>
>> Signed-off-by: Alistair Francis <alistair@alistair23.me>
>> ---
>> V6:
>>  - Correct the number of USART/UART devices
>>  - Use macros to define how many devices are inited
>>  - Update the memory regions name from netduino.* to
>>    STM32F205.*
>>
>>  default-configs/arm-softmmu.mak |   1 +
>>  hw/arm/Makefile.objs            |   1 +
>>  hw/arm/stm32f205_soc.c          | 157 ++++++++++++++++++++++++++++++++++++++++
>>  include/hw/arm/stm32f205_soc.h  |  69 ++++++++++++++++++
>>  4 files changed, 228 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 a5aab7f..9ac755e 100644
>> --- a/default-configs/arm-softmmu.mak
>> +++ b/default-configs/arm-softmmu.mak
>> @@ -81,6 +81,7 @@ CONFIG_ZYNQ=y
>>  CONFIG_STM32F2XX_TIMER=y
>>  CONFIG_STM32F2XX_USART=y
>>  CONFIG_STM32F2XX_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..186e15d
>> --- /dev/null
>> +++ b/hw/arm/stm32f205_soc.c
>> @@ -0,0 +1,157 @@
>> +/*
>> + * 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[STM_NUM_TIMERS] = { 0x40000000, 0x40000400,
>> +    0x40000800, 0x40000C00 };
>> +static const uint32_t usart_addr[STM_NUM_USARTS] = { 0x40011000, 0x40004400,
>> +    0x40004800, 0x40004C00, 0x40005000, 0x40011400 };
>> +
>> +static const int timer_irq[STM_NUM_TIMERS] = {28, 29, 30, 50};
>> +static const int usart_irq[STM_NUM_USARTS] = {37, 38, 39, 52, 53, 71};
>> +
>> +static void stm32f205_soc_initfn(Object *obj)
>> +{
>> +    STM32F205State *s = STM32F205_SOC(obj);
>> +    int i;
>> +
>> +    object_initialize(&s->syscfg, sizeof(s->syscfg), TYPE_STM32F2XX_SYSCFG);
>> +    qdev_set_parent_bus(DEVICE(&s->syscfg), sysbus_get_default());
>> +
>> +    for (i = 0; i < STM_NUM_USARTS; i++) {
>> +        object_initialize(&s->usart[i], sizeof(s->usart[i]),
>> +                          TYPE_STM32F2XX_USART);
>> +        qdev_set_parent_bus(DEVICE(&s->usart[i]), sysbus_get_default());
>> +    }
>> +
>> +    for (i = 0; i < STM_NUM_TIMERS; i++) {
>> +        object_initialize(&s->timer[i], sizeof(s->timer[i]),
>> +                          TYPE_STM32F2XX_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, "STM32F205.flash", FLASH_SIZE,
>> +                           &error_abort);
>> +    memory_region_init_alias(flash_alias, NULL, "STM32F205.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, "STM32F205.sram", SRAM_SIZE,
>> +                           &error_abort);
>> +    vmstate_register_ram_global(sram);
>> +    memory_region_add_subregion(system_memory, SRAM_BASE_ADDRESS, sram);
>> +
>> +    pic = armv7m_init(get_system_memory(), FLASH_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 < STM_NUM_USARTS; 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 < STM_NUM_TIMERS; i++) {
>> +        timerdev = DEVICE(&(s->timer[i]));
>> +        qdev_prop_set_uint64(timerdev, "clock-frequency", 1000000000);
>> +        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..4b71c40
>> --- /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"
>
> Is this needed?
>
>> +#include "hw/devices.h"
>> +#include "qemu/timer.h"
>> +#include "net/net.h"
>
> Is this needed?
>
>> +#include "elf.h"
>> +#include "hw/loader.h"
>
> And these.
>
> I think the headers need to be audited for unneeded ones.
>
>> +#include "hw/boards.h"
>> +#include "exec/address-spaces.h"
>> +#include "qemu/error-report.h"
>
> Also as a general rule, you should limit the header included headers
> to the ones that are needed by the header itself. Headers like this
> that are only needed for the operation of the C file, can be included
> in C files.

Ok, I used to do it the other way around I will fix this up.

>
>> +#include "sysemu/qtest.h"
>> +#include "hw/misc/stm32f2xx_syscfg.h"
>> +#include "hw/timer/stm32f2xx_timer.h"
>> +#include "hw/char/stm32f2xx_usart.h"
>> +
>> +#define TYPE_STM32F205_SOC "stm32f205_soc"
>> +#define STM32F205_SOC(obj) \
>> +    OBJECT_CHECK(STM32F205State, (obj), TYPE_STM32F205_SOC)
>> +
>> +#define STM_NUM_USARTS 6
>> +#define STM_NUM_TIMERS 4
>> +
>> +#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;
>
> What sets this? Can you delete it and just pass NULL to ARMv7 init?

It isn't really required, I have made it a property now.

Thanks for the feedback and reviews, I have made all changes and am
re-sending now.

Thanks,

Alistair

>
> Regards,
> Peter
>
>> +
>> +    STM32F2XXSyscfgState syscfg;
>> +    STM32F2XXUsartState usart[STM_NUM_USARTS];
>> +    STM32F2XXTimerState timer[STM_NUM_TIMERS];
>> +} STM32F205State;
>> +
>> +#endif
>> --
>> 2.1.0
>>
>>

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

end of thread, other threads:[~2015-02-17 10:36 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-29 12:31 [Qemu-devel] [PATCH v10 0/5] Netduino 2 Machine Model Alistair Francis
2015-01-29 12:31 ` [Qemu-devel] [PATCH v10 1/5] stm32f2xx_timer: Add the stm32f2xx Timer Alistair Francis
2015-02-10  6:22   ` Peter Crosthwaite
2015-01-29 12:31 ` [Qemu-devel] [PATCH v10 2/5] stm32f2xx_USART: Add the stm32f2xx USART Controller Alistair Francis
2015-02-10  5:49   ` Peter Crosthwaite
2015-01-29 12:31 ` [Qemu-devel] [PATCH v10 3/5] stm32f2xx_SYSCFG: Add the stm32f2xx SYSCFG Alistair Francis
2015-01-29 12:31 ` [Qemu-devel] [PATCH v10 4/5] stm32f205: Add the stm32f205 SoC Alistair Francis
2015-02-10  6:14   ` Peter Crosthwaite
2015-02-17 10:35     ` Alistair Francis
2015-01-29 12:31 ` [Qemu-devel] [PATCH v10 5/5] netduino2: Add the Netduino 2 Machine Alistair Francis
2015-02-10  6:03   ` Peter Crosthwaite

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.