All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [Qemu-devel RFC 1/3] msf2: Add Smartfusion2 System timer
@ 2017-03-19 12:02 Subbaraya Sundeep
  2017-03-19 12:02 ` [Qemu-devel] [Qemu-devel RFC 2/3] msf2: Microsemi Smartfusion2 System Register block Subbaraya Sundeep
  2017-03-19 12:02 ` [Qemu-devel] [Qemu-devel RFC 3/3] msf2: Add Emcraft's Smartfusion2 SOM kit Subbaraya Sundeep
  0 siblings, 2 replies; 3+ messages in thread
From: Subbaraya Sundeep @ 2017-03-19 12:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, crosthwaite.peter, Subbaraya Sundeep

Modelled System Timer in Microsemi's Smartfusion2 Soc.
Timer has two 32bit down counters and two interrupts.

Signed-off-by: Subbaraya Sundeep <sundeep.lkml@gmail.com>
---
 hw/timer/Makefile.objs |   1 +
 hw/timer/msf2_timer.c  | 273 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 274 insertions(+)
 create mode 100644 hw/timer/msf2_timer.c

diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index dd6f27e..0bdf1e1 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -41,3 +41,4 @@ common-obj-$(CONFIG_STM32F2XX_TIMER) += stm32f2xx_timer.o
 common-obj-$(CONFIG_ASPEED_SOC) += aspeed_timer.o
 
 common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
+common-obj-$(CONFIG_MSF2) += msf2_timer.o
diff --git a/hw/timer/msf2_timer.c b/hw/timer/msf2_timer.c
new file mode 100644
index 0000000..ce34601
--- /dev/null
+++ b/hw/timer/msf2_timer.c
@@ -0,0 +1,273 @@
+/*
+ * QEMU model of the Microsemi SmartFusion2 timer.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep <sundeep.lkml@gmail.com>.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "hw/ptimer.h"
+#include "qemu/log.h"
+#include "qemu/main-loop.h"
+
+#define D(x)
+
+#define NUM_TIMERS     2
+
+#define R_VAL          0
+#define R_LOADVAL      1
+#define R_BGLOADVAL    2
+#define R_CTRL         3
+#define R_RIS          4
+#define R_MIS          5
+#define R_MAX          6
+
+#define TIMER_CTRL_ENBL     (1 << 0)
+#define TIMER_CTRL_ONESHOT  (1 << 1)
+#define TIMER_CTRL_INTR     (1 << 2)
+#define TIMER_RIS_ACK       (1 << 0)
+#define TIMER_RST_CLR       (1 << 6)
+
+struct msf2_timer {
+    QEMUBH *bh;
+    ptimer_state *ptimer;
+    void *parent;
+    int nr; /* for debug.  */
+
+    unsigned long timer_div;
+
+    uint32_t regs[R_MAX];
+    qemu_irq irq;
+};
+
+#define TYPE_MSF2_TIMER "msf2-timer"
+#define MSF2_TIMER(obj) \
+    OBJECT_CHECK(struct timerblock, (obj), TYPE_MSF2_TIMER)
+
+struct timerblock {
+    SysBusDevice parent_obj;
+
+    MemoryRegion mmio;
+    uint32_t freq_hz;
+    struct msf2_timer *timers;
+};
+
+static inline unsigned int timer_from_addr(hwaddr addr)
+{
+    /* Timers get a 6x32bit control reg area each.  */
+    return addr / R_MAX;
+}
+
+static void timer_update_irq(struct msf2_timer *st)
+{
+    int isr;
+    int ier;
+
+    isr = !!(st->regs[R_RIS] & TIMER_RIS_ACK);
+    ier = !!(st->regs[R_CTRL] & TIMER_CTRL_INTR);
+
+    qemu_set_irq(st->irq, (ier && isr));
+}
+
+static uint64_t
+timer_read(void *opaque, hwaddr addr, unsigned int size)
+{
+    struct timerblock *t = opaque;
+    struct msf2_timer *st;
+    uint32_t r = 0;
+    unsigned int timer;
+    int isr;
+    int ier;
+
+    addr >>= 2;
+    timer = timer_from_addr(addr);
+    st = &t->timers[timer];
+
+    if (timer) {
+        addr -= 6;
+    }
+
+    switch (addr) {
+    case R_VAL:
+        r = ptimer_get_count(st->ptimer);
+        D(qemu_log("msf2_timer t=%d read counter=%x\n", timer, r));
+        break;
+
+    case R_MIS:
+        isr = !!(st->regs[R_RIS] & TIMER_RIS_ACK);
+        ier = !!(st->regs[R_CTRL] & TIMER_CTRL_INTR);
+        r = ier && isr;
+        break;
+
+    default:
+        if (addr < ARRAY_SIZE(st->regs)) {
+            r = st->regs[addr];
+        }
+        break;
+    }
+    D(fprintf(stderr, "%s timer=%d %x=%x\n", __func__, timer, addr * 4, r));
+    return r;
+}
+
+static void timer_update(struct msf2_timer *st)
+{
+    uint64_t count;
+
+    D(fprintf(stderr, "%s timer=%d\n", __func__, st->nr));
+
+    if (!(st->regs[R_CTRL] & TIMER_CTRL_ENBL)) {
+        ptimer_stop(st->ptimer);
+        return;
+    }
+
+    count = st->regs[R_LOADVAL];
+    ptimer_set_limit(st->ptimer, count, 1);
+    ptimer_run(st->ptimer, 1);
+}
+
+static void
+timer_write(void *opaque, hwaddr addr,
+            uint64_t val64, unsigned int size)
+{
+    struct timerblock *t = opaque;
+    struct msf2_timer *st;
+    unsigned int timer;
+    uint32_t value = val64;
+
+    addr >>= 2;
+    timer = timer_from_addr(addr);
+    st = &t->timers[timer];
+    D(fprintf(stderr, "%s addr=%x val=%x (timer=%d)\n",
+             __func__, addr * 4, value, timer));
+
+    if (timer) {
+        addr -= 6;
+    }
+
+    switch (addr) {
+    case R_CTRL:
+        st->regs[R_CTRL] = value;
+        timer_update(st);
+        break;
+
+    case R_RIS:
+        if (value & TIMER_RIS_ACK) {
+            st->regs[R_RIS] &= ~TIMER_RIS_ACK;
+        }
+        break;
+
+    case R_LOADVAL:
+        st->regs[R_LOADVAL] = value;
+        if (st->regs[R_CTRL] & TIMER_CTRL_ENBL) {
+            timer_update(st);
+        }
+        break;
+
+    case R_BGLOADVAL:
+        st->regs[R_BGLOADVAL] = value;
+        st->regs[R_LOADVAL] = value;
+        break;
+
+    case R_VAL:
+    case R_MIS:
+        break;
+
+    default:
+        if (addr < ARRAY_SIZE(st->regs)) {
+            st->regs[addr] = value;
+        }
+        break;
+    }
+    timer_update_irq(st);
+}
+
+static const MemoryRegionOps timer_ops = {
+    .read = timer_read,
+    .write = timer_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4
+    }
+};
+
+static void timer_hit(void *opaque)
+{
+    struct msf2_timer *st = opaque;
+    D(fprintf(stderr, "%s %d\n", __func__, st->nr));
+    st->regs[R_RIS] |= TIMER_RIS_ACK;
+
+    if (!(st->regs[R_CTRL] & TIMER_CTRL_ONESHOT)) {
+        timer_update(st);
+    }
+    timer_update_irq(st);
+}
+
+static void msf2_timer_realize(DeviceState *dev, Error **errp)
+{
+    struct timerblock *t = MSF2_TIMER(dev);
+    unsigned int i;
+
+    /* Init all the ptimers.  */
+    t->timers = g_malloc0((sizeof t->timers[0]) * NUM_TIMERS);
+    for (i = 0; i < NUM_TIMERS; i++) {
+        struct msf2_timer *st = &t->timers[i];
+
+        st->parent = t;
+        st->nr = i;
+        st->bh = qemu_bh_new(timer_hit, st);
+        st->ptimer = ptimer_init(st->bh, PTIMER_POLICY_DEFAULT);
+        ptimer_set_freq(st->ptimer, t->freq_hz);
+        sysbus_init_irq(SYS_BUS_DEVICE(dev), &st->irq);
+    }
+
+    memory_region_init_io(&t->mmio, OBJECT(t), &timer_ops, t, "msf2-timer",
+                          R_MAX * 4 * NUM_TIMERS);
+    sysbus_init_mmio(SYS_BUS_DEVICE(dev), &t->mmio);
+}
+
+static Property msf2_timer_properties[] = {
+    DEFINE_PROP_UINT32("clock-frequency", struct timerblock, freq_hz,
+                                                                83 * 1000000),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void msf2_timer_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = msf2_timer_realize;
+    dc->props = msf2_timer_properties;
+}
+
+static const TypeInfo msf2_timer_info = {
+    .name          = TYPE_MSF2_TIMER,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(struct timerblock),
+    .class_init    = msf2_timer_class_init,
+};
+
+static void msf2_timer_register_types(void)
+{
+    type_register_static(&msf2_timer_info);
+}
+
+type_init(msf2_timer_register_types)
-- 
2.5.0

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

* [Qemu-devel] [Qemu-devel RFC 2/3] msf2: Microsemi Smartfusion2 System Register block.
  2017-03-19 12:02 [Qemu-devel] [Qemu-devel RFC 1/3] msf2: Add Smartfusion2 System timer Subbaraya Sundeep
@ 2017-03-19 12:02 ` Subbaraya Sundeep
  2017-03-19 12:02 ` [Qemu-devel] [Qemu-devel RFC 3/3] msf2: Add Emcraft's Smartfusion2 SOM kit Subbaraya Sundeep
  1 sibling, 0 replies; 3+ messages in thread
From: Subbaraya Sundeep @ 2017-03-19 12:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, crosthwaite.peter, Subbaraya Sundeep

Added Sytem register block of Smartfusion2.
This block has PLL registers which are accessed by guest.

Signed-off-by: Subbaraya Sundeep <sundeep.lkml@gmail.com>
---
 hw/misc/Makefile.objs |   1 +
 hw/misc/msf2_sysreg.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 169 insertions(+)
 create mode 100644 hw/misc/msf2_sysreg.c

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index c8b4893..aee53df 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -56,3 +56,4 @@ obj-$(CONFIG_EDU) += edu.o
 obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
 obj-$(CONFIG_AUX) += auxbus.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o
+obj-$(CONFIG_MSF2) += msf2_sysreg.o
diff --git a/hw/misc/msf2_sysreg.c b/hw/misc/msf2_sysreg.c
new file mode 100644
index 0000000..4873463
--- /dev/null
+++ b/hw/misc/msf2_sysreg.c
@@ -0,0 +1,168 @@
+/*
+ * System Register block model of Microsemi SmartFusion2.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep <sundeep.lkml@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/hw.h"
+#include "qemu/timer.h"
+#include "hw/sysbus.h"
+#include "sysemu/sysemu.h"
+#include "qemu/log.h"
+
+#ifndef MSF2_SYSREG_ERR_DEBUG
+#define MSF2_SYSREG_ERR_DEBUG 0
+#endif
+
+#define DB_PRINT(...) do { \
+        if (MSF2_SYSREG_ERR_DEBUG) { \
+            fprintf(stderr,  ": %s: ", __func__); \
+            fprintf(stderr, ## __VA_ARGS__); \
+        } \
+    } while (0);
+
+#define R_PSS_RST_CTRL_SOFT_RST 0x1
+
+enum {
+    ESRAM_CR        = 0x00 / 4,
+    ESRAM_MAX_LAT,
+    DDR_CR,
+    ENVM_CR,
+    ENVM_REMAP_BASE_CR,
+    ENVM_REMAP_FAB_CR,
+    CC_CR,
+    CC_REGION_CR,
+    CC_LOCK_BASE_ADDR_CR,
+    CC_FLUSH_INDX_CR,
+    DDRB_BUF_TIMER_CR,
+    DDRB_NB_ADDR_CR,
+    DDRB_NB_SIZE_CR,
+    DDRB_CR,
+
+    SOFT_RESET_CR  = 0x48 / 4,
+    M3_CR,
+
+    GPIO_SYSRESET_SEL_CR = 0x58 / 4,
+
+    MDDR_CR = 0x60 / 4,
+
+    MSSDDR_PLL_STATUS_LOW_CR = 0x90 / 4,
+    MSSDDR_PLL_STATUS_HIGH_CR,
+    MSSDDR_FACC1_CR,
+    MSSDDR_FACC2_CR,
+
+    MSSDDR_PLL_STATUS = 0x150 / 4,
+
+};
+
+#define MSF2_SYSREG_MMIO_SIZE     0x300
+#define MSF2_SYSREG_NUM_REGS      (MSF2_SYSREG_MMIO_SIZE / 4)
+
+#define TYPE_MSF2_SYSREG          "msf2-sysreg"
+#define MSF2_SYSREG(obj)  OBJECT_CHECK(Sf2SysregState, (obj), TYPE_MSF2_SYSREG)
+
+typedef struct Sf2SysregState {
+    SysBusDevice parent_obj;
+
+    MemoryRegion iomem;
+
+    uint32_t regs[MSF2_SYSREG_NUM_REGS];
+} Sf2SysregState;
+
+static void msf2_sysreg_reset(DeviceState *d)
+{
+    Sf2SysregState *s = MSF2_SYSREG(d);
+
+    DB_PRINT("RESET\n");
+
+    s->regs[MSSDDR_PLL_STATUS_LOW_CR] = 0x02420041;
+    s->regs[MSSDDR_FACC1_CR] = 0x0A482124;
+    s->regs[MSSDDR_PLL_STATUS] = 0x3;
+}
+
+static uint64_t msf2_sysreg_read(void *opaque, hwaddr offset,
+    unsigned size)
+{
+    Sf2SysregState *s = opaque;
+    offset /= 4;
+    uint32_t ret = s->regs[offset];
+
+    DB_PRINT("addr: %08" HWADDR_PRIx " data: %08" PRIx32 "\n", offset * 4, ret);
+
+   return ret;
+}
+
+static void msf2_sysreg_write(void *opaque, hwaddr offset,
+                          uint64_t val, unsigned size)
+{
+    Sf2SysregState *s = (Sf2SysregState *)opaque;
+    offset /= 4;
+
+    DB_PRINT("addr: %08" HWADDR_PRIx " data: %08" PRIx64 "\n", offset * 4, val);
+
+    switch (offset) {
+    case MSSDDR_PLL_STATUS:
+        break;
+
+    default:
+        s->regs[offset] = val;
+        break;
+    }
+}
+
+static const MemoryRegionOps sysreg_ops = {
+    .read = msf2_sysreg_read,
+    .write = msf2_sysreg_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void msf2_sysreg_init(Object *obj)
+{
+    Sf2SysregState *s = MSF2_SYSREG(obj);
+
+    memory_region_init_io(&s->iomem, obj, &sysreg_ops, s, "sysreg",
+                          MSF2_SYSREG_MMIO_SIZE);
+    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
+}
+
+static const VMStateDescription vmstate_msf2_sysreg = {
+    .name = "msf2_sysreg",
+    .version_id = 2,
+    .minimum_version_id = 2,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(regs, Sf2SysregState, MSF2_SYSREG_NUM_REGS),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void msf2_sysreg_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->vmsd = &vmstate_msf2_sysreg;
+    dc->reset = msf2_sysreg_reset;
+}
+
+static const TypeInfo msf2_sysreg_info = {
+    .class_init = msf2_sysreg_class_init,
+    .name  = TYPE_MSF2_SYSREG,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size  = sizeof(Sf2SysregState),
+    .instance_init = msf2_sysreg_init,
+};
+
+static void msf2_sysreg_register_types(void)
+{
+    type_register_static(&msf2_sysreg_info);
+}
+
+type_init(msf2_sysreg_register_types)
-- 
2.5.0

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

* [Qemu-devel] [Qemu-devel RFC 3/3] msf2: Add Emcraft's Smartfusion2 SOM kit.
  2017-03-19 12:02 [Qemu-devel] [Qemu-devel RFC 1/3] msf2: Add Smartfusion2 System timer Subbaraya Sundeep
  2017-03-19 12:02 ` [Qemu-devel] [Qemu-devel RFC 2/3] msf2: Microsemi Smartfusion2 System Register block Subbaraya Sundeep
@ 2017-03-19 12:02 ` Subbaraya Sundeep
  1 sibling, 0 replies; 3+ messages in thread
From: Subbaraya Sundeep @ 2017-03-19 12:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, crosthwaite.peter, Subbaraya Sundeep

Emulated Emcraft's Smartfusion2 System On Module starter
kit.

Signed-off-by: Subbaraya Sundeep <sundeep.lkml@gmail.com>
---
 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs            |   2 +-
 hw/arm/msf2_soc.c               | 122 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 124 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/msf2_soc.c

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 1e3bd2b..379f7e1 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -121,3 +121,4 @@ CONFIG_ACPI=y
 CONFIG_SMBIOS=y
 CONFIG_ASPEED_SOC=y
 CONFIG_GPIO_KEY=y
+CONFIG_MSF2=y
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 4c5c4ee..cce2759 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -1,7 +1,7 @@
 obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o
 obj-$(CONFIG_DIGIC) += digic_boards.o
 obj-y += integratorcp.o mainstone.o musicpal.o nseries.o
-obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o
+obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o msf2_soc.o
 obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o
 obj-$(CONFIG_ACPI) += virt-acpi-build.o
 obj-y += netduino2.o
diff --git a/hw/arm/msf2_soc.c b/hw/arm/msf2_soc.c
new file mode 100644
index 0000000..53da55b
--- /dev/null
+++ b/hw/arm/msf2_soc.c
@@ -0,0 +1,122 @@
+/*
+ * Smartfusion2 SOM starter kit(from Emcraft) emulation.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep <sundeep.lkml@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "hw/arm/arm.h"
+#include "exec/address-spaces.h"
+#include "hw/sysbus.h"
+#include "hw/char/serial.h"
+#include "hw/boards.h"
+#include "sysemu/block-backend.h"
+
+#define MSF2_NUM_USARTS      1
+#define MSF2_NUM_TIMERS      2
+
+#define ENVM_BASE_ADDRESS    0x60000000
+#define ENVM_SIZE            (128 * 1024)
+
+#define DDR_BASE_ADDRESS     0xA0000000
+#define DDR_SIZE             (1024 * 1024 * 1024)
+
+#define SRAM_BASE_ADDRESS    0x20000000
+#define SRAM_SIZE            (64 * 1024)
+
+#define MSF2_TIMER_BASE      0x40004000
+#define MSF2_SYSREG_BASE     0x40038000
+
+static const uint32_t usart_addr[MSF2_NUM_USARTS] = { 0x40000000 };
+
+static const int timer_irq[MSF2_NUM_TIMERS] = {14, 15};
+static const int usart_irq[MSF2_NUM_USARTS] = {10};
+
+static void msf2_init(MachineState *machine)
+{
+    const char *kernel_filename = NULL;
+    DeviceState *dev, *nvic;
+    int i;
+    MemoryRegion *system_memory = get_system_memory();
+    MemoryRegion *nvm = g_new(MemoryRegion, 1);
+    MemoryRegion *nvm_alias = g_new(MemoryRegion, 1);
+    MemoryRegion *sram = g_new(MemoryRegion, 1);
+    MemoryRegion *ddr = g_new(MemoryRegion, 1);
+    QemuOpts *machine_opts = qemu_get_machine_opts();
+
+    kernel_filename = qemu_opt_get(machine_opts, "kernel");
+
+    memory_region_init_ram(nvm, NULL, "MSF2.envm", ENVM_SIZE,
+                           &error_fatal);
+    memory_region_init_alias(nvm_alias, NULL, "STM32F205.flash.alias",
+                             nvm, 0, ENVM_SIZE);
+    vmstate_register_ram_global(nvm);
+
+    memory_region_set_readonly(nvm, true);
+    memory_region_set_readonly(nvm_alias, true);
+
+    memory_region_add_subregion(system_memory, ENVM_BASE_ADDRESS, nvm);
+    memory_region_add_subregion(system_memory, 0, nvm_alias);
+
+    memory_region_init_ram(ddr, NULL, "MSF2.ddr", DDR_SIZE,
+                           &error_fatal);
+    vmstate_register_ram_global(ddr);
+    memory_region_add_subregion(system_memory, DDR_BASE_ADDRESS, ddr);
+
+    memory_region_init_ram(sram, NULL, "MSF2.sram", SRAM_SIZE,
+                           &error_fatal);
+    vmstate_register_ram_global(sram);
+    memory_region_add_subregion(system_memory, SRAM_BASE_ADDRESS, sram);
+
+    nvic = armv7m_init(system_memory, ENVM_SIZE, 96,
+                       kernel_filename, "cortex-m3");
+
+    for (i = 0; i < MSF2_NUM_USARTS; i++) {
+        if (serial_hds[i]) {
+            serial_mm_init(get_system_memory(), usart_addr[i], 2,
+                           qdev_get_gpio_in(nvic, usart_irq[i]),
+                           115200, serial_hds[i], DEVICE_NATIVE_ENDIAN);
+        }
+    }
+
+    dev = qdev_create(NULL, "msf2-timer");
+    qdev_prop_set_uint32(dev, "clock-frequency", 83 * 1000000);
+    qdev_init_nofail(dev);
+    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, MSF2_TIMER_BASE);
+    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
+                           qdev_get_gpio_in(nvic, timer_irq[0]));
+    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1,
+                           qdev_get_gpio_in(nvic, timer_irq[1]));
+
+    dev = qdev_create(NULL, "msf2-sysreg");
+    qdev_init_nofail(dev);
+    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, MSF2_SYSREG_BASE);
+}
+
+static void msf2_machine_init(MachineClass *mc)
+{
+    mc->desc = "Microsemi Smart Fusion2 Development Kit";
+    mc->init = msf2_init;
+}
+
+DEFINE_MACHINE("smartfusion2", msf2_machine_init)
-- 
2.5.0

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

end of thread, other threads:[~2017-03-19 12:02 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-19 12:02 [Qemu-devel] [Qemu-devel RFC 1/3] msf2: Add Smartfusion2 System timer Subbaraya Sundeep
2017-03-19 12:02 ` [Qemu-devel] [Qemu-devel RFC 2/3] msf2: Microsemi Smartfusion2 System Register block Subbaraya Sundeep
2017-03-19 12:02 ` [Qemu-devel] [Qemu-devel RFC 3/3] msf2: Add Emcraft's Smartfusion2 SOM kit Subbaraya Sundeep

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.