[Qemu-devel] [[Qemu devel] RFC] hw/net: Add Smartfusion2 emac block

2018-05-26 Thread Subbaraya Sundeep
Modelled Ethernet MAC of Smartfusion2 SoC.
Micrel KSZ8051 PHY is present on Emcraft's SOM kit hence same
PHY is emulated.

Signed-off-by: Subbaraya Sundeep 
---
 hw/arm/msf2-soc.c |  21 +-
 hw/net/Makefile.objs  |   1 +
 hw/net/mss-emac.c | 544 ++
 include/hw/arm/msf2-soc.h |   3 +
 include/hw/net/mss-emac.h |  23 ++
 5 files changed, 591 insertions(+), 1 deletion(-)
 create mode 100644 hw/net/mss-emac.c
 create mode 100644 include/hw/net/mss-emac.h

diff --git a/hw/arm/msf2-soc.c b/hw/arm/msf2-soc.c
index 75c44ad..ed3d0f5 100644
--- a/hw/arm/msf2-soc.c
+++ b/hw/arm/msf2-soc.c
@@ -35,6 +35,7 @@
 
 #define MSF2_TIMER_BASE   0x40004000
 #define MSF2_SYSREG_BASE  0x40038000
+#define MSF2_EMAC_BASE0x40041000
 
 #define ENVM_BASE_ADDRESS 0x6000
 
@@ -55,6 +56,7 @@ static const uint32_t uart_addr[MSF2_NUM_UARTS] = { 
0x4000 , 0x4001 };
 static const int spi_irq[MSF2_NUM_SPIS] = { 2, 3 };
 static const int uart_irq[MSF2_NUM_UARTS] = { 10, 11 };
 static const int timer_irq[MSF2_NUM_TIMERS] = { 14, 15 };
+static const int emac_irq[MSF2_NUM_EMACS] = { 12 };
 
 static void do_sys_reset(void *opaque, int n, int level)
 {
@@ -82,6 +84,13 @@ static void m2sxxx_soc_initfn(Object *obj)
   TYPE_MSS_SPI);
 qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default());
 }
+
+object_initialize(&s->emac, sizeof(s->emac), TYPE_MSS_EMAC);
+qdev_set_parent_bus(DEVICE(&s->emac), sysbus_get_default());
+if (nd_table[0].used) {
+qemu_check_nic_model(&nd_table[0], TYPE_MSS_EMAC);
+qdev_set_nic_properties(DEVICE(&s->emac), &nd_table[0]);
+}
 }
 
 static void m2sxxx_soc_realize(DeviceState *dev_soc, Error **errp)
@@ -192,6 +201,17 @@ static void m2sxxx_soc_realize(DeviceState *dev_soc, Error 
**errp)
 g_free(bus_name);
 }
 
+dev = DEVICE(&s->emac);
+object_property_set_bool(OBJECT(&s->emac), true, "realized", &err);
+if (err != NULL) {
+error_propagate(errp, err);
+return;
+}
+busdev = SYS_BUS_DEVICE(dev);
+sysbus_mmio_map(busdev, 0, MSF2_EMAC_BASE);
+sysbus_connect_irq(busdev, 0,
+   qdev_get_gpio_in(armv7m, emac_irq[0]));
+
 /* Below devices are not modelled yet. */
 create_unimplemented_device("i2c_0", 0x40002000, 0x1000);
 create_unimplemented_device("dma", 0x40003000, 0x1000);
@@ -202,7 +222,6 @@ static void m2sxxx_soc_realize(DeviceState *dev_soc, Error 
**errp)
 create_unimplemented_device("can", 0x40015000, 0x1000);
 create_unimplemented_device("rtc", 0x40017000, 0x1000);
 create_unimplemented_device("apb_config", 0x4002, 0x1);
-create_unimplemented_device("emac", 0x40041000, 0x1000);
 create_unimplemented_device("usb", 0x40043000, 0x1000);
 }
 
diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs
index ab22968..d9b4cae 100644
--- a/hw/net/Makefile.objs
+++ b/hw/net/Makefile.objs
@@ -48,3 +48,4 @@ common-obj-$(CONFIG_ROCKER) += rocker/rocker.o 
rocker/rocker_fp.o \
 obj-$(call lnot,$(CONFIG_ROCKER)) += rocker/qmp-norocker.o
 
 common-obj-$(CONFIG_CAN_BUS) += can/
+common-obj-$(CONFIG_MSF2) += mss-emac.o
diff --git a/hw/net/mss-emac.c b/hw/net/mss-emac.c
new file mode 100644
index 000..a9588c0
--- /dev/null
+++ b/hw/net/mss-emac.c
@@ -0,0 +1,544 @@
+/*
+ * QEMU model of the Smartfusion2 Ethernet MAC.
+ *
+ * Copyright (c) 2018 Subbaraya Sundeep .
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/log.h"
+#include "hw/net/mss-emac.h"
+#include "hw/net/mii.h"
+
+#define R_CFG1  (0x0 / 4)
+#define R_CFG2

[Qemu-devel] [[Qemu devel] RFC] hw/net: Add Smartfusion2 emac block

2018-05-26 Thread Subbaraya Sundeep
Modelled Ethernet MAC of Smartfusion2 SoC.
Micrel KSZ8051 PHY is present on Emcraft's SOM kit hence same
PHY is emulated.

Signed-off-by: Subbaraya Sundeep 
---
 hw/arm/msf2-soc.c |  21 +-
 hw/net/Makefile.objs  |   1 +
 hw/net/mss-emac.c | 544 ++
 include/hw/arm/msf2-soc.h |   3 +
 include/hw/net/mss-emac.h |  23 ++
 5 files changed, 591 insertions(+), 1 deletion(-)
 create mode 100644 hw/net/mss-emac.c
 create mode 100644 include/hw/net/mss-emac.h

diff --git a/hw/arm/msf2-soc.c b/hw/arm/msf2-soc.c
index 75c44ad..ed3d0f5 100644
--- a/hw/arm/msf2-soc.c
+++ b/hw/arm/msf2-soc.c
@@ -35,6 +35,7 @@
 
 #define MSF2_TIMER_BASE   0x40004000
 #define MSF2_SYSREG_BASE  0x40038000
+#define MSF2_EMAC_BASE0x40041000
 
 #define ENVM_BASE_ADDRESS 0x6000
 
@@ -55,6 +56,7 @@ static const uint32_t uart_addr[MSF2_NUM_UARTS] = { 
0x4000 , 0x4001 };
 static const int spi_irq[MSF2_NUM_SPIS] = { 2, 3 };
 static const int uart_irq[MSF2_NUM_UARTS] = { 10, 11 };
 static const int timer_irq[MSF2_NUM_TIMERS] = { 14, 15 };
+static const int emac_irq[MSF2_NUM_EMACS] = { 12 };
 
 static void do_sys_reset(void *opaque, int n, int level)
 {
@@ -82,6 +84,13 @@ static void m2sxxx_soc_initfn(Object *obj)
   TYPE_MSS_SPI);
 qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default());
 }
+
+object_initialize(&s->emac, sizeof(s->emac), TYPE_MSS_EMAC);
+qdev_set_parent_bus(DEVICE(&s->emac), sysbus_get_default());
+if (nd_table[0].used) {
+qemu_check_nic_model(&nd_table[0], TYPE_MSS_EMAC);
+qdev_set_nic_properties(DEVICE(&s->emac), &nd_table[0]);
+}
 }
 
 static void m2sxxx_soc_realize(DeviceState *dev_soc, Error **errp)
@@ -192,6 +201,17 @@ static void m2sxxx_soc_realize(DeviceState *dev_soc, Error 
**errp)
 g_free(bus_name);
 }
 
+dev = DEVICE(&s->emac);
+object_property_set_bool(OBJECT(&s->emac), true, "realized", &err);
+if (err != NULL) {
+error_propagate(errp, err);
+return;
+}
+busdev = SYS_BUS_DEVICE(dev);
+sysbus_mmio_map(busdev, 0, MSF2_EMAC_BASE);
+sysbus_connect_irq(busdev, 0,
+   qdev_get_gpio_in(armv7m, emac_irq[0]));
+
 /* Below devices are not modelled yet. */
 create_unimplemented_device("i2c_0", 0x40002000, 0x1000);
 create_unimplemented_device("dma", 0x40003000, 0x1000);
@@ -202,7 +222,6 @@ static void m2sxxx_soc_realize(DeviceState *dev_soc, Error 
**errp)
 create_unimplemented_device("can", 0x40015000, 0x1000);
 create_unimplemented_device("rtc", 0x40017000, 0x1000);
 create_unimplemented_device("apb_config", 0x4002, 0x1);
-create_unimplemented_device("emac", 0x40041000, 0x1000);
 create_unimplemented_device("usb", 0x40043000, 0x1000);
 }
 
diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs
index ab22968..d9b4cae 100644
--- a/hw/net/Makefile.objs
+++ b/hw/net/Makefile.objs
@@ -48,3 +48,4 @@ common-obj-$(CONFIG_ROCKER) += rocker/rocker.o 
rocker/rocker_fp.o \
 obj-$(call lnot,$(CONFIG_ROCKER)) += rocker/qmp-norocker.o
 
 common-obj-$(CONFIG_CAN_BUS) += can/
+common-obj-$(CONFIG_MSF2) += mss-emac.o
diff --git a/hw/net/mss-emac.c b/hw/net/mss-emac.c
new file mode 100644
index 000..a9588c0
--- /dev/null
+++ b/hw/net/mss-emac.c
@@ -0,0 +1,544 @@
+/*
+ * QEMU model of the Smartfusion2 Ethernet MAC.
+ *
+ * Copyright (c) 2018 Subbaraya Sundeep .
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/log.h"
+#include "hw/net/mss-emac.h"
+#include "hw/net/mii.h"
+
+#define R_CFG1  (0x0 / 4)
+#define R_CFG2

[Qemu-devel] [Qemu devel PATCH v2] MAINTAINERS: Add entries for Smartfusion2

2017-11-12 Thread Subbaraya Sundeep
Voluntarily add myself as maintainer for Smartfusion2

Signed-off-by: Subbaraya Sundeep 
Reviewed-by: Alistair Francis 
Reviewed-by: Philippe Mathieu-Daudé 
---
v2:
reframed commit message as per Alistair's comment.
Renamed MSF2 SoC -> SmartFusion2
MSF2 SOM -> Emcraft M2S-FG484
as per Philippe's comments.

 MAINTAINERS | 17 +
 1 file changed, 17 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 0cd4d02..ffd77b4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -564,6 +564,23 @@ M: Alistair Francis 
 S: Maintained
 F: hw/arm/netduino2.c
 
+SmartFusion2
+M: Subbaraya Sundeep 
+S: Maintained
+F: hw/arm/msf2-soc.c
+F: hw/misc/msf2-sysreg.c
+F: hw/timer/mss-timer.c
+F: hw/ssi/mss-spi.c
+F: include/hw/arm/msf2-soc.h
+F: include/hw/misc/msf2-sysreg.h
+F: include/hw/timer/mss-timer.h
+F: include/hw/ssi/mss-spi.h
+
+Emcraft M2S-FG484
+M: Subbaraya Sundeep 
+S: Maintained
+F: hw/arm/msf2-som.c
+
 CRIS Machines
 -
 Axis Dev88
-- 
2.5.0




[Qemu-devel] [Qemu devel PATCH] MAINTAINERS: Add entries for Smartfusion2

2017-11-09 Thread Subbaraya Sundeep
add voluntarily myself as maintainer for Smartfusion2

Signed-off-by: Subbaraya Sundeep 
---
 MAINTAINERS | 17 +
 1 file changed, 17 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 0cd4d02..dae08bd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -564,6 +564,23 @@ M: Alistair Francis 
 S: Maintained
 F: hw/arm/netduino2.c
 
+MSF2 SoC
+M: Subbaraya Sundeep 
+S: Maintained
+F: hw/arm/msf2-soc.c
+F: hw/misc/msf2-sysreg.c
+F: hw/timer/mss-timer.c
+F: hw/ssi/mss-spi.c
+F: include/hw/arm/msf2-soc.h
+F: include/hw/misc/msf2-sysreg.h
+F: include/hw/timer/mss-timer.h
+F: include/hw/ssi/mss-spi.h
+
+MSF2 SOM board
+M: Subbaraya Sundeep 
+S: Maintained
+F: hw/arm/msf2-som.c
+
 CRIS Machines
 -
 Axis Dev88
-- 
2.5.0




[Qemu-devel] [Qemu devel PATCH] msf2: Wire up SYSRESETREQ in SoC for system reset

2017-10-28 Thread Subbaraya Sundeep
Implemented system reset by creating SYSRESETREQ gpio
out from nvic.

Signed-off-by: Subbaraya Sundeep 
---
 hw/arm/msf2-soc.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/hw/arm/msf2-soc.c b/hw/arm/msf2-soc.c
index 6f97fa9..a8ec2cd 100644
--- a/hw/arm/msf2-soc.c
+++ b/hw/arm/msf2-soc.c
@@ -57,6 +57,13 @@ static const int spi_irq[MSF2_NUM_SPIS] = { 2, 3 };
 static const int uart_irq[MSF2_NUM_UARTS] = { 10, 11 };
 static const int timer_irq[MSF2_NUM_TIMERS] = { 14, 15 };
 
+static void do_sys_reset(void *opaque, int n, int level)
+{
+if (level) {
+qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
+}
+}
+
 static void m2sxxx_soc_initfn(Object *obj)
 {
 MSF2State *s = MSF2_SOC(obj);
@@ -125,6 +132,10 @@ static void m2sxxx_soc_realize(DeviceState *dev_soc, Error 
**errp)
 error_append_hint(errp, "m3clk can not be zero\n");
 return;
 }
+
+qdev_connect_gpio_out_named(DEVICE(&s->armv7m.nvic), "SYSRESETREQ", 0,
+qemu_allocate_irq(&do_sys_reset, NULL, 0));
+
 system_clock_scale = NANOSECONDS_PER_SECOND / s->m3clk;
 
 for (i = 0; i < MSF2_NUM_UARTS; i++) {
-- 
2.5.0




[Qemu-devel] [Qemu devel V4 PATCH] msf2: Remove dead code reported by Coverity

2017-10-24 Thread Subbaraya Sundeep
Fixed incorrect frame size mask, validated maximum frame
size in spi_write and removed dead code.

Signed-off-by: Subbaraya Sundeep 
---
v4:
changed %d to %u while logging frame size error.
v3:
Added comment that [31:6] bits are reserved in R_SPI_DFSIZE
register and logged incorrect value too in guest error(suggested
by Darren).
v2:
else if -> else in set_fifodepth
log guest error when frame size is more than 32

 hw/ssi/mss-spi.c | 18 ++
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/hw/ssi/mss-spi.c b/hw/ssi/mss-spi.c
index 5a8e308..d60daba 100644
--- a/hw/ssi/mss-spi.c
+++ b/hw/ssi/mss-spi.c
@@ -76,9 +76,10 @@
 #define C_BIGFIFO(1 << 29)
 #define C_RESET  (1 << 31)
 
-#define FRAMESZ_MASK 0x1F
+#define FRAMESZ_MASK 0x3F
 #define FMCOUNT_MASK 0x0000
 #define FMCOUNT_SHIFT8
+#define FRAMESZ_MAX  32
 
 static void txfifo_reset(MSSSpiState *s)
 {
@@ -104,10 +105,8 @@ static void set_fifodepth(MSSSpiState *s)
 s->fifo_depth = 32;
 } else if (size <= 16) {
 s->fifo_depth = 16;
-} else if (size <= 32) {
-s->fifo_depth = 8;
 } else {
-s->fifo_depth = 4;
+s->fifo_depth = 8;
 }
 }
 
@@ -301,6 +300,17 @@ static void spi_write(void *opaque, hwaddr addr,
 if (s->enabled) {
 break;
 }
+/*
+ * [31:6] bits are reserved bits and for future use.
+ * [5:0] are for frame size. Only [5:0] bits are validated
+ * during write, [31:6] bits are untouched.
+ */
+if ((value & FRAMESZ_MASK) > FRAMESZ_MAX) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: Incorrect size %u provided."
+ "Maximum frame size is %u\n",
+ __func__, value & FRAMESZ_MASK, FRAMESZ_MAX);
+break;
+}
 s->regs[R_SPI_DFSIZE] = value;
 break;
 
-- 
2.5.0




[Qemu-devel] [Qemu devel v3 PATCH] msf2: Remove dead code reported by Coverity

2017-10-22 Thread Subbaraya Sundeep
Fixed incorrect frame size mask, validated maximum frame
size in spi_write and removed dead code.

Signed-off-by: Subbaraya Sundeep 
---
v3:
Added comment that [31:6] bits are reserved in R_SPI_DFSIZE
register and logged incorrect value too in guest error(suggested
by Darren). 
v2:
else if -> else in set_fifodepth
log guest error when frame size is more than 32

 hw/ssi/mss-spi.c | 18 ++
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/hw/ssi/mss-spi.c b/hw/ssi/mss-spi.c
index 5a8e308..e1b6227 100644
--- a/hw/ssi/mss-spi.c
+++ b/hw/ssi/mss-spi.c
@@ -76,9 +76,10 @@
 #define C_BIGFIFO(1 << 29)
 #define C_RESET  (1 << 31)
 
-#define FRAMESZ_MASK 0x1F
+#define FRAMESZ_MASK 0x3F
 #define FMCOUNT_MASK 0x0000
 #define FMCOUNT_SHIFT8
+#define FRAMESZ_MAX  32
 
 static void txfifo_reset(MSSSpiState *s)
 {
@@ -104,10 +105,8 @@ static void set_fifodepth(MSSSpiState *s)
 s->fifo_depth = 32;
 } else if (size <= 16) {
 s->fifo_depth = 16;
-} else if (size <= 32) {
-s->fifo_depth = 8;
 } else {
-s->fifo_depth = 4;
+s->fifo_depth = 8;
 }
 }
 
@@ -301,6 +300,17 @@ static void spi_write(void *opaque, hwaddr addr,
 if (s->enabled) {
 break;
 }
+/*
+ * [31:6] bits are reserved bits and for future use.
+ * [5:0] are for frame size. Only [5:0] bits are validated
+ * during write, [31:6] bits are untouched.
+ */
+if ((value & FRAMESZ_MASK) > FRAMESZ_MAX) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: Incorrect size %d provided."
+ "Maximum frame size is %d\n",
+ __func__, value & FRAMESZ_MASK, FRAMESZ_MAX);
+break;
+}
 s->regs[R_SPI_DFSIZE] = value;
 break;
 
-- 
2.5.0




[Qemu-devel] [Qemu devel v2 PATCH] msf2: Remove dead code reported by Coverity

2017-10-17 Thread Subbaraya Sundeep
Fixed incorrect frame size mask, validated maximum frame
size in spi_write and removed dead code.

Signed-off-by: Subbaraya Sundeep 
---
v2:
else if -> else in set_fifodepth
log guest error when frame size is more than 32

 hw/ssi/mss-spi.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/hw/ssi/mss-spi.c b/hw/ssi/mss-spi.c
index 5a8e308..7fef2c3 100644
--- a/hw/ssi/mss-spi.c
+++ b/hw/ssi/mss-spi.c
@@ -76,9 +76,10 @@
 #define C_BIGFIFO(1 << 29)
 #define C_RESET  (1 << 31)
 
-#define FRAMESZ_MASK 0x1F
+#define FRAMESZ_MASK 0x3F
 #define FMCOUNT_MASK 0x0000
 #define FMCOUNT_SHIFT8
+#define FRAMESZ_MAX  32
 
 static void txfifo_reset(MSSSpiState *s)
 {
@@ -104,10 +105,8 @@ static void set_fifodepth(MSSSpiState *s)
 s->fifo_depth = 32;
 } else if (size <= 16) {
 s->fifo_depth = 16;
-} else if (size <= 32) {
-s->fifo_depth = 8;
 } else {
-s->fifo_depth = 4;
+s->fifo_depth = 8;
 }
 }
 
@@ -301,6 +300,11 @@ static void spi_write(void *opaque, hwaddr addr,
 if (s->enabled) {
 break;
 }
+if ((value & FRAMESZ_MASK) > FRAMESZ_MAX) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: Maximum frame size is %d\n",
+ __func__, FRAMESZ_MAX);
+break;
+}
 s->regs[R_SPI_DFSIZE] = value;
 break;
 
-- 
2.5.0




[Qemu-devel] [Qemu devel PATCH] msf2: Remove dead code reported by Coverity

2017-10-16 Thread Subbaraya Sundeep
Fixed incorrect frame size mask, validated maximum frame
size in spi_write and removed dead code.

Signed-off-by: Subbaraya Sundeep 
---
 hw/ssi/mss-spi.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/hw/ssi/mss-spi.c b/hw/ssi/mss-spi.c
index 5a8e308..1e49cbc 100644
--- a/hw/ssi/mss-spi.c
+++ b/hw/ssi/mss-spi.c
@@ -76,9 +76,10 @@
 #define C_BIGFIFO(1 << 29)
 #define C_RESET  (1 << 31)
 
-#define FRAMESZ_MASK 0x1F
+#define FRAMESZ_MASK 0x3F
 #define FMCOUNT_MASK 0x0000
 #define FMCOUNT_SHIFT8
+#define FRAMESZ_MAX  32
 
 static void txfifo_reset(MSSSpiState *s)
 {
@@ -106,8 +107,6 @@ static void set_fifodepth(MSSSpiState *s)
 s->fifo_depth = 16;
 } else if (size <= 32) {
 s->fifo_depth = 8;
-} else {
-s->fifo_depth = 4;
 }
 }
 
@@ -301,6 +300,9 @@ static void spi_write(void *opaque, hwaddr addr,
 if (s->enabled) {
 break;
 }
+if ((value & FRAMESZ_MASK) > FRAMESZ_MAX) {
+break;
+}
 s->regs[R_SPI_DFSIZE] = value;
 break;
 
-- 
2.5.0




[Qemu-devel] [Qemu devel v10 PATCH 5/5] msf2: Add Emcraft's Smartfusion2 SOM kit

2017-09-18 Thread Subbaraya Sundeep
Emulated Emcraft's Smartfusion2 System On Module starter
kit.

Signed-off-by: Subbaraya Sundeep 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
---
 hw/arm/Makefile.objs |  2 +-
 hw/arm/msf2-som.c| 94 
 2 files changed, 95 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/msf2-som.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index a6cf24f..2794e08 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -19,4 +19,4 @@ obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
 obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o
 obj-$(CONFIG_MPS2) += mps2.o
-obj-$(CONFIG_MSF2) += msf2-soc.o
+obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
diff --git a/hw/arm/msf2-som.c b/hw/arm/msf2-som.c
new file mode 100644
index 000..d395696
--- /dev/null
+++ b/hw/arm/msf2-som.c
@@ -0,0 +1,94 @@
+/*
+ * SmartFusion2 SOM starter kit(from Emcraft) emulation.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/boards.h"
+#include "hw/arm/arm.h"
+#include "exec/address-spaces.h"
+#include "qemu/cutils.h"
+#include "hw/arm/msf2-soc.h"
+
+#define DDR_BASE_ADDRESS  0xA000
+#define DDR_SIZE  (64 * M_BYTE)
+
+#define M2S010_ENVM_SIZE  (256 * K_BYTE)
+#define M2S010_ESRAM_SIZE (64 * K_BYTE)
+
+static void emcraft_sf2_s2s010_init(MachineState *machine)
+{
+DeviceState *dev;
+DeviceState *spi_flash;
+MSF2State *soc;
+DriveInfo *dinfo = drive_get_next(IF_MTD);
+qemu_irq cs_line;
+SSIBus *spi_bus;
+MemoryRegion *sysmem = get_system_memory();
+MemoryRegion *ddr = g_new(MemoryRegion, 1);
+
+memory_region_init_ram(ddr, NULL, "ddr-ram", DDR_SIZE,
+   &error_fatal);
+memory_region_add_subregion(sysmem, DDR_BASE_ADDRESS, ddr);
+
+dev = qdev_create(NULL, TYPE_MSF2_SOC);
+qdev_prop_set_string(dev, "part-name", "M2S010");
+qdev_prop_set_uint64(dev, "eNVM-size", M2S010_ENVM_SIZE);
+qdev_prop_set_uint64(dev, "eSRAM-size", M2S010_ESRAM_SIZE);
+
+/*
+ * CPU clock and peripheral clocks(APB0, APB1)are configurable
+ * in Libero. CPU clock is divided by APB0 and APB1 divisors for
+ * peripherals. Emcraft's SoM kit comes with these settings by default.
+ */
+qdev_prop_set_uint32(dev, "m3clk", 142 * 100);
+qdev_prop_set_uint32(dev, "apb0div", 2);
+qdev_prop_set_uint32(dev, "apb1div", 2);
+
+object_property_set_bool(OBJECT(dev), true, "realized", &error_fatal);
+
+soc = MSF2_SOC(dev);
+
+/* Attach SPI flash to SPI0 controller */
+spi_bus = (SSIBus *)qdev_get_child_bus(dev, "spi0");
+spi_flash = ssi_create_slave_no_init(spi_bus, "s25sl12801");
+qdev_prop_set_uint8(spi_flash, "spansion-cr2nv", 1);
+if (dinfo) {
+qdev_prop_set_drive(spi_flash, "drive", blk_by_legacy_dinfo(dinfo),
+&error_fatal);
+}
+qdev_init_nofail(spi_flash);
+cs_line = qdev_get_gpio_in_named(spi_flash, SSI_GPIO_CS, 0);
+sysbus_connect_irq(SYS_BUS_DEVICE(&soc->spi[0]), 1, cs_line);
+
+armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
+   soc->envm_size);
+}
+
+static void emcraft_sf2_machine_init(MachineClass *mc)
+{
+mc->desc = "SmartFusion2 SOM kit from Emcraft (M2S010)";
+mc->init = emcraft_sf2_s2s010_init;
+}
+
+DEFINE_MACHINE("emcraft-sf2", emcraft_sf2_machine_init)
-- 
2.5.0




[Qemu-devel] [Qemu devel v10 PATCH 3/5] msf2: Add Smartfusion2 SPI controller

2017-09-18 Thread Subbaraya Sundeep
Modelled Microsemi's Smartfusion2 SPI controller.

Signed-off-by: Subbaraya Sundeep 
Reviewed-by: Alistair Francis 
Tested-by: Philippe Mathieu-Daudé 
---
 hw/ssi/Makefile.objs |   1 +
 hw/ssi/mss-spi.c | 404 +++
 include/hw/ssi/mss-spi.h |  58 +++
 3 files changed, 463 insertions(+)
 create mode 100644 hw/ssi/mss-spi.c
 create mode 100644 include/hw/ssi/mss-spi.h

diff --git a/hw/ssi/Makefile.objs b/hw/ssi/Makefile.objs
index 487add2..f5bcc65 100644
--- a/hw/ssi/Makefile.objs
+++ b/hw/ssi/Makefile.objs
@@ -4,6 +4,7 @@ common-obj-$(CONFIG_XILINX_SPI) += xilinx_spi.o
 common-obj-$(CONFIG_XILINX_SPIPS) += xilinx_spips.o
 common-obj-$(CONFIG_ASPEED_SOC) += aspeed_smc.o
 common-obj-$(CONFIG_STM32F2XX_SPI) += stm32f2xx_spi.o
+common-obj-$(CONFIG_MSF2) += mss-spi.o
 
 obj-$(CONFIG_OMAP) += omap_spi.o
 obj-$(CONFIG_IMX) += imx_spi.o
diff --git a/hw/ssi/mss-spi.c b/hw/ssi/mss-spi.c
new file mode 100644
index 000..5a8e308
--- /dev/null
+++ b/hw/ssi/mss-spi.c
@@ -0,0 +1,404 @@
+/*
+ * Block model of SPI controller present in
+ * Microsemi's SmartFusion2 and SmartFusion SoCs.
+ *
+ * Copyright (C) 2017 Subbaraya Sundeep 
+ *
+ * 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/ssi/mss-spi.h"
+#include "qemu/log.h"
+
+#ifndef MSS_SPI_ERR_DEBUG
+#define MSS_SPI_ERR_DEBUG   0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+if (MSS_SPI_ERR_DEBUG >= lvl) { \
+qemu_log("%s: " fmt "\n", __func__, ## args); \
+} \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+#define FIFO_CAPACITY 32
+
+#define R_SPI_CONTROL 0
+#define R_SPI_DFSIZE  1
+#define R_SPI_STATUS  2
+#define R_SPI_INTCLR  3
+#define R_SPI_RX  4
+#define R_SPI_TX  5
+#define R_SPI_CLKGEN  6
+#define R_SPI_SS  7
+#define R_SPI_MIS 8
+#define R_SPI_RIS 9
+
+#define S_TXDONE (1 << 0)
+#define S_RXRDY  (1 << 1)
+#define S_RXCHOVRF   (1 << 2)
+#define S_RXFIFOFUL  (1 << 4)
+#define S_RXFIFOFULNXT   (1 << 5)
+#define S_RXFIFOEMP  (1 << 6)
+#define S_RXFIFOEMPNXT   (1 << 7)
+#define S_TXFIFOFUL  (1 << 8)
+#define S_TXFIFOFULNXT   (1 << 9)
+#define S_TXFIFOEMP  (1 << 10)
+#define S_TXFIFOEMPNXT   (1 << 11)
+#define S_FRAMESTART (1 << 12)
+#define S_SSEL   (1 << 13)
+#define S_ACTIVE (1 << 14)
+
+#define C_ENABLE (1 << 0)
+#define C_MODE   (1 << 1)
+#define C_INTRXDATA  (1 << 4)
+#define C_INTTXDATA  (1 << 5)
+#define C_INTRXOVRFLO(1 << 6)
+#define C_SPS(1 << 26)
+#define C_BIGFIFO(1 << 29)
+#define C_RESET  (1 << 31)
+
+#define FRAMESZ_MASK 0x1F
+#define FMCOUNT_MASK 0x0000
+#define FMCOUNT_SHIFT8
+
+static void txfifo_reset(MSSSpiState *s)
+{
+fifo32_reset(&s->tx_fifo);
+
+s->regs[R_SPI_STATUS] &= ~S_TXFIFOFUL;
+s->regs[R_SPI_STATUS] |= S_TXFIFOEMP;
+}
+
+static void rxfifo_reset(MSSSpiState *s)
+{
+fifo32_reset(&s->rx_fifo);
+
+s->regs[R_SPI_STATUS] &= ~S_RXFIFOFUL;
+s->regs[R_SPI_STATUS] |= S_RXFIFOEMP;
+}
+
+static void set_fifodepth(MSSSpiState *s)
+{
+unsigned int size = s->regs[R_SPI_DFSIZE] & FRAMESZ_MASK;
+
+if (size <= 8) {
+s->fifo_depth = 32;
+} else if (size <= 16) {
+s->fifo_depth = 16;
+} else if (size <= 32) {
+s->fifo_depth = 8;
+} else {
+s->fifo_depth = 4;
+}
+}
+
+static void update_m

[Qemu-devel] [Qemu devel v10 PATCH 1/5] msf2: Add Smartfusion2 System timer

2017-09-18 Thread Subbaraya Sundeep
Modelled System Timer in Microsemi's Smartfusion2 Soc.
Timer has two 32bit down counters and two interrupts.

Signed-off-by: Subbaraya Sundeep 
Reviewed-by: Alistair Francis 
Acked-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
---
 hw/timer/Makefile.objs   |   1 +
 hw/timer/mss-timer.c | 289 +++
 include/hw/timer/mss-timer.h |  64 ++
 3 files changed, 354 insertions(+)
 create mode 100644 hw/timer/mss-timer.c
 create mode 100644 include/hw/timer/mss-timer.h

diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index 15cce1c..8c19eac 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -42,3 +42,4 @@ common-obj-$(CONFIG_ASPEED_SOC) += aspeed_timer.o
 
 common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
 common-obj-$(CONFIG_CMSDK_APB_TIMER) += cmsdk-apb-timer.o
+common-obj-$(CONFIG_MSF2) += mss-timer.o
diff --git a/hw/timer/mss-timer.c b/hw/timer/mss-timer.c
new file mode 100644
index 000..60f1213
--- /dev/null
+++ b/hw/timer/mss-timer.c
@@ -0,0 +1,289 @@
+/*
+ * Block model of System timer present in
+ * Microsemi's SmartFusion2 and SmartFusion SoCs.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep .
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/main-loop.h"
+#include "qemu/log.h"
+#include "hw/timer/mss-timer.h"
+
+#ifndef MSS_TIMER_ERR_DEBUG
+#define MSS_TIMER_ERR_DEBUG  0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+if (MSS_TIMER_ERR_DEBUG >= lvl) { \
+qemu_log("%s: " fmt "\n", __func__, ## args); \
+} \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+#define R_TIM_VAL 0
+#define R_TIM_LOADVAL 1
+#define R_TIM_BGLOADVAL   2
+#define R_TIM_CTRL3
+#define R_TIM_RIS 4
+#define R_TIM_MIS 5
+
+#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)
+#define TIMER_MODE  (1 << 0)
+
+static void timer_update_irq(struct Msf2Timer *st)
+{
+bool isr, ier;
+
+isr = !!(st->regs[R_TIM_RIS] & TIMER_RIS_ACK);
+ier = !!(st->regs[R_TIM_CTRL] & TIMER_CTRL_INTR);
+qemu_set_irq(st->irq, (ier && isr));
+}
+
+static void timer_update(struct Msf2Timer *st)
+{
+uint64_t count;
+
+if (!(st->regs[R_TIM_CTRL] & TIMER_CTRL_ENBL)) {
+ptimer_stop(st->ptimer);
+return;
+}
+
+count = st->regs[R_TIM_LOADVAL];
+ptimer_set_limit(st->ptimer, count, 1);
+ptimer_run(st->ptimer, 1);
+}
+
+static uint64_t
+timer_read(void *opaque, hwaddr offset, unsigned int size)
+{
+MSSTimerState *t = opaque;
+hwaddr addr;
+struct Msf2Timer *st;
+uint32_t ret = 0;
+int timer = 0;
+int isr;
+int ier;
+
+addr = offset >> 2;
+/*
+ * Two independent timers has same base address.
+ * Based on address passed figure out which timer is being used.
+ */
+if ((addr >= R_TIM1_MAX) && (addr < NUM_TIMERS * R_TIM1_MAX)) {
+timer = 1;
+addr -= R_TIM1_MAX;
+}
+
+st = &t->timers[timer];
+
+switch (addr) {
+case R_TIM_VAL:
+ret = ptimer_get_count(st->ptimer);
+break;
+
+case R_TIM_MIS:
+isr = !!(st->regs[R_TIM_RIS] & TIMER_RIS_ACK);
+ier = !!(st->regs[R_TIM_CTRL] & TIMER_CTRL_INTR);
+ret = ier & isr;
+break;
+
+default:
+if (addr < R_TIM1_MAX) {
+ret = st->regs[addr];
+} else {
+qemu_log_mask(LOG_GUEST_ERROR,
+TYPE_MSS_TIMER": 64-bit mode not supported\n");
+return ret;
+  

[Qemu-devel] [Qemu devel v10 PATCH 4/5] msf2: Add Smartfusion2 SoC

2017-09-18 Thread Subbaraya Sundeep
Smartfusion2 SoC has hardened Microcontroller subsystem
and flash based FPGA fabric. This patch adds support for
Microcontroller subsystem in the SoC.

Signed-off-by: Subbaraya Sundeep 
Reviewed-by: Alistair Francis 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
---
 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/msf2-soc.c   | 232 
 include/hw/arm/msf2-soc.h   |  66 
 4 files changed, 300 insertions(+)
 create mode 100644 hw/arm/msf2-soc.c
 create mode 100644 include/hw/arm/msf2-soc.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index bbdd3c1..5059d13 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -129,3 +129,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 5ee6f7d..a6cf24f 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -19,3 +19,4 @@ obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
 obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o
 obj-$(CONFIG_MPS2) += mps2.o
+obj-$(CONFIG_MSF2) += msf2-soc.o
diff --git a/hw/arm/msf2-soc.c b/hw/arm/msf2-soc.c
new file mode 100644
index 000..313da5d
--- /dev/null
+++ b/hw/arm/msf2-soc.c
@@ -0,0 +1,232 @@
+/*
+ * SmartFusion2 SoC emulation.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep 
+ *
+ * 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/char/serial.h"
+#include "hw/boards.h"
+#include "sysemu/block-backend.h"
+#include "qemu/cutils.h"
+#include "hw/arm/msf2-soc.h"
+#include "hw/misc/unimp.h"
+
+#define MSF2_TIMER_BASE   0x40004000
+#define MSF2_SYSREG_BASE  0x40038000
+
+#define ENVM_BASE_ADDRESS 0x6000
+
+#define SRAM_BASE_ADDRESS 0x2000
+
+#define MSF2_ENVM_MAX_SIZE(512 * K_BYTE)
+
+/*
+ * eSRAM max size is 80k without SECDED(Single error correction and
+ * dual error detection) feature and 64k with SECDED.
+ * We do not support SECDED now.
+ */
+#define MSF2_ESRAM_MAX_SIZE   (80 * K_BYTE)
+
+static const uint32_t spi_addr[MSF2_NUM_SPIS] = { 0x40001000 , 0x40011000 };
+static const uint32_t uart_addr[MSF2_NUM_UARTS] = { 0x4000 , 0x4001 };
+
+static const int spi_irq[MSF2_NUM_SPIS] = { 2, 3 };
+static const int uart_irq[MSF2_NUM_UARTS] = { 10, 11 };
+static const int timer_irq[MSF2_NUM_TIMERS] = { 14, 15 };
+
+static void m2sxxx_soc_initfn(Object *obj)
+{
+MSF2State *s = MSF2_SOC(obj);
+int i;
+
+object_initialize(&s->armv7m, sizeof(s->armv7m), TYPE_ARMV7M);
+qdev_set_parent_bus(DEVICE(&s->armv7m), sysbus_get_default());
+
+object_initialize(&s->sysreg, sizeof(s->sysreg), TYPE_MSF2_SYSREG);
+qdev_set_parent_bus(DEVICE(&s->sysreg), sysbus_get_default());
+
+object_initialize(&s->timer, sizeof(s->timer), TYPE_MSS_TIMER);
+qdev_set_parent_bus(DEVICE(&s->timer), sysbus_get_default());
+
+for (i = 0; i < MSF2_NUM_SPIS; i++) {
+object_initialize(&s->spi[i], sizeof(s->spi[i]),
+  TYPE_MSS_SPI);
+qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default());
+}
+}
+
+static void m2sxxx_soc_realize(DeviceState *dev_soc, Error **errp)
+{
+MSF2State *s = MSF2_SOC(dev_soc);
+DeviceState *dev, *armv7m;
+SysBusDevice *busdev;
+Error *err = NULL;
+int i;
+
+MemoryRegion *system_memory = get_system_memory();
+MemoryRegion *nvm = g_new(MemoryRegion, 1);
+MemoryRegion *nvm_alias = g_new(Me

[Qemu-devel] [Qemu devel v10 PATCH 0/5] Add support for Smartfusion2 SoC

2017-09-18 Thread Subbaraya Sundeep
Hi Qemu-devel,

I am trying to add Smartfusion2 SoC.
SoC is from Microsemi and System on Module(SOM)
board is from Emcraft systems. Smartfusion2 has hardened
Microcontroller(Cortex-M3)based Sub System and FPGA fabric.
At the moment only system timer, sysreg and SPI
controller are modelled.

Testing:
./arm-softmmu/qemu-system-arm -M emcraft-sf2 -serial mon:stdio \
-kernel u-boot.bin -display none -drive file=spi.bin,if=mtd,format=raw

Binaries u-boot.bin and spi.bin are at:
https://github.com/Subbaraya-Sundeep/qemu-test-binaries.git

U-boot is from Emcraft with modified
- SPI driver not to use PDMA.
- ugly hack to pass dtb to kernel in r1.
@
https://github.com/Subbaraya-Sundeep/emcraft-uboot-sf2.git

Linux is 4.5 linux with Smartfusion2 SoC dts and clocksource
driver added by myself @
https://github.com/Subbaraya-Sundeep/linux.git

v10:
Added msf2_sysreg_realize in msf2-sysreg.c
modified unimplemented devices names:
pdma->dma and hpdma->hs-dma
used uint8_t for apb divisors properties
simplified msf2_divbits() using ctz32()

v9:
used trace instead of DB_PRINT in msf2-sysreg.c
used LOG_UNIMP for non guest errors in msf2-sysreg.c
added unimplemented devices in msf2-soc.c
removed .alias suffix in alias memory region name for eNVM
removed mc->ignore_memory_transaction_failures in msf2-som.c

v8:
memory_region_init_ram to memory_region_init_rom in soc
%s/emcraft_sf2_init/emcraft_sf2_s2s010_init/g in som
Added mc->ignore_memory_transaction_failures = true in som
as per latest commit.
Code simplifications as suggested by Alistair in sysreg and ssi.

v7:
Removed vmstate_register_ram_global as per latest commit
Moved header files to C which are local to C source files
Removed abort() from msf2-sysreg.c
Added VMStateDescription in mss-timer.c

v6:
Moved some defines from header files to source files
Added properties m3clk, apb0div, apb0div1 properties
to soc.
Added properties apb0divisor, apb1divisor to sysreg
Update system_clock_source in msf2-soc.c
Changed machine name smartfusion2-som->emcraft-sf2

v5
As per Philippe comments:
Added abort in Sysreg if guest tries to remap memory
other than default mapping.
Use of CONFIG_MSF2 in Makefile for soc.c
Fixed incorrect logic in timer model.
Renamed msf2-timer.c -> mss-timer.c
msf2-spi.c -> mss-spi.c also type names
Renamed function msf2_init->emcraft_sf2_init in msf2-som.c
Added part-name,eNVM-size,eSRAM-size,pclk0 and pclk1
properties to soc.
Pass soc part-name,memory size and clock rate properties from som.
v4:
Fixed build failure by using PRIx macros.
v3:
Added SoC file and board file as per Alistair comments.
v2:
Added SPI controller so that u-boot loads kernel from spi flash.
v1:
Initial patch set with timer and sysreg

Thanks,
Sundeep


Subbaraya Sundeep (5):
  msf2: Add Smartfusion2 System timer
  msf2: Microsemi Smartfusion2 System Register block
  msf2: Add Smartfusion2 SPI controller
  msf2: Add Smartfusion2 SoC
  msf2: Add Emcraft's Smartfusion2 SOM kit

 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/msf2-soc.c   | 232 +++
 hw/arm/msf2-som.c   |  94 ++
 hw/misc/Makefile.objs   |   1 +
 hw/misc/msf2-sysreg.c   | 160 
 hw/misc/trace-events|   5 +
 hw/ssi/Makefile.objs|   1 +
 hw/ssi/mss-spi.c| 404 
 hw/timer/Makefile.objs  |   1 +
 hw/timer/mss-timer.c| 289 
 include/hw/arm/msf2-soc.h   |  66 +++
 include/hw/misc/msf2-sysreg.h   |  77 
 include/hw/ssi/mss-spi.h|  58 ++
 include/hw/timer/mss-timer.h|  64 +++
 15 files changed, 1454 insertions(+)
 create mode 100644 hw/arm/msf2-soc.c
 create mode 100644 hw/arm/msf2-som.c
 create mode 100644 hw/misc/msf2-sysreg.c
 create mode 100644 hw/ssi/mss-spi.c
 create mode 100644 hw/timer/mss-timer.c
 create mode 100644 include/hw/arm/msf2-soc.h
 create mode 100644 include/hw/misc/msf2-sysreg.h
 create mode 100644 include/hw/ssi/mss-spi.h
 create mode 100644 include/hw/timer/mss-timer.h

-- 
2.5.0




[Qemu-devel] [Qemu devel v10 PATCH 2/5] msf2: Microsemi Smartfusion2 System Register block

2017-09-18 Thread Subbaraya Sundeep
Added Sytem register block of Smartfusion2.
This block has PLL registers which are accessed by guest.

Signed-off-by: Subbaraya Sundeep 
Reviewed-by: Alistair Francis 
Acked-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
---
 hw/misc/Makefile.objs |   1 +
 hw/misc/msf2-sysreg.c | 160 ++
 hw/misc/trace-events  |   5 ++
 include/hw/misc/msf2-sysreg.h |  77 
 4 files changed, 243 insertions(+)
 create mode 100644 hw/misc/msf2-sysreg.c
 create mode 100644 include/hw/misc/msf2-sysreg.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 29fb922..e8f0a02 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -59,3 +59,4 @@ obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
 obj-$(CONFIG_AUX) += auxbus.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o
 obj-y += mmio_interface.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 000..6eb5011
--- /dev/null
+++ b/hw/misc/msf2-sysreg.c
@@ -0,0 +1,160 @@
+/*
+ * System Register block model of Microsemi SmartFusion2.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep 
+ *
+ * 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 "qapi/error.h"
+#include "qemu/log.h"
+#include "hw/misc/msf2-sysreg.h"
+#include "qemu/error-report.h"
+#include "trace.h"
+
+static inline int msf2_divbits(uint32_t div)
+{
+int r = ctz32(div);
+
+return (div < 8) ? r : r + 1;
+}
+
+static void msf2_sysreg_reset(DeviceState *d)
+{
+MSF2SysregState *s = MSF2_SYSREG(d);
+
+s->regs[MSSDDR_PLL_STATUS_LOW_CR] = 0x021A2358;
+s->regs[MSSDDR_PLL_STATUS] = 0x3;
+s->regs[MSSDDR_FACC1_CR] = msf2_divbits(s->apb0div) << 5 |
+   msf2_divbits(s->apb1div) << 2;
+}
+
+static uint64_t msf2_sysreg_read(void *opaque, hwaddr offset,
+unsigned size)
+{
+MSF2SysregState *s = opaque;
+uint32_t ret = 0;
+
+offset >>= 2;
+if (offset < ARRAY_SIZE(s->regs)) {
+ret = s->regs[offset];
+trace_msf2_sysreg_read(offset << 2, ret);
+} else {
+qemu_log_mask(LOG_GUEST_ERROR,
+"%s: Bad offset 0x%08" HWADDR_PRIx "\n", __func__,
+offset << 2);
+}
+
+return ret;
+}
+
+static void msf2_sysreg_write(void *opaque, hwaddr offset,
+  uint64_t val, unsigned size)
+{
+MSF2SysregState *s = opaque;
+uint32_t newval = val;
+
+offset >>= 2;
+
+switch (offset) {
+case MSSDDR_PLL_STATUS:
+trace_msf2_sysreg_write_pll_status();
+break;
+
+case ESRAM_CR:
+case DDR_CR:
+case ENVM_REMAP_BASE_CR:
+if (newval != s->regs[offset]) {
+qemu_log_mask(LOG_UNIMP,
+   TYPE_MSF2_SYSREG": remapping not supported\n");
+}
+break;
+
+default:
+if (offset < ARRAY_SIZE(s->regs)) {
+trace_msf2_sysreg_write(offset << 2, newval, s->regs[offset]);
+s->regs[offset] = newval;
+} else {
+qemu_log_mask(LOG_GUEST_ERROR,
+"%s: Bad offset 0x%08" HWADDR_PRIx "\n", __func__,
+offset << 2);
+}
+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)
+{
+MSF2SysregState *s = MSF2_SYSREG(obj);
+
+memory_region_init_io(&s->iomem, obj, &sysreg_ops, s, TYPE_MSF2_SYSREG,
+  MSF2_SYSREG_MMIO_SIZE);
+sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
+}
+
+static const VMStateDescription vmstate_msf2_sysreg = {
+.name = TYPE_MSF2_SYSREG,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32_ARRAY(regs, MSF2SysregState, MSF2_SYSREG_MMIO_SIZE / 4),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static Property msf2_sysreg_properties[] = {
+/* default divisors in Libero GUI */
+DEFINE_PROP_UINT8("apb0divisor", MSF2SysregState, apb0div, 2),
+DEFINE_PROP_UINT8("apb1divisor", MSF2SysregState, apb1div, 2),
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void msf2_sysreg_realize(DeviceState *dev, Error **errp)
+{
+MSF2Sysreg

[Qemu-devel] [Qemu devel v9 PATCH 3/5] msf2: Add Smartfusion2 SPI controller

2017-09-15 Thread Subbaraya Sundeep
Modelled Microsemi's Smartfusion2 SPI controller.

Signed-off-by: Subbaraya Sundeep 
Reviewed-by: Alistair Francis 
---
 hw/ssi/Makefile.objs |   1 +
 hw/ssi/mss-spi.c | 404 +++
 include/hw/ssi/mss-spi.h |  58 +++
 3 files changed, 463 insertions(+)
 create mode 100644 hw/ssi/mss-spi.c
 create mode 100644 include/hw/ssi/mss-spi.h

diff --git a/hw/ssi/Makefile.objs b/hw/ssi/Makefile.objs
index 487add2..f5bcc65 100644
--- a/hw/ssi/Makefile.objs
+++ b/hw/ssi/Makefile.objs
@@ -4,6 +4,7 @@ common-obj-$(CONFIG_XILINX_SPI) += xilinx_spi.o
 common-obj-$(CONFIG_XILINX_SPIPS) += xilinx_spips.o
 common-obj-$(CONFIG_ASPEED_SOC) += aspeed_smc.o
 common-obj-$(CONFIG_STM32F2XX_SPI) += stm32f2xx_spi.o
+common-obj-$(CONFIG_MSF2) += mss-spi.o
 
 obj-$(CONFIG_OMAP) += omap_spi.o
 obj-$(CONFIG_IMX) += imx_spi.o
diff --git a/hw/ssi/mss-spi.c b/hw/ssi/mss-spi.c
new file mode 100644
index 000..5a8e308
--- /dev/null
+++ b/hw/ssi/mss-spi.c
@@ -0,0 +1,404 @@
+/*
+ * Block model of SPI controller present in
+ * Microsemi's SmartFusion2 and SmartFusion SoCs.
+ *
+ * Copyright (C) 2017 Subbaraya Sundeep 
+ *
+ * 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/ssi/mss-spi.h"
+#include "qemu/log.h"
+
+#ifndef MSS_SPI_ERR_DEBUG
+#define MSS_SPI_ERR_DEBUG   0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+if (MSS_SPI_ERR_DEBUG >= lvl) { \
+qemu_log("%s: " fmt "\n", __func__, ## args); \
+} \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+#define FIFO_CAPACITY 32
+
+#define R_SPI_CONTROL 0
+#define R_SPI_DFSIZE  1
+#define R_SPI_STATUS  2
+#define R_SPI_INTCLR  3
+#define R_SPI_RX  4
+#define R_SPI_TX  5
+#define R_SPI_CLKGEN  6
+#define R_SPI_SS  7
+#define R_SPI_MIS 8
+#define R_SPI_RIS 9
+
+#define S_TXDONE (1 << 0)
+#define S_RXRDY  (1 << 1)
+#define S_RXCHOVRF   (1 << 2)
+#define S_RXFIFOFUL  (1 << 4)
+#define S_RXFIFOFULNXT   (1 << 5)
+#define S_RXFIFOEMP  (1 << 6)
+#define S_RXFIFOEMPNXT   (1 << 7)
+#define S_TXFIFOFUL  (1 << 8)
+#define S_TXFIFOFULNXT   (1 << 9)
+#define S_TXFIFOEMP  (1 << 10)
+#define S_TXFIFOEMPNXT   (1 << 11)
+#define S_FRAMESTART (1 << 12)
+#define S_SSEL   (1 << 13)
+#define S_ACTIVE (1 << 14)
+
+#define C_ENABLE (1 << 0)
+#define C_MODE   (1 << 1)
+#define C_INTRXDATA  (1 << 4)
+#define C_INTTXDATA  (1 << 5)
+#define C_INTRXOVRFLO(1 << 6)
+#define C_SPS(1 << 26)
+#define C_BIGFIFO(1 << 29)
+#define C_RESET  (1 << 31)
+
+#define FRAMESZ_MASK 0x1F
+#define FMCOUNT_MASK 0x0000
+#define FMCOUNT_SHIFT8
+
+static void txfifo_reset(MSSSpiState *s)
+{
+fifo32_reset(&s->tx_fifo);
+
+s->regs[R_SPI_STATUS] &= ~S_TXFIFOFUL;
+s->regs[R_SPI_STATUS] |= S_TXFIFOEMP;
+}
+
+static void rxfifo_reset(MSSSpiState *s)
+{
+fifo32_reset(&s->rx_fifo);
+
+s->regs[R_SPI_STATUS] &= ~S_RXFIFOFUL;
+s->regs[R_SPI_STATUS] |= S_RXFIFOEMP;
+}
+
+static void set_fifodepth(MSSSpiState *s)
+{
+unsigned int size = s->regs[R_SPI_DFSIZE] & FRAMESZ_MASK;
+
+if (size <= 8) {
+s->fifo_depth = 32;
+} else if (size <= 16) {
+s->fifo_depth = 16;
+} else if (size <= 32) {
+s->fifo_depth = 8;
+} else {
+s->fifo_depth = 4;
+}
+}
+
+static void update_mis(MSSSpiState *s)
+{
+uint32_t reg =

[Qemu-devel] [Qemu devel v9 PATCH 1/5] msf2: Add Smartfusion2 System timer

2017-09-15 Thread Subbaraya Sundeep
Modelled System Timer in Microsemi's Smartfusion2 Soc.
Timer has two 32bit down counters and two interrupts.

Signed-off-by: Subbaraya Sundeep 
Reviewed-by: Alistair Francis 
---
 hw/timer/Makefile.objs   |   1 +
 hw/timer/mss-timer.c | 289 +++
 include/hw/timer/mss-timer.h |  64 ++
 3 files changed, 354 insertions(+)
 create mode 100644 hw/timer/mss-timer.c
 create mode 100644 include/hw/timer/mss-timer.h

diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index 15cce1c..8c19eac 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -42,3 +42,4 @@ common-obj-$(CONFIG_ASPEED_SOC) += aspeed_timer.o
 
 common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
 common-obj-$(CONFIG_CMSDK_APB_TIMER) += cmsdk-apb-timer.o
+common-obj-$(CONFIG_MSF2) += mss-timer.o
diff --git a/hw/timer/mss-timer.c b/hw/timer/mss-timer.c
new file mode 100644
index 000..60f1213
--- /dev/null
+++ b/hw/timer/mss-timer.c
@@ -0,0 +1,289 @@
+/*
+ * Block model of System timer present in
+ * Microsemi's SmartFusion2 and SmartFusion SoCs.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep .
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/main-loop.h"
+#include "qemu/log.h"
+#include "hw/timer/mss-timer.h"
+
+#ifndef MSS_TIMER_ERR_DEBUG
+#define MSS_TIMER_ERR_DEBUG  0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+if (MSS_TIMER_ERR_DEBUG >= lvl) { \
+qemu_log("%s: " fmt "\n", __func__, ## args); \
+} \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+#define R_TIM_VAL 0
+#define R_TIM_LOADVAL 1
+#define R_TIM_BGLOADVAL   2
+#define R_TIM_CTRL3
+#define R_TIM_RIS 4
+#define R_TIM_MIS 5
+
+#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)
+#define TIMER_MODE  (1 << 0)
+
+static void timer_update_irq(struct Msf2Timer *st)
+{
+bool isr, ier;
+
+isr = !!(st->regs[R_TIM_RIS] & TIMER_RIS_ACK);
+ier = !!(st->regs[R_TIM_CTRL] & TIMER_CTRL_INTR);
+qemu_set_irq(st->irq, (ier && isr));
+}
+
+static void timer_update(struct Msf2Timer *st)
+{
+uint64_t count;
+
+if (!(st->regs[R_TIM_CTRL] & TIMER_CTRL_ENBL)) {
+ptimer_stop(st->ptimer);
+return;
+}
+
+count = st->regs[R_TIM_LOADVAL];
+ptimer_set_limit(st->ptimer, count, 1);
+ptimer_run(st->ptimer, 1);
+}
+
+static uint64_t
+timer_read(void *opaque, hwaddr offset, unsigned int size)
+{
+MSSTimerState *t = opaque;
+hwaddr addr;
+struct Msf2Timer *st;
+uint32_t ret = 0;
+int timer = 0;
+int isr;
+int ier;
+
+addr = offset >> 2;
+/*
+ * Two independent timers has same base address.
+ * Based on address passed figure out which timer is being used.
+ */
+if ((addr >= R_TIM1_MAX) && (addr < NUM_TIMERS * R_TIM1_MAX)) {
+timer = 1;
+addr -= R_TIM1_MAX;
+}
+
+st = &t->timers[timer];
+
+switch (addr) {
+case R_TIM_VAL:
+ret = ptimer_get_count(st->ptimer);
+break;
+
+case R_TIM_MIS:
+isr = !!(st->regs[R_TIM_RIS] & TIMER_RIS_ACK);
+ier = !!(st->regs[R_TIM_CTRL] & TIMER_CTRL_INTR);
+ret = ier & isr;
+break;
+
+default:
+if (addr < R_TIM1_MAX) {
+ret = st->regs[addr];
+} else {
+qemu_log_mask(LOG_GUEST_ERROR,
+TYPE_MSS_TIMER": 64-bit mode not supported\n");
+return ret;
+}
+break;
+}
+
+DB_PRINT("timer=%d 

[Qemu-devel] [Qemu devel v9 PATCH 5/5] msf2: Add Emcraft's Smartfusion2 SOM kit

2017-09-15 Thread Subbaraya Sundeep
Emulated Emcraft's Smartfusion2 System On Module starter
kit.

Signed-off-by: Subbaraya Sundeep 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/arm/Makefile.objs |  2 +-
 hw/arm/msf2-som.c| 94 
 2 files changed, 95 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/msf2-som.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index df36a03..e81a7dc 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -19,4 +19,4 @@ obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
 obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o
 obj-$(CONFIG_MPS2) += mps2.o
-obj-$(CONFIG_MSF2) += msf2-soc.o
+obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
diff --git a/hw/arm/msf2-som.c b/hw/arm/msf2-som.c
new file mode 100644
index 000..d395696
--- /dev/null
+++ b/hw/arm/msf2-som.c
@@ -0,0 +1,94 @@
+/*
+ * SmartFusion2 SOM starter kit(from Emcraft) emulation.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/boards.h"
+#include "hw/arm/arm.h"
+#include "exec/address-spaces.h"
+#include "qemu/cutils.h"
+#include "hw/arm/msf2-soc.h"
+
+#define DDR_BASE_ADDRESS  0xA000
+#define DDR_SIZE  (64 * M_BYTE)
+
+#define M2S010_ENVM_SIZE  (256 * K_BYTE)
+#define M2S010_ESRAM_SIZE (64 * K_BYTE)
+
+static void emcraft_sf2_s2s010_init(MachineState *machine)
+{
+DeviceState *dev;
+DeviceState *spi_flash;
+MSF2State *soc;
+DriveInfo *dinfo = drive_get_next(IF_MTD);
+qemu_irq cs_line;
+SSIBus *spi_bus;
+MemoryRegion *sysmem = get_system_memory();
+MemoryRegion *ddr = g_new(MemoryRegion, 1);
+
+memory_region_init_ram(ddr, NULL, "ddr-ram", DDR_SIZE,
+   &error_fatal);
+memory_region_add_subregion(sysmem, DDR_BASE_ADDRESS, ddr);
+
+dev = qdev_create(NULL, TYPE_MSF2_SOC);
+qdev_prop_set_string(dev, "part-name", "M2S010");
+qdev_prop_set_uint64(dev, "eNVM-size", M2S010_ENVM_SIZE);
+qdev_prop_set_uint64(dev, "eSRAM-size", M2S010_ESRAM_SIZE);
+
+/*
+ * CPU clock and peripheral clocks(APB0, APB1)are configurable
+ * in Libero. CPU clock is divided by APB0 and APB1 divisors for
+ * peripherals. Emcraft's SoM kit comes with these settings by default.
+ */
+qdev_prop_set_uint32(dev, "m3clk", 142 * 100);
+qdev_prop_set_uint32(dev, "apb0div", 2);
+qdev_prop_set_uint32(dev, "apb1div", 2);
+
+object_property_set_bool(OBJECT(dev), true, "realized", &error_fatal);
+
+soc = MSF2_SOC(dev);
+
+/* Attach SPI flash to SPI0 controller */
+spi_bus = (SSIBus *)qdev_get_child_bus(dev, "spi0");
+spi_flash = ssi_create_slave_no_init(spi_bus, "s25sl12801");
+qdev_prop_set_uint8(spi_flash, "spansion-cr2nv", 1);
+if (dinfo) {
+qdev_prop_set_drive(spi_flash, "drive", blk_by_legacy_dinfo(dinfo),
+&error_fatal);
+}
+qdev_init_nofail(spi_flash);
+cs_line = qdev_get_gpio_in_named(spi_flash, SSI_GPIO_CS, 0);
+sysbus_connect_irq(SYS_BUS_DEVICE(&soc->spi[0]), 1, cs_line);
+
+armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
+   soc->envm_size);
+}
+
+static void emcraft_sf2_machine_init(MachineClass *mc)
+{
+mc->desc = "SmartFusion2 SOM kit from Emcraft (M2S010)";
+mc->init = emcraft_sf2_s2s010_init;
+}
+
+DEFINE_MACHINE("emcraft-sf2", emcraft_sf2_machine_init)
-- 
2.5.0




[Qemu-devel] [Qemu devel v9 PATCH 0/5] Add support for Smartfusion2 SoC

2017-09-15 Thread Subbaraya Sundeep
Hi Qemu-devel,

I am trying to add Smartfusion2 SoC.
SoC is from Microsemi and System on Module(SOM)
board is from Emcraft systems. Smartfusion2 has hardened
Microcontroller(Cortex-M3)based Sub System and FPGA fabric.
At the moment only system timer, sysreg and SPI
controller are modelled.

Tested-by: Philippe Mathieu-Daudé 

Testing:
./arm-softmmu/qemu-system-arm -M emcraft-sf2 -serial mon:stdio \
-kernel u-boot.bin -display none -drive file=spi.bin,if=mtd,format=raw

Binaries u-boot.bin and spi.bin are at:
https://github.com/Subbaraya-Sundeep/qemu-test-binaries.git

U-boot is from Emcraft with modified
- SPI driver not to use PDMA.
- ugly hack to pass dtb to kernel in r1.
@
https://github.com/Subbaraya-Sundeep/emcraft-uboot-sf2.git

Linux is 4.5 linux with Smartfusion2 SoC dts and clocksource
driver added by myself @
https://github.com/Subbaraya-Sundeep/linux.git

v9:
used trace instead of DB_PRINT in msf2-sysreg.c
used LOG_UNIMP for non guest errors in msf2-sysreg.c
added unimplemented devices in msf2-soc.c
removed .alias suffix in alias memory region name for eNVM

v8:
memory_region_init_ram to memory_region_init_rom in soc
%s/emcraft_sf2_init/emcraft_sf2_s2s010_init/g in som
Added mc->ignore_memory_transaction_failures = true in som
as per latest commit.
Code simplifications as suggested by Alistair in sysreg and ssi.

v7:
Removed vmstate_register_ram_global as per latest commit
Moved header files to C which are local to C source files
Removed abort() from msf2-sysreg.c
Added VMStateDescription in mss-timer.c

v6:
Moved some defines from header files to source files
Added properties m3clk, apb0div, apb0div1 properties
to soc.
Added properties apb0divisor, apb1divisor to sysreg
Update system_clock_source in msf2-soc.c
Changed machine name smartfusion2-som->emcraft-sf2

v5
As per Philippe comments:
Added abort in Sysreg if guest tries to remap memory
other than default mapping.
Use of CONFIG_MSF2 in Makefile for soc.c
Fixed incorrect logic in timer model.
Renamed msf2-timer.c -> mss-timer.c
msf2-spi.c -> mss-spi.c also type names
Renamed function msf2_init->emcraft_sf2_init in msf2-som.c
Added part-name,eNVM-size,eSRAM-size,pclk0 and pclk1
properties to soc.
Pass soc part-name,memory size and clock rate properties from som.
v4:
Fixed build failure by using PRIx macros.
v3:
Added SoC file and board file as per Alistair comments.
v2:
Added SPI controller so that u-boot loads kernel from spi flash.
v1:
Initial patch set with timer and sysreg

Thanks,
Sundeep


Subbaraya Sundeep (5):
  msf2: Add Smartfusion2 System timer
  msf2: Microsemi Smartfusion2 System Register block
  msf2: Add Smartfusion2 SPI controller
  msf2: Add Smartfusion2 SoC
  msf2: Add Emcraft's Smartfusion2 SOM kit

 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/msf2-soc.c   | 232 +++
 hw/arm/msf2-som.c   |  94 ++
 hw/misc/Makefile.objs   |   1 +
 hw/misc/msf2-sysreg.c   | 168 +
 hw/misc/trace-events|   5 +
 hw/ssi/Makefile.objs|   1 +
 hw/ssi/mss-spi.c| 404 
 hw/timer/Makefile.objs  |   1 +
 hw/timer/mss-timer.c| 289 
 include/hw/arm/msf2-soc.h   |  66 +++
 include/hw/misc/msf2-sysreg.h   |  77 
 include/hw/ssi/mss-spi.h|  58 ++
 include/hw/timer/mss-timer.h|  64 +++
 15 files changed, 1462 insertions(+)
 create mode 100644 hw/arm/msf2-soc.c
 create mode 100644 hw/arm/msf2-som.c
 create mode 100644 hw/misc/msf2-sysreg.c
 create mode 100644 hw/ssi/mss-spi.c
 create mode 100644 hw/timer/mss-timer.c
 create mode 100644 include/hw/arm/msf2-soc.h
 create mode 100644 include/hw/misc/msf2-sysreg.h
 create mode 100644 include/hw/ssi/mss-spi.h
 create mode 100644 include/hw/timer/mss-timer.h

-- 
2.5.0




[Qemu-devel] [Qemu devel v9 PATCH 4/5] msf2: Add Smartfusion2 SoC

2017-09-15 Thread Subbaraya Sundeep
Smartfusion2 SoC has hardened Microcontroller subsystem
and flash based FPGA fabric. This patch adds support for
Microcontroller subsystem in the SoC.

Signed-off-by: Subbaraya Sundeep 
Reviewed-by: Alistair Francis 
---
 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/msf2-soc.c   | 232 
 include/hw/arm/msf2-soc.h   |  66 
 4 files changed, 300 insertions(+)
 create mode 100644 hw/arm/msf2-soc.c
 create mode 100644 include/hw/arm/msf2-soc.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index bbdd3c1..5059d13 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -129,3 +129,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 a2e56ec..df36a03 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -19,3 +19,4 @@ obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
 obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o
 obj-$(CONFIG_MPS2) += mps2.o
+obj-$(CONFIG_MSF2) += msf2-soc.o
diff --git a/hw/arm/msf2-soc.c b/hw/arm/msf2-soc.c
new file mode 100644
index 000..5c0a2ea
--- /dev/null
+++ b/hw/arm/msf2-soc.c
@@ -0,0 +1,232 @@
+/*
+ * SmartFusion2 SoC emulation.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep 
+ *
+ * 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/char/serial.h"
+#include "hw/boards.h"
+#include "sysemu/block-backend.h"
+#include "qemu/cutils.h"
+#include "hw/arm/msf2-soc.h"
+#include "hw/misc/unimp.h"
+
+#define MSF2_TIMER_BASE   0x40004000
+#define MSF2_SYSREG_BASE  0x40038000
+
+#define ENVM_BASE_ADDRESS 0x6000
+
+#define SRAM_BASE_ADDRESS 0x2000
+
+#define MSF2_ENVM_MAX_SIZE(512 * K_BYTE)
+
+/*
+ * eSRAM max size is 80k without SECDED(Single error correction and
+ * dual error detection) feature and 64k with SECDED.
+ * We do not support SECDED now.
+ */
+#define MSF2_ESRAM_MAX_SIZE   (80 * K_BYTE)
+
+static const uint32_t spi_addr[MSF2_NUM_SPIS] = { 0x40001000 , 0x40011000 };
+static const uint32_t uart_addr[MSF2_NUM_UARTS] = { 0x4000 , 0x4001 };
+
+static const int spi_irq[MSF2_NUM_SPIS] = { 2, 3 };
+static const int uart_irq[MSF2_NUM_UARTS] = { 10, 11 };
+static const int timer_irq[MSF2_NUM_TIMERS] = { 14, 15 };
+
+static void m2sxxx_soc_initfn(Object *obj)
+{
+MSF2State *s = MSF2_SOC(obj);
+int i;
+
+object_initialize(&s->armv7m, sizeof(s->armv7m), TYPE_ARMV7M);
+qdev_set_parent_bus(DEVICE(&s->armv7m), sysbus_get_default());
+
+object_initialize(&s->sysreg, sizeof(s->sysreg), TYPE_MSF2_SYSREG);
+qdev_set_parent_bus(DEVICE(&s->sysreg), sysbus_get_default());
+
+object_initialize(&s->timer, sizeof(s->timer), TYPE_MSS_TIMER);
+qdev_set_parent_bus(DEVICE(&s->timer), sysbus_get_default());
+
+for (i = 0; i < MSF2_NUM_SPIS; i++) {
+object_initialize(&s->spi[i], sizeof(s->spi[i]),
+  TYPE_MSS_SPI);
+qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default());
+}
+}
+
+static void m2sxxx_soc_realize(DeviceState *dev_soc, Error **errp)
+{
+MSF2State *s = MSF2_SOC(dev_soc);
+DeviceState *dev, *armv7m;
+SysBusDevice *busdev;
+Error *err = NULL;
+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);
+
+   

[Qemu-devel] [Qemu devel v9 PATCH 2/5] msf2: Microsemi Smartfusion2 System Register block

2017-09-15 Thread Subbaraya Sundeep
Added Sytem register block of Smartfusion2.
This block has PLL registers which are accessed by guest.

Signed-off-by: Subbaraya Sundeep 
Reviewed-by: Alistair Francis 
---
 hw/misc/Makefile.objs |   1 +
 hw/misc/msf2-sysreg.c | 168 ++
 hw/misc/trace-events  |   5 ++
 include/hw/misc/msf2-sysreg.h |  77 +++
 4 files changed, 251 insertions(+)
 create mode 100644 hw/misc/msf2-sysreg.c
 create mode 100644 include/hw/misc/msf2-sysreg.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 29fb922..e8f0a02 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -59,3 +59,4 @@ obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
 obj-$(CONFIG_AUX) += auxbus.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o
 obj-y += mmio_interface.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 000..dc3597b
--- /dev/null
+++ b/hw/misc/msf2-sysreg.c
@@ -0,0 +1,168 @@
+/*
+ * System Register block model of Microsemi SmartFusion2.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep 
+ *
+ * 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 "qemu/log.h"
+#include "hw/misc/msf2-sysreg.h"
+#include "trace.h"
+
+static inline int msf2_divbits(uint32_t div)
+{
+int ret = 0;
+
+switch (div) {
+case 1:
+ret = 0;
+break;
+case 2:
+ret = 1;
+break;
+case 4:
+ret = 2;
+break;
+case 8:
+ret = 4;
+break;
+case 16:
+ret = 5;
+break;
+case 32:
+ret = 6;
+break;
+default:
+break;
+}
+
+return ret;
+}
+
+static void msf2_sysreg_reset(DeviceState *d)
+{
+MSF2SysregState *s = MSF2_SYSREG(d);
+
+s->regs[MSSDDR_PLL_STATUS_LOW_CR] = 0x021A2358;
+s->regs[MSSDDR_PLL_STATUS] = 0x3;
+s->regs[MSSDDR_FACC1_CR] = msf2_divbits(s->apb0div) << 5 |
+   msf2_divbits(s->apb1div) << 2;
+}
+
+static uint64_t msf2_sysreg_read(void *opaque, hwaddr offset,
+unsigned size)
+{
+MSF2SysregState *s = opaque;
+uint32_t ret = 0;
+
+offset >>= 2;
+if (offset < ARRAY_SIZE(s->regs)) {
+ret = s->regs[offset];
+trace_msf2_sysreg_read(offset << 2, ret);
+} else {
+qemu_log_mask(LOG_GUEST_ERROR,
+"%s: Bad offset 0x%08" HWADDR_PRIx "\n", __func__,
+offset << 2);
+}
+
+return ret;
+}
+
+static void msf2_sysreg_write(void *opaque, hwaddr offset,
+  uint64_t val, unsigned size)
+{
+MSF2SysregState *s = opaque;
+uint32_t newval = val;
+
+offset >>= 2;
+
+switch (offset) {
+case MSSDDR_PLL_STATUS:
+trace_msf2_sysreg_write_pll_status();
+break;
+
+case ESRAM_CR:
+case DDR_CR:
+case ENVM_REMAP_BASE_CR:
+if (newval != s->regs[offset]) {
+qemu_log_mask(LOG_UNIMP,
+   TYPE_MSF2_SYSREG": remapping not supported\n");
+}
+break;
+
+default:
+if (offset < ARRAY_SIZE(s->regs)) {
+trace_msf2_sysreg_write(offset << 2, newval, s->regs[offset]);
+s->regs[offset] = newval;
+} else {
+qemu_log_mask(LOG_GUEST_ERROR,
+"%s: Bad offset 0x%08" HWADDR_PRIx "\n", __func__,
+offset << 2);
+}
+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)
+{
+MSF2SysregState *s = MSF2_SYSREG(obj);
+
+memory_region_init_io(&s->iomem, obj, &sysreg_ops, s, TYPE_MSF2_SYSREG,
+  MSF2_SYSREG_MMIO_SIZE);
+sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
+}
+
+static const VMStateDescription vmstate_msf2_sysreg = {
+.name = TYPE_MSF2_SYSREG,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32_ARRAY(regs, MSF2SysregState, MSF2_SYSREG_MMIO_SIZE / 4),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static Property msf2_sysreg_properties[] = {
+/* default divisors in Libero GUI */
+DEFINE_PROP_UINT32("apb0divisor", MSF2SysregState, apb0div, 2),
+DEFINE_PROP_UINT32(&q

[Qemu-devel] [Qemu devel v8 PATCH 5/5] msf2: Add Emcraft's Smartfusion2 SOM kit

2017-09-07 Thread Subbaraya Sundeep
Emulated Emcraft's Smartfusion2 System On Module starter
kit.

Signed-off-by: Subbaraya Sundeep 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/arm/Makefile.objs |  2 +-
 hw/arm/msf2-som.c| 95 
 2 files changed, 96 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/msf2-som.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index df36a03..e81a7dc 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -19,4 +19,4 @@ obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
 obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o
 obj-$(CONFIG_MPS2) += mps2.o
-obj-$(CONFIG_MSF2) += msf2-soc.o
+obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
diff --git a/hw/arm/msf2-som.c b/hw/arm/msf2-som.c
new file mode 100644
index 000..bc917db
--- /dev/null
+++ b/hw/arm/msf2-som.c
@@ -0,0 +1,95 @@
+/*
+ * SmartFusion2 SOM starter kit(from Emcraft) emulation.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/boards.h"
+#include "hw/arm/arm.h"
+#include "exec/address-spaces.h"
+#include "qemu/cutils.h"
+#include "hw/arm/msf2-soc.h"
+
+#define DDR_BASE_ADDRESS  0xA000
+#define DDR_SIZE  (64 * M_BYTE)
+
+#define M2S010_ENVM_SIZE  (256 * K_BYTE)
+#define M2S010_ESRAM_SIZE (64 * K_BYTE)
+
+static void emcraft_sf2_s2s010_init(MachineState *machine)
+{
+DeviceState *dev;
+DeviceState *spi_flash;
+MSF2State *soc;
+DriveInfo *dinfo = drive_get_next(IF_MTD);
+qemu_irq cs_line;
+SSIBus *spi_bus;
+MemoryRegion *sysmem = get_system_memory();
+MemoryRegion *ddr = g_new(MemoryRegion, 1);
+
+memory_region_init_ram(ddr, NULL, "ddr-ram", DDR_SIZE,
+   &error_fatal);
+memory_region_add_subregion(sysmem, DDR_BASE_ADDRESS, ddr);
+
+dev = qdev_create(NULL, TYPE_MSF2_SOC);
+qdev_prop_set_string(dev, "part-name", "M2S010");
+qdev_prop_set_uint64(dev, "eNVM-size", M2S010_ENVM_SIZE);
+qdev_prop_set_uint64(dev, "eSRAM-size", M2S010_ESRAM_SIZE);
+
+/*
+ * CPU clock and peripheral clocks(APB0, APB1)are configurable
+ * in Libero. CPU clock is divided by APB0 and APB1 divisors for
+ * peripherals. Emcraft's SoM kit comes with these settings by default.
+ */
+qdev_prop_set_uint32(dev, "m3clk", 142 * 100);
+qdev_prop_set_uint32(dev, "apb0div", 2);
+qdev_prop_set_uint32(dev, "apb1div", 2);
+
+object_property_set_bool(OBJECT(dev), true, "realized", &error_fatal);
+
+soc = MSF2_SOC(dev);
+
+/* Attach SPI flash to SPI0 controller */
+spi_bus = (SSIBus *)qdev_get_child_bus(dev, "spi0");
+spi_flash = ssi_create_slave_no_init(spi_bus, "s25sl12801");
+qdev_prop_set_uint8(spi_flash, "spansion-cr2nv", 1);
+if (dinfo) {
+qdev_prop_set_drive(spi_flash, "drive", blk_by_legacy_dinfo(dinfo),
+&error_fatal);
+}
+qdev_init_nofail(spi_flash);
+cs_line = qdev_get_gpio_in_named(spi_flash, SSI_GPIO_CS, 0);
+sysbus_connect_irq(SYS_BUS_DEVICE(&soc->spi[0]), 1, cs_line);
+
+armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
+   soc->envm_size);
+}
+
+static void emcraft_sf2_machine_init(MachineClass *mc)
+{
+mc->desc = "SmartFusion2 SOM kit from Emcraft (M2S010)";
+mc->init = emcraft_sf2_s2s010_init;
+mc->ignore_memory_transaction_failures = true;
+}
+
+DEFINE_MACHINE("emcraft-sf2", emcraft_sf2_machine_init)
-- 
2.5.0




[Qemu-devel] [Qemu devel v8 PATCH 4/5] msf2: Add Smartfusion2 SoC

2017-09-07 Thread Subbaraya Sundeep
Smartfusion2 SoC has hardened Microcontroller subsystem
and flash based FPGA fabric. This patch adds support for
Microcontroller subsystem in the SoC.

Signed-off-by: Subbaraya Sundeep 
Reviewed-by: Alistair Francis 
---
 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/msf2-soc.c   | 218 
 include/hw/arm/msf2-soc.h   |  66 
 4 files changed, 286 insertions(+)
 create mode 100644 hw/arm/msf2-soc.c
 create mode 100644 include/hw/arm/msf2-soc.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index bbdd3c1..5059d13 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -129,3 +129,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 a2e56ec..df36a03 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -19,3 +19,4 @@ obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
 obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o
 obj-$(CONFIG_MPS2) += mps2.o
+obj-$(CONFIG_MSF2) += msf2-soc.o
diff --git a/hw/arm/msf2-soc.c b/hw/arm/msf2-soc.c
new file mode 100644
index 000..47fffa4
--- /dev/null
+++ b/hw/arm/msf2-soc.c
@@ -0,0 +1,218 @@
+/*
+ * SmartFusion2 SoC emulation.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep 
+ *
+ * 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/char/serial.h"
+#include "hw/boards.h"
+#include "sysemu/block-backend.h"
+#include "qemu/cutils.h"
+#include "hw/arm/msf2-soc.h"
+
+#define MSF2_TIMER_BASE   0x40004000
+#define MSF2_SYSREG_BASE  0x40038000
+
+#define ENVM_BASE_ADDRESS 0x6000
+
+#define SRAM_BASE_ADDRESS 0x2000
+
+#define MSF2_ENVM_MAX_SIZE(512 * K_BYTE)
+
+/*
+ * eSRAM max size is 80k without SECDED(Single error correction and
+ * dual error detection) feature and 64k with SECDED.
+ * We do not support SECDED now.
+ */
+#define MSF2_ESRAM_MAX_SIZE   (80 * K_BYTE)
+
+static const uint32_t spi_addr[MSF2_NUM_SPIS] = { 0x40001000 , 0x40011000 };
+static const uint32_t uart_addr[MSF2_NUM_UARTS] = { 0x4000 , 0x4001 };
+
+static const int spi_irq[MSF2_NUM_SPIS] = { 2, 3 };
+static const int uart_irq[MSF2_NUM_UARTS] = { 10, 11 };
+static const int timer_irq[MSF2_NUM_TIMERS] = { 14, 15 };
+
+static void m2sxxx_soc_initfn(Object *obj)
+{
+MSF2State *s = MSF2_SOC(obj);
+int i;
+
+object_initialize(&s->armv7m, sizeof(s->armv7m), TYPE_ARMV7M);
+qdev_set_parent_bus(DEVICE(&s->armv7m), sysbus_get_default());
+
+object_initialize(&s->sysreg, sizeof(s->sysreg), TYPE_MSF2_SYSREG);
+qdev_set_parent_bus(DEVICE(&s->sysreg), sysbus_get_default());
+
+object_initialize(&s->timer, sizeof(s->timer), TYPE_MSS_TIMER);
+qdev_set_parent_bus(DEVICE(&s->timer), sysbus_get_default());
+
+for (i = 0; i < MSF2_NUM_SPIS; i++) {
+object_initialize(&s->spi[i], sizeof(s->spi[i]),
+  TYPE_MSS_SPI);
+qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default());
+}
+}
+
+static void m2sxxx_soc_realize(DeviceState *dev_soc, Error **errp)
+{
+MSF2State *s = MSF2_SOC(dev_soc);
+DeviceState *dev, *armv7m;
+SysBusDevice *busdev;
+Error *err = NULL;
+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);
+
+memory_region_init_rom(nvm, N

[Qemu-devel] [Qemu devel v8 PATCH 3/5] msf2: Add Smartfusion2 SPI controller

2017-09-07 Thread Subbaraya Sundeep
Modelled Microsemi's Smartfusion2 SPI controller.

Signed-off-by: Subbaraya Sundeep 
---
 hw/ssi/Makefile.objs |   1 +
 hw/ssi/mss-spi.c | 404 +++
 include/hw/ssi/mss-spi.h |  58 +++
 3 files changed, 463 insertions(+)
 create mode 100644 hw/ssi/mss-spi.c
 create mode 100644 include/hw/ssi/mss-spi.h

diff --git a/hw/ssi/Makefile.objs b/hw/ssi/Makefile.objs
index 487add2..f5bcc65 100644
--- a/hw/ssi/Makefile.objs
+++ b/hw/ssi/Makefile.objs
@@ -4,6 +4,7 @@ common-obj-$(CONFIG_XILINX_SPI) += xilinx_spi.o
 common-obj-$(CONFIG_XILINX_SPIPS) += xilinx_spips.o
 common-obj-$(CONFIG_ASPEED_SOC) += aspeed_smc.o
 common-obj-$(CONFIG_STM32F2XX_SPI) += stm32f2xx_spi.o
+common-obj-$(CONFIG_MSF2) += mss-spi.o
 
 obj-$(CONFIG_OMAP) += omap_spi.o
 obj-$(CONFIG_IMX) += imx_spi.o
diff --git a/hw/ssi/mss-spi.c b/hw/ssi/mss-spi.c
new file mode 100644
index 000..5a8e308
--- /dev/null
+++ b/hw/ssi/mss-spi.c
@@ -0,0 +1,404 @@
+/*
+ * Block model of SPI controller present in
+ * Microsemi's SmartFusion2 and SmartFusion SoCs.
+ *
+ * Copyright (C) 2017 Subbaraya Sundeep 
+ *
+ * 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/ssi/mss-spi.h"
+#include "qemu/log.h"
+
+#ifndef MSS_SPI_ERR_DEBUG
+#define MSS_SPI_ERR_DEBUG   0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+if (MSS_SPI_ERR_DEBUG >= lvl) { \
+qemu_log("%s: " fmt "\n", __func__, ## args); \
+} \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+#define FIFO_CAPACITY 32
+
+#define R_SPI_CONTROL 0
+#define R_SPI_DFSIZE  1
+#define R_SPI_STATUS  2
+#define R_SPI_INTCLR  3
+#define R_SPI_RX  4
+#define R_SPI_TX  5
+#define R_SPI_CLKGEN  6
+#define R_SPI_SS  7
+#define R_SPI_MIS 8
+#define R_SPI_RIS 9
+
+#define S_TXDONE (1 << 0)
+#define S_RXRDY  (1 << 1)
+#define S_RXCHOVRF   (1 << 2)
+#define S_RXFIFOFUL  (1 << 4)
+#define S_RXFIFOFULNXT   (1 << 5)
+#define S_RXFIFOEMP  (1 << 6)
+#define S_RXFIFOEMPNXT   (1 << 7)
+#define S_TXFIFOFUL  (1 << 8)
+#define S_TXFIFOFULNXT   (1 << 9)
+#define S_TXFIFOEMP  (1 << 10)
+#define S_TXFIFOEMPNXT   (1 << 11)
+#define S_FRAMESTART (1 << 12)
+#define S_SSEL   (1 << 13)
+#define S_ACTIVE (1 << 14)
+
+#define C_ENABLE (1 << 0)
+#define C_MODE   (1 << 1)
+#define C_INTRXDATA  (1 << 4)
+#define C_INTTXDATA  (1 << 5)
+#define C_INTRXOVRFLO(1 << 6)
+#define C_SPS(1 << 26)
+#define C_BIGFIFO(1 << 29)
+#define C_RESET  (1 << 31)
+
+#define FRAMESZ_MASK 0x1F
+#define FMCOUNT_MASK 0x0000
+#define FMCOUNT_SHIFT8
+
+static void txfifo_reset(MSSSpiState *s)
+{
+fifo32_reset(&s->tx_fifo);
+
+s->regs[R_SPI_STATUS] &= ~S_TXFIFOFUL;
+s->regs[R_SPI_STATUS] |= S_TXFIFOEMP;
+}
+
+static void rxfifo_reset(MSSSpiState *s)
+{
+fifo32_reset(&s->rx_fifo);
+
+s->regs[R_SPI_STATUS] &= ~S_RXFIFOFUL;
+s->regs[R_SPI_STATUS] |= S_RXFIFOEMP;
+}
+
+static void set_fifodepth(MSSSpiState *s)
+{
+unsigned int size = s->regs[R_SPI_DFSIZE] & FRAMESZ_MASK;
+
+if (size <= 8) {
+s->fifo_depth = 32;
+} else if (size <= 16) {
+s->fifo_depth = 16;
+} else if (size <= 32) {
+s->fifo_depth = 8;
+} else {
+s->fifo_depth = 4;
+}
+}
+
+static void update_mis(MSSSpiState *s)
+{
+uint32_t reg = s->regs[R_SPI_CONTROL];
+

[Qemu-devel] [Qemu devel v8 PATCH 0/5] Add support for Smartfusion2 SoC

2017-09-07 Thread Subbaraya Sundeep
Hi Qemu-devel,

I am trying to add Smartfusion2 SoC.
SoC is from Microsemi and System on Module(SOM)
board is from Emcraft systems. Smartfusion2 has hardened
Microcontroller(Cortex-M3)based Sub System and FPGA fabric.
At the moment only system timer, sysreg and SPI
controller are modelled.

Testing:
./arm-softmmu/qemu-system-arm -M smartfusion2-som -serial mon:stdio \
-kernel u-boot.bin -display none -drive file=spi.bin,if=mtd,format=raw

Binaries u-boot.bin and spi.bin are at:
https://github.com/Subbaraya-Sundeep/qemu-test-binaries.git

U-boot is from Emcraft with modified
- SPI driver not to use PDMA.
- ugly hack to pass dtb to kernel in r1.
@
https://github.com/Subbaraya-Sundeep/emcraft-uboot-sf2.git

Linux is 4.5 linux with Smartfusion2 SoC dts and clocksource
driver added by myself @
https://github.com/Subbaraya-Sundeep/linux.git

v8:
memory_region_init_ram to memory_region_init_rom in soc
%s/emcraft_sf2_init/emcraft_sf2_s2s010_init/g in som
Added mc->ignore_memory_transaction_failures = true in som
as per latest commit.
Code simplifications as suggested by Alistair in sysreg and ssi.

v7:
Removed vmstate_register_ram_global as per latest commit
Moved header files to C which are local to C source files
Removed abort() from msf2-sysreg.c
Added VMStateDescription in mss-timer.c

v6:
Moved some defines from header files to source files
Added properties m3clk, apb0div, apb0div1 properties
to soc.
Added properties apb0divisor, apb1divisor to sysreg
Update system_clock_source in msf2-soc.c
Changed machine name smartfusion2-som->emcraft-sf2

v5
As per Philippe comments:
Added abort in Sysreg if guest tries to remap memory
other than default mapping.
Use of CONFIG_MSF2 in Makefile for soc.c
Fixed incorrect logic in timer model.
Renamed msf2-timer.c -> mss-timer.c
msf2-spi.c -> mss-spi.c also type names
Renamed function msf2_init->emcraft_sf2_init in msf2-som.c
Added part-name,eNVM-size,eSRAM-size,pclk0 and pclk1
properties to soc.
Pass soc part-name,memory size and clock rate properties from som.
v4:
Fixed build failure by using PRIx macros.
v3:
Added SoC file and board file as per Alistair comments.
v2:
Added SPI controller so that u-boot loads kernel from spi flash.
v1:
Initial patch set with timer and sysreg

Thanks,
Sundeep


Subbaraya Sundeep (5):
  msf2: Add Smartfusion2 System timer
  msf2: Microsemi Smartfusion2 System Register block
  msf2: Add Smartfusion2 SPI controller
  msf2: Add Smartfusion2 SoC
  msf2: Add Emcraft's Smartfusion2 SOM kit

 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/msf2-soc.c   | 218 ++
 hw/arm/msf2-som.c   |  95 ++
 hw/misc/Makefile.objs   |   1 +
 hw/misc/msf2-sysreg.c   | 195 +++
 hw/ssi/Makefile.objs|   1 +
 hw/ssi/mss-spi.c| 404 
 hw/timer/Makefile.objs  |   1 +
 hw/timer/mss-timer.c| 289 
 include/hw/arm/msf2-soc.h   |  66 +++
 include/hw/misc/msf2-sysreg.h   |  78 
 include/hw/ssi/mss-spi.h|  58 ++
 include/hw/timer/mss-timer.h|  64 +++
 14 files changed, 1472 insertions(+)
 create mode 100644 hw/arm/msf2-soc.c
 create mode 100644 hw/arm/msf2-som.c
 create mode 100644 hw/misc/msf2-sysreg.c
 create mode 100644 hw/ssi/mss-spi.c
 create mode 100644 hw/timer/mss-timer.c
 create mode 100644 include/hw/arm/msf2-soc.h
 create mode 100644 include/hw/misc/msf2-sysreg.h
 create mode 100644 include/hw/ssi/mss-spi.h
 create mode 100644 include/hw/timer/mss-timer.h

-- 
2.5.0




[Qemu-devel] [Qemu devel v8 PATCH 2/5] msf2: Microsemi Smartfusion2 System Register block

2017-09-07 Thread Subbaraya Sundeep
Added Sytem register block of Smartfusion2.
This block has PLL registers which are accessed by guest.

Signed-off-by: Subbaraya Sundeep 
Reviewed-by: Alistair Francis 
---
 hw/misc/Makefile.objs |   1 +
 hw/misc/msf2-sysreg.c | 195 ++
 include/hw/misc/msf2-sysreg.h |  78 +
 3 files changed, 274 insertions(+)
 create mode 100644 hw/misc/msf2-sysreg.c
 create mode 100644 include/hw/misc/msf2-sysreg.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 29fb922..e8f0a02 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -59,3 +59,4 @@ obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
 obj-$(CONFIG_AUX) += auxbus.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o
 obj-y += mmio_interface.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 000..40d603d
--- /dev/null
+++ b/hw/misc/msf2-sysreg.c
@@ -0,0 +1,195 @@
+/*
+ * System Register block model of Microsemi SmartFusion2.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep 
+ *
+ * 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 "qemu/log.h"
+#include "hw/misc/msf2-sysreg.h"
+
+#ifndef MSF2_SYSREG_ERR_DEBUG
+#define MSF2_SYSREG_ERR_DEBUG  0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+if (MSF2_SYSREG_ERR_DEBUG >= lvl) { \
+qemu_log("%s: " fmt "\n", __func__, ## args); \
+} \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+static inline int msf2_divbits(uint32_t div)
+{
+int ret = 0;
+
+switch (div) {
+case 1:
+ret = 0;
+break;
+case 2:
+ret = 1;
+break;
+case 4:
+ret = 2;
+break;
+case 8:
+ret = 4;
+break;
+case 16:
+ret = 5;
+break;
+case 32:
+ret = 6;
+break;
+default:
+break;
+}
+
+return ret;
+}
+
+static void msf2_sysreg_reset(DeviceState *d)
+{
+MSF2SysregState *s = MSF2_SYSREG(d);
+
+DB_PRINT("RESET");
+
+s->regs[MSSDDR_PLL_STATUS_LOW_CR] = 0x021A2358;
+s->regs[MSSDDR_PLL_STATUS] = 0x3;
+s->regs[MSSDDR_FACC1_CR] = msf2_divbits(s->apb0div) << 5 |
+   msf2_divbits(s->apb1div) << 2;
+}
+
+static uint64_t msf2_sysreg_read(void *opaque, hwaddr offset,
+unsigned size)
+{
+MSF2SysregState *s = opaque;
+uint32_t ret = 0;
+
+offset >>= 2;
+if (offset < ARRAY_SIZE(s->regs)) {
+ret = s->regs[offset];
+DB_PRINT("addr: 0x%08" HWADDR_PRIx " data: 0x%08" PRIx32,
+offset << 2, ret);
+} else {
+qemu_log_mask(LOG_GUEST_ERROR,
+"%s: Bad offset 0x%08" HWADDR_PRIx "\n", __func__,
+offset << 2);
+}
+
+return ret;
+}
+
+static void msf2_sysreg_write(void *opaque, hwaddr offset,
+  uint64_t val, unsigned size)
+{
+MSF2SysregState *s = opaque;
+uint32_t newval = val;
+
+DB_PRINT("addr: 0x%08" HWADDR_PRIx " data: 0x%08" PRIx64,
+offset, val);
+
+offset >>= 2;
+
+switch (offset) {
+case MSSDDR_PLL_STATUS:
+break;
+
+case ESRAM_CR:
+if (newval != s->regs[ESRAM_CR]) {
+qemu_log_mask(LOG_GUEST_ERROR,
+   TYPE_MSF2_SYSREG": eSRAM remapping not supported\n");
+}
+break;
+
+case DDR_CR:
+if (newval != s->regs[DDR_CR]) {
+qemu_log_mask(LOG_GUEST_ERROR,
+   TYPE_MSF2_SYSREG": DDR remapping not supported\n");
+}
+break;
+
+case ENVM_REMAP_BASE_CR:
+if (newval != s->regs[ENVM_REMAP_BASE_CR]) {
+qemu_log_mask(LOG_GUEST_ERROR,
+   TYPE_MSF2_SYSREG": eNVM remapping not supported\n");
+}
+break;
+
+default:
+if (offset < ARRAY_SIZE(s->regs)) {
+s->regs[offset] = newval;
+} else {
+qemu_log_mask(LOG_GUEST_ERROR,
+"%s: Bad offset 0x%08" HWADDR_PRIx "\n", __func__,
+offset << 2);
+}
+break;
+}
+}
+
+static const MemoryRegionOps sysreg_ops = {
+.read = msf2_sysreg_read,
+.write = msf2_sysreg_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static v

[Qemu-devel] [Qemu devel v8 PATCH 1/5] msf2: Add Smartfusion2 System timer

2017-09-07 Thread Subbaraya Sundeep
Modelled System Timer in Microsemi's Smartfusion2 Soc.
Timer has two 32bit down counters and two interrupts.

Signed-off-by: Subbaraya Sundeep 
Reviewed-by: Alistair Francis 
---
 hw/timer/Makefile.objs   |   1 +
 hw/timer/mss-timer.c | 289 +++
 include/hw/timer/mss-timer.h |  64 ++
 3 files changed, 354 insertions(+)
 create mode 100644 hw/timer/mss-timer.c
 create mode 100644 include/hw/timer/mss-timer.h

diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index 15cce1c..8c19eac 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -42,3 +42,4 @@ common-obj-$(CONFIG_ASPEED_SOC) += aspeed_timer.o
 
 common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
 common-obj-$(CONFIG_CMSDK_APB_TIMER) += cmsdk-apb-timer.o
+common-obj-$(CONFIG_MSF2) += mss-timer.o
diff --git a/hw/timer/mss-timer.c b/hw/timer/mss-timer.c
new file mode 100644
index 000..60f1213
--- /dev/null
+++ b/hw/timer/mss-timer.c
@@ -0,0 +1,289 @@
+/*
+ * Block model of System timer present in
+ * Microsemi's SmartFusion2 and SmartFusion SoCs.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep .
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/main-loop.h"
+#include "qemu/log.h"
+#include "hw/timer/mss-timer.h"
+
+#ifndef MSS_TIMER_ERR_DEBUG
+#define MSS_TIMER_ERR_DEBUG  0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+if (MSS_TIMER_ERR_DEBUG >= lvl) { \
+qemu_log("%s: " fmt "\n", __func__, ## args); \
+} \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+#define R_TIM_VAL 0
+#define R_TIM_LOADVAL 1
+#define R_TIM_BGLOADVAL   2
+#define R_TIM_CTRL3
+#define R_TIM_RIS 4
+#define R_TIM_MIS 5
+
+#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)
+#define TIMER_MODE  (1 << 0)
+
+static void timer_update_irq(struct Msf2Timer *st)
+{
+bool isr, ier;
+
+isr = !!(st->regs[R_TIM_RIS] & TIMER_RIS_ACK);
+ier = !!(st->regs[R_TIM_CTRL] & TIMER_CTRL_INTR);
+qemu_set_irq(st->irq, (ier && isr));
+}
+
+static void timer_update(struct Msf2Timer *st)
+{
+uint64_t count;
+
+if (!(st->regs[R_TIM_CTRL] & TIMER_CTRL_ENBL)) {
+ptimer_stop(st->ptimer);
+return;
+}
+
+count = st->regs[R_TIM_LOADVAL];
+ptimer_set_limit(st->ptimer, count, 1);
+ptimer_run(st->ptimer, 1);
+}
+
+static uint64_t
+timer_read(void *opaque, hwaddr offset, unsigned int size)
+{
+MSSTimerState *t = opaque;
+hwaddr addr;
+struct Msf2Timer *st;
+uint32_t ret = 0;
+int timer = 0;
+int isr;
+int ier;
+
+addr = offset >> 2;
+/*
+ * Two independent timers has same base address.
+ * Based on address passed figure out which timer is being used.
+ */
+if ((addr >= R_TIM1_MAX) && (addr < NUM_TIMERS * R_TIM1_MAX)) {
+timer = 1;
+addr -= R_TIM1_MAX;
+}
+
+st = &t->timers[timer];
+
+switch (addr) {
+case R_TIM_VAL:
+ret = ptimer_get_count(st->ptimer);
+break;
+
+case R_TIM_MIS:
+isr = !!(st->regs[R_TIM_RIS] & TIMER_RIS_ACK);
+ier = !!(st->regs[R_TIM_CTRL] & TIMER_CTRL_INTR);
+ret = ier & isr;
+break;
+
+default:
+if (addr < R_TIM1_MAX) {
+ret = st->regs[addr];
+} else {
+qemu_log_mask(LOG_GUEST_ERROR,
+TYPE_MSS_TIMER": 64-bit mode not supported\n");
+return ret;
+}
+break;
+}
+
+DB_PRINT("timer=%d 

[Qemu-devel] [Qemu devel v7 PATCH 4/5] msf2: Add Smartfusion2 SoC

2017-08-28 Thread Subbaraya Sundeep
Smartfusion2 SoC has hardened Microcontroller subsystem
and flash based FPGA fabric. This patch adds support for
Microcontroller subsystem in the SoC.

Signed-off-by: Subbaraya Sundeep 
---
 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/msf2-soc.c   | 215 
 include/hw/arm/msf2-soc.h   |  66 
 4 files changed, 283 insertions(+)
 create mode 100644 hw/arm/msf2-soc.c
 create mode 100644 include/hw/arm/msf2-soc.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index bbdd3c1..5059d13 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -129,3 +129,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 a2e56ec..df36a03 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -19,3 +19,4 @@ obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
 obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o
 obj-$(CONFIG_MPS2) += mps2.o
+obj-$(CONFIG_MSF2) += msf2-soc.o
diff --git a/hw/arm/msf2-soc.c b/hw/arm/msf2-soc.c
new file mode 100644
index 000..276eec5
--- /dev/null
+++ b/hw/arm/msf2-soc.c
@@ -0,0 +1,215 @@
+/*
+ * SmartFusion2 SoC emulation.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep 
+ *
+ * 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/char/serial.h"
+#include "hw/boards.h"
+#include "sysemu/block-backend.h"
+#include "qemu/cutils.h"
+#include "hw/arm/msf2-soc.h"
+
+#define MSF2_TIMER_BASE   0x40004000
+#define MSF2_SYSREG_BASE  0x40038000
+
+#define ENVM_BASE_ADDRESS 0x6000
+
+#define SRAM_BASE_ADDRESS 0x2000
+
+#define MSF2_ENVM_SIZE(512 * K_BYTE)
+#define MSF2_ESRAM_SIZE   (64 * K_BYTE)
+
+static const uint32_t spi_addr[MSF2_NUM_SPIS] = { 0x40001000 , 0x40011000 };
+static const uint32_t uart_addr[MSF2_NUM_UARTS] = { 0x4000 , 0x4001 };
+
+static const int spi_irq[MSF2_NUM_SPIS] = { 2, 3 };
+static const int uart_irq[MSF2_NUM_UARTS] = { 10, 11 };
+static const int timer_irq[MSF2_NUM_TIMERS] = { 14, 15 };
+
+static void m2sxxx_soc_initfn(Object *obj)
+{
+MSF2State *s = MSF2_SOC(obj);
+int i;
+
+object_initialize(&s->armv7m, sizeof(s->armv7m), TYPE_ARMV7M);
+qdev_set_parent_bus(DEVICE(&s->armv7m), sysbus_get_default());
+
+object_initialize(&s->sysreg, sizeof(s->sysreg), TYPE_MSF2_SYSREG);
+qdev_set_parent_bus(DEVICE(&s->sysreg), sysbus_get_default());
+
+object_initialize(&s->timer, sizeof(s->timer), TYPE_MSS_TIMER);
+qdev_set_parent_bus(DEVICE(&s->timer), sysbus_get_default());
+
+for (i = 0; i < MSF2_NUM_SPIS; i++) {
+object_initialize(&s->spi[i], sizeof(s->spi[i]),
+  TYPE_MSS_SPI);
+qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default());
+}
+}
+
+static void m2sxxx_soc_realize(DeviceState *dev_soc, Error **errp)
+{
+MSF2State *s = MSF2_SOC(dev_soc);
+DeviceState *dev, *armv7m;
+SysBusDevice *busdev;
+Error *err = NULL;
+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);
+
+memory_region_init_ram(nvm, NULL, "MSF2.eNVM", s->envm_size,
+   &error_fatal);
+
+/*
+ * On power-on, the eNVM region 0x6000 is automatically
+ * remapped to the Cortex-M3 processor ex

[Qemu-devel] [Qemu devel v7 PATCH 1/5] msf2: Add Smartfusion2 System timer

2017-08-28 Thread Subbaraya Sundeep
Modelled System Timer in Microsemi's Smartfusion2 Soc.
Timer has two 32bit down counters and two interrupts.

Signed-off-by: Subbaraya Sundeep 
---
 hw/timer/Makefile.objs   |   1 +
 hw/timer/mss-timer.c | 289 +++
 include/hw/timer/mss-timer.h |  64 ++
 3 files changed, 354 insertions(+)
 create mode 100644 hw/timer/mss-timer.c
 create mode 100644 include/hw/timer/mss-timer.h

diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index 15cce1c..8c19eac 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -42,3 +42,4 @@ common-obj-$(CONFIG_ASPEED_SOC) += aspeed_timer.o
 
 common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
 common-obj-$(CONFIG_CMSDK_APB_TIMER) += cmsdk-apb-timer.o
+common-obj-$(CONFIG_MSF2) += mss-timer.o
diff --git a/hw/timer/mss-timer.c b/hw/timer/mss-timer.c
new file mode 100644
index 000..60f1213
--- /dev/null
+++ b/hw/timer/mss-timer.c
@@ -0,0 +1,289 @@
+/*
+ * Block model of System timer present in
+ * Microsemi's SmartFusion2 and SmartFusion SoCs.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep .
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/main-loop.h"
+#include "qemu/log.h"
+#include "hw/timer/mss-timer.h"
+
+#ifndef MSS_TIMER_ERR_DEBUG
+#define MSS_TIMER_ERR_DEBUG  0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+if (MSS_TIMER_ERR_DEBUG >= lvl) { \
+qemu_log("%s: " fmt "\n", __func__, ## args); \
+} \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+#define R_TIM_VAL 0
+#define R_TIM_LOADVAL 1
+#define R_TIM_BGLOADVAL   2
+#define R_TIM_CTRL3
+#define R_TIM_RIS 4
+#define R_TIM_MIS 5
+
+#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)
+#define TIMER_MODE  (1 << 0)
+
+static void timer_update_irq(struct Msf2Timer *st)
+{
+bool isr, ier;
+
+isr = !!(st->regs[R_TIM_RIS] & TIMER_RIS_ACK);
+ier = !!(st->regs[R_TIM_CTRL] & TIMER_CTRL_INTR);
+qemu_set_irq(st->irq, (ier && isr));
+}
+
+static void timer_update(struct Msf2Timer *st)
+{
+uint64_t count;
+
+if (!(st->regs[R_TIM_CTRL] & TIMER_CTRL_ENBL)) {
+ptimer_stop(st->ptimer);
+return;
+}
+
+count = st->regs[R_TIM_LOADVAL];
+ptimer_set_limit(st->ptimer, count, 1);
+ptimer_run(st->ptimer, 1);
+}
+
+static uint64_t
+timer_read(void *opaque, hwaddr offset, unsigned int size)
+{
+MSSTimerState *t = opaque;
+hwaddr addr;
+struct Msf2Timer *st;
+uint32_t ret = 0;
+int timer = 0;
+int isr;
+int ier;
+
+addr = offset >> 2;
+/*
+ * Two independent timers has same base address.
+ * Based on address passed figure out which timer is being used.
+ */
+if ((addr >= R_TIM1_MAX) && (addr < NUM_TIMERS * R_TIM1_MAX)) {
+timer = 1;
+addr -= R_TIM1_MAX;
+}
+
+st = &t->timers[timer];
+
+switch (addr) {
+case R_TIM_VAL:
+ret = ptimer_get_count(st->ptimer);
+break;
+
+case R_TIM_MIS:
+isr = !!(st->regs[R_TIM_RIS] & TIMER_RIS_ACK);
+ier = !!(st->regs[R_TIM_CTRL] & TIMER_CTRL_INTR);
+ret = ier & isr;
+break;
+
+default:
+if (addr < R_TIM1_MAX) {
+ret = st->regs[addr];
+} else {
+qemu_log_mask(LOG_GUEST_ERROR,
+TYPE_MSS_TIMER": 64-bit mode not supported\n");
+return ret;
+}
+break;
+}
+
+DB_PRINT("timer=%d 0x%" HWADDR_PRIx "=0x%"

[Qemu-devel] [Qemu devel v7 PATCH 5/5] msf2: Add Emcraft's Smartfusion2 SOM kit

2017-08-28 Thread Subbaraya Sundeep
Emulated Emcraft's Smartfusion2 System On Module starter
kit.

Signed-off-by: Subbaraya Sundeep 
---
 hw/arm/Makefile.objs |  2 +-
 hw/arm/msf2-som.c| 94 
 2 files changed, 95 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/msf2-som.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index df36a03..e81a7dc 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -19,4 +19,4 @@ obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
 obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o
 obj-$(CONFIG_MPS2) += mps2.o
-obj-$(CONFIG_MSF2) += msf2-soc.o
+obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
diff --git a/hw/arm/msf2-som.c b/hw/arm/msf2-som.c
new file mode 100644
index 000..fd89ba9
--- /dev/null
+++ b/hw/arm/msf2-som.c
@@ -0,0 +1,94 @@
+/*
+ * SmartFusion2 SOM starter kit(from Emcraft) emulation.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/boards.h"
+#include "hw/arm/arm.h"
+#include "exec/address-spaces.h"
+#include "qemu/cutils.h"
+#include "hw/arm/msf2-soc.h"
+
+#define DDR_BASE_ADDRESS  0xA000
+#define DDR_SIZE  (64 * M_BYTE)
+
+#define M2S010_ENVM_SIZE  (256 * K_BYTE)
+#define M2S010_ESRAM_SIZE (64 * K_BYTE)
+
+static void emcraft_sf2_init(MachineState *machine)
+{
+DeviceState *dev;
+DeviceState *spi_flash;
+MSF2State *soc;
+DriveInfo *dinfo = drive_get_next(IF_MTD);
+qemu_irq cs_line;
+SSIBus *spi_bus;
+MemoryRegion *sysmem = get_system_memory();
+MemoryRegion *ddr = g_new(MemoryRegion, 1);
+
+memory_region_init_ram(ddr, NULL, "ddr-ram", DDR_SIZE,
+   &error_fatal);
+memory_region_add_subregion(sysmem, DDR_BASE_ADDRESS, ddr);
+
+dev = qdev_create(NULL, TYPE_MSF2_SOC);
+qdev_prop_set_string(dev, "part-name", "M2S010");
+qdev_prop_set_uint64(dev, "eNVM-size", M2S010_ENVM_SIZE);
+qdev_prop_set_uint64(dev, "eSRAM-size", M2S010_ESRAM_SIZE);
+
+/*
+ * CPU clock and peripheral clocks(APB0, APB1)are configurable
+ * in Libero. CPU clock is divided by APB0 and APB1 divisors for
+ * peripherals. Emcraft's SoM kit comes with these settings by default.
+ */
+qdev_prop_set_uint32(dev, "m3clk", 142 * 100);
+qdev_prop_set_uint32(dev, "apb0div", 2);
+qdev_prop_set_uint32(dev, "apb1div", 2);
+
+object_property_set_bool(OBJECT(dev), true, "realized", &error_fatal);
+
+soc = MSF2_SOC(dev);
+
+/* Attach SPI flash to SPI0 controller */
+spi_bus = (SSIBus *)qdev_get_child_bus(dev, "spi0");
+spi_flash = ssi_create_slave_no_init(spi_bus, "s25sl12801");
+qdev_prop_set_uint8(spi_flash, "spansion-cr2nv", 1);
+if (dinfo) {
+qdev_prop_set_drive(spi_flash, "drive", blk_by_legacy_dinfo(dinfo),
+&error_fatal);
+}
+qdev_init_nofail(spi_flash);
+cs_line = qdev_get_gpio_in_named(spi_flash, SSI_GPIO_CS, 0);
+sysbus_connect_irq(SYS_BUS_DEVICE(&soc->spi[0]), 1, cs_line);
+
+armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
+   soc->envm_size);
+}
+
+static void emcraft_sf2_machine_init(MachineClass *mc)
+{
+mc->desc = "SmartFusion2 SOM kit from Emcraft";
+mc->init = emcraft_sf2_init;
+}
+
+DEFINE_MACHINE("emcraft-sf2", emcraft_sf2_machine_init)
-- 
2.5.0




[Qemu-devel] [Qemu devel v7 PATCH 2/5] msf2: Microsemi Smartfusion2 System Register block

2017-08-28 Thread Subbaraya Sundeep
Added Sytem register block of Smartfusion2.
This block has PLL registers which are accessed by guest.

Signed-off-by: Subbaraya Sundeep 
---
 hw/misc/Makefile.objs |   1 +
 hw/misc/msf2-sysreg.c | 199 ++
 include/hw/misc/msf2-sysreg.h |  78 +
 3 files changed, 278 insertions(+)
 create mode 100644 hw/misc/msf2-sysreg.c
 create mode 100644 include/hw/misc/msf2-sysreg.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 29fb922..e8f0a02 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -59,3 +59,4 @@ obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
 obj-$(CONFIG_AUX) += auxbus.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o
 obj-y += mmio_interface.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 000..2aeb555
--- /dev/null
+++ b/hw/misc/msf2-sysreg.c
@@ -0,0 +1,199 @@
+/*
+ * System Register block model of Microsemi SmartFusion2.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep 
+ *
+ * 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 "qemu/log.h"
+#include "hw/misc/msf2-sysreg.h"
+
+#ifndef MSF2_SYSREG_ERR_DEBUG
+#define MSF2_SYSREG_ERR_DEBUG  0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+if (MSF2_SYSREG_ERR_DEBUG >= lvl) { \
+qemu_log("%s: " fmt "\n", __func__, ## args); \
+} \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+static inline int msf2_divbits(uint32_t div)
+{
+int ret = 0;
+
+switch (div) {
+case 1:
+ret = 0;
+break;
+case 2:
+ret = 1;
+break;
+case 4:
+ret = 2;
+break;
+case 8:
+ret = 4;
+break;
+case 16:
+ret = 5;
+break;
+case 32:
+ret = 6;
+break;
+default:
+break;
+}
+
+return ret;
+}
+
+static void msf2_sysreg_reset(DeviceState *d)
+{
+MSF2SysregState *s = MSF2_SYSREG(d);
+
+DB_PRINT("RESET");
+
+s->regs[MSSDDR_PLL_STATUS_LOW_CR] = 0x021A2358;
+s->regs[MSSDDR_PLL_STATUS] = 0x3;
+s->regs[MSSDDR_FACC1_CR] = msf2_divbits(s->apb0div) << 5 |
+   msf2_divbits(s->apb1div) << 2;
+}
+
+static uint64_t msf2_sysreg_read(void *opaque, hwaddr offset,
+unsigned size)
+{
+MSF2SysregState *s = opaque;
+uint32_t ret = 0;
+
+offset >>= 2;
+if (offset < ARRAY_SIZE(s->regs)) {
+ret = s->regs[offset];
+DB_PRINT("addr: 0x%08" HWADDR_PRIx " data: 0x%08" PRIx32,
+offset << 2, ret);
+} else {
+qemu_log_mask(LOG_GUEST_ERROR,
+"%s: Bad offset 0x%08" HWADDR_PRIx "\n", __func__,
+offset << 2);
+}
+
+return ret;
+}
+
+static void msf2_sysreg_write(void *opaque, hwaddr offset,
+  uint64_t val, unsigned size)
+{
+MSF2SysregState *s = (MSF2SysregState *)opaque;
+uint32_t newval = val;
+uint32_t oldval;
+
+DB_PRINT("addr: 0x%08" HWADDR_PRIx " data: 0x%08" PRIx64,
+offset, val);
+
+offset >>= 2;
+
+switch (offset) {
+case MSSDDR_PLL_STATUS:
+break;
+
+case ESRAM_CR:
+oldval = s->regs[ESRAM_CR];
+if (oldval ^ newval) {
+qemu_log_mask(LOG_GUEST_ERROR,
+   TYPE_MSF2_SYSREG": eSRAM remapping not supported\n");
+}
+break;
+
+case DDR_CR:
+oldval = s->regs[DDR_CR];
+if (oldval ^ newval) {
+qemu_log_mask(LOG_GUEST_ERROR,
+   TYPE_MSF2_SYSREG": DDR remapping not supported\n");
+}
+break;
+
+case ENVM_REMAP_BASE_CR:
+oldval = s->regs[ENVM_REMAP_BASE_CR];
+if (oldval ^ newval) {
+qemu_log_mask(LOG_GUEST_ERROR,
+   TYPE_MSF2_SYSREG": eNVM remapping not supported\n");
+}
+break;
+
+default:
+if (offset < ARRAY_SIZE(s->regs)) {
+s->regs[offset] = val;
+} else {
+qemu_log_mask(LOG_GUEST_ERROR,
+"%s: Bad offset 0x%08" HWADDR_PRIx "\n", __func__,
+offset << 2);
+}
+break;
+}
+}
+
+static const MemoryRegionOps sysreg_ops = {
+.read = ms

[Qemu-devel] [Qemu devel v7 PATCH 3/5] msf2: Add Smartfusion2 SPI controller

2017-08-28 Thread Subbaraya Sundeep
Modelled Microsemi's Smartfusion2 SPI controller.

Signed-off-by: Subbaraya Sundeep 
---
 hw/ssi/Makefile.objs |   1 +
 hw/ssi/mss-spi.c | 409 +++
 include/hw/ssi/mss-spi.h |  58 +++
 3 files changed, 468 insertions(+)
 create mode 100644 hw/ssi/mss-spi.c
 create mode 100644 include/hw/ssi/mss-spi.h

diff --git a/hw/ssi/Makefile.objs b/hw/ssi/Makefile.objs
index 487add2..f5bcc65 100644
--- a/hw/ssi/Makefile.objs
+++ b/hw/ssi/Makefile.objs
@@ -4,6 +4,7 @@ common-obj-$(CONFIG_XILINX_SPI) += xilinx_spi.o
 common-obj-$(CONFIG_XILINX_SPIPS) += xilinx_spips.o
 common-obj-$(CONFIG_ASPEED_SOC) += aspeed_smc.o
 common-obj-$(CONFIG_STM32F2XX_SPI) += stm32f2xx_spi.o
+common-obj-$(CONFIG_MSF2) += mss-spi.o
 
 obj-$(CONFIG_OMAP) += omap_spi.o
 obj-$(CONFIG_IMX) += imx_spi.o
diff --git a/hw/ssi/mss-spi.c b/hw/ssi/mss-spi.c
new file mode 100644
index 000..7209363
--- /dev/null
+++ b/hw/ssi/mss-spi.c
@@ -0,0 +1,409 @@
+/*
+ * Block model of SPI controller present in
+ * Microsemi's SmartFusion2 and SmartFusion SoCs.
+ *
+ * Copyright (C) 2017 Subbaraya Sundeep 
+ *
+ * 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/ssi/mss-spi.h"
+#include "qemu/log.h"
+
+#ifndef MSS_SPI_ERR_DEBUG
+#define MSS_SPI_ERR_DEBUG   0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+if (MSS_SPI_ERR_DEBUG >= lvl) { \
+qemu_log("%s: " fmt "\n", __func__, ## args); \
+} \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+#define FIFO_CAPACITY 32
+#define FIFO_CAPACITY 32
+
+#define R_SPI_CONTROL 0
+#define R_SPI_DFSIZE  1
+#define R_SPI_STATUS  2
+#define R_SPI_INTCLR  3
+#define R_SPI_RX  4
+#define R_SPI_TX  5
+#define R_SPI_CLKGEN  6
+#define R_SPI_SS  7
+#define R_SPI_MIS 8
+#define R_SPI_RIS 9
+
+#define S_TXDONE (1 << 0)
+#define S_RXRDY  (1 << 1)
+#define S_RXCHOVRF   (1 << 2)
+#define S_RXFIFOFUL  (1 << 4)
+#define S_RXFIFOFULNXT   (1 << 5)
+#define S_RXFIFOEMP  (1 << 6)
+#define S_RXFIFOEMPNXT   (1 << 7)
+#define S_TXFIFOFUL  (1 << 8)
+#define S_TXFIFOFULNXT   (1 << 9)
+#define S_TXFIFOEMP  (1 << 10)
+#define S_TXFIFOEMPNXT   (1 << 11)
+#define S_FRAMESTART (1 << 12)
+#define S_SSEL   (1 << 13)
+#define S_ACTIVE (1 << 14)
+
+#define C_ENABLE (1 << 0)
+#define C_MODE   (1 << 1)
+#define C_INTRXDATA  (1 << 4)
+#define C_INTTXDATA  (1 << 5)
+#define C_INTRXOVRFLO(1 << 6)
+#define C_SPS(1 << 26)
+#define C_BIGFIFO(1 << 29)
+#define C_RESET  (1 << 31)
+
+#define FRAMESZ_MASK 0x1F
+#define FMCOUNT_MASK 0x0000
+#define FMCOUNT_SHIFT8
+
+static void txfifo_reset(MSSSpiState *s)
+{
+fifo32_reset(&s->tx_fifo);
+
+s->regs[R_SPI_STATUS] &= ~S_TXFIFOFUL;
+s->regs[R_SPI_STATUS] |= S_TXFIFOEMP;
+}
+
+static void rxfifo_reset(MSSSpiState *s)
+{
+fifo32_reset(&s->rx_fifo);
+
+s->regs[R_SPI_STATUS] &= ~S_RXFIFOFUL;
+s->regs[R_SPI_STATUS] |= S_RXFIFOEMP;
+}
+
+static void set_fifodepth(MSSSpiState *s)
+{
+unsigned int size = s->regs[R_SPI_DFSIZE] & FRAMESZ_MASK;
+
+if (size <= 8) {
+s->fifo_depth = 32;
+} else if (size <= 16) {
+s->fifo_depth = 16;
+} else if (size <= 32) {
+s->fifo_depth = 8;
+} else {
+s->fifo_depth = 4;
+}
+}
+
+static void mss_spi_do_reset(MSSSpiState *s)
+{
+ 

[Qemu-devel] [Qemu devel v7 PATCH 0/5] Add support for Smartfusion2 SoC

2017-08-28 Thread Subbaraya Sundeep
Hi Qemu-devel,

I am trying to add Smartfusion2 SoC.
SoC is from Microsemi and System on Module(SOM)
board is from Emcraft systems. Smartfusion2 has hardened
Microcontroller(Cortex-M3)based Sub System and FPGA fabric.
At the moment only system timer, sysreg and SPI
controller are modelled.

Testing:
./arm-softmmu/qemu-system-arm -M smartfusion2-som -serial mon:stdio \
-kernel u-boot.bin -display none -drive file=spi.bin,if=mtd,format=raw

Binaries u-boot.bin and spi.bin are at:
https://github.com/Subbaraya-Sundeep/qemu-test-binaries.git

U-boot is from Emcraft with modified
- SPI driver not to use PDMA.
- ugly hack to pass dtb to kernel in r1.
@
https://github.com/Subbaraya-Sundeep/emcraft-uboot-sf2.git

Linux is 4.5 linux with Smartfusion2 SoC dts and clocksource
driver added by myself @
https://github.com/Subbaraya-Sundeep/linux.git

v7:
Removed vmstate_register_ram_global as per latest commit
Moved header files to C which are local to C source files
Removed abort() from msf2-sysreg.c
Added VMStateDescription in mss-timer.c

v6:
Moved some defines from header files to source files
Added properties m3clk, apb0div, apb0div1 properties
to soc.
Added properties apb0divisor, apb1divisor to sysreg
Update system_clock_source in msf2-soc.c
Changed machine name smartfusion2-som->emcraft-sf2

v5
As per Philippe comments:
Added abort in Sysreg if guest tries to remap memory
other than default mapping.
Use of CONFIG_MSF2 in Makefile for soc.c
Fixed incorrect logic in timer model.
Renamed msf2-timer.c -> mss-timer.c
msf2-spi.c -> mss-spi.c also type names
Renamed function msf2_init->emcraft_sf2_init in msf2-som.c
Added part-name,eNVM-size,eSRAM-size,pclk0 and pclk1
properties to soc.
Pass soc part-name,memory size and clock rate properties from som.
v4:
Fixed build failure by using PRIx macros.
v3:
Added SoC file and board file as per Alistair comments.
v2:
Added SPI controller so that u-boot loads kernel from spi flash.
v1:
Initial patch set with timer and sysreg

Thanks,
Sundeep

Subbaraya Sundeep (5):
  msf2: Add Smartfusion2 System timer
  msf2: Microsemi Smartfusion2 System Register block
  msf2: Add Smartfusion2 SPI controller
  msf2: Add Smartfusion2 SoC
  msf2: Add Emcraft's Smartfusion2 SOM kit

 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/msf2-soc.c   | 215 +
 hw/arm/msf2-som.c   |  94 +
 hw/misc/Makefile.objs   |   1 +
 hw/misc/msf2-sysreg.c   | 199 +++
 hw/ssi/Makefile.objs|   1 +
 hw/ssi/mss-spi.c| 409 
 hw/timer/Makefile.objs  |   1 +
 hw/timer/mss-timer.c| 289 
 include/hw/arm/msf2-soc.h   |  66 +++
 include/hw/misc/msf2-sysreg.h   |  78 
 include/hw/ssi/mss-spi.h|  58 ++
 include/hw/timer/mss-timer.h|  64 +++
 14 files changed, 1477 insertions(+)
 create mode 100644 hw/arm/msf2-soc.c
 create mode 100644 hw/arm/msf2-som.c
 create mode 100644 hw/misc/msf2-sysreg.c
 create mode 100644 hw/ssi/mss-spi.c
 create mode 100644 hw/timer/mss-timer.c
 create mode 100644 include/hw/arm/msf2-soc.h
 create mode 100644 include/hw/misc/msf2-sysreg.h
 create mode 100644 include/hw/ssi/mss-spi.h
 create mode 100644 include/hw/timer/mss-timer.h

-- 
2.5.0




[Qemu-devel] [Qemu devel v6 PATCH 5/5] msf2: Add Emcraft's Smartfusion2 SOM kit.

2017-07-02 Thread Subbaraya Sundeep
Emulated Emcraft's Smartfusion2 System On Module starter
kit.

Signed-off-by: Subbaraya Sundeep 
---
 hw/arm/Makefile.objs |  1 +
 hw/arm/msf2-som.c| 94 
 2 files changed, 95 insertions(+)
 create mode 100644 hw/arm/msf2-som.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index c828061..2073934 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -5,6 +5,7 @@ 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-$(CONFIG_ACPI) += virt-acpi-build.o
 obj-y += netduino2.o
+obj-$(CONFIG_MSF2) += msf2-som.o
 obj-y += sysbus-fdt.o
 
 obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
diff --git a/hw/arm/msf2-som.c b/hw/arm/msf2-som.c
new file mode 100644
index 000..ea945b1
--- /dev/null
+++ b/hw/arm/msf2-som.c
@@ -0,0 +1,94 @@
+/*
+ * SmartFusion2 SOM starter kit(from Emcraft) emulation.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/boards.h"
+#include "hw/arm/msf2-soc.h"
+#include "hw/arm/arm.h"
+#include "exec/address-spaces.h"
+
+#define DDR_BASE_ADDRESS  0xA000
+#define DDR_SIZE  (64 * M_BYTE)
+
+#define M2S010_ENVM_SIZE  (256 * K_BYTE)
+#define M2S010_ESRAM_SIZE (64 * K_BYTE)
+
+static void emcraft_sf2_init(MachineState *machine)
+{
+DeviceState *dev;
+DeviceState *spi_flash;
+MSF2State *soc;
+DriveInfo *dinfo = drive_get_next(IF_MTD);
+qemu_irq cs_line;
+SSIBus *spi_bus;
+MemoryRegion *sysmem = get_system_memory();
+MemoryRegion *ddr = g_new(MemoryRegion, 1);
+
+memory_region_init_ram(ddr, NULL, "ddr-ram", DDR_SIZE,
+   &error_fatal);
+vmstate_register_ram_global(ddr);
+memory_region_add_subregion(sysmem, DDR_BASE_ADDRESS, ddr);
+
+dev = qdev_create(NULL, TYPE_MSF2_SOC);
+qdev_prop_set_string(dev, "part-name", "M2S010");
+qdev_prop_set_uint64(dev, "eNVM-size", M2S010_ENVM_SIZE);
+qdev_prop_set_uint64(dev, "eSRAM-size", M2S010_ESRAM_SIZE);
+
+/*
+ * CPU clock and peripheral clocks(APB0, APB1)are configurable
+ * in Libero. CPU clock is divided by APB0 and APB1 divisors for
+ * peripherals. Emcraft's SoM kit comes with these settings by default.
+ */
+qdev_prop_set_uint32(dev, "m3clk", 142 * 100);
+qdev_prop_set_uint32(dev, "apb0div", 2);
+qdev_prop_set_uint32(dev, "apb1div", 2);
+
+object_property_set_bool(OBJECT(dev), true, "realized", &error_fatal);
+
+soc = MSF2_SOC(dev);
+
+/* Attach SPI flash to SPI0 controller */
+spi_bus = (SSIBus *)qdev_get_child_bus(dev, "spi0");
+spi_flash = ssi_create_slave_no_init(spi_bus, "s25sl12801");
+qdev_prop_set_uint8(spi_flash, "spansion-cr2nv", 1);
+if (dinfo) {
+qdev_prop_set_drive(spi_flash, "drive", blk_by_legacy_dinfo(dinfo),
+&error_fatal);
+}
+qdev_init_nofail(spi_flash);
+cs_line = qdev_get_gpio_in_named(spi_flash, SSI_GPIO_CS, 0);
+sysbus_connect_irq(SYS_BUS_DEVICE(&soc->spi[0]), 1, cs_line);
+
+armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
+   soc->envm_size);
+}
+
+static void emcraft_sf2_machine_init(MachineClass *mc)
+{
+mc->desc = "SmartFusion2 SOM kit from Emcraft";
+mc->init = emcraft_sf2_init;
+}
+
+DEFINE_MACHINE("emcraft-sf2", emcraft_sf2_machine_init)
-- 
2.5.0




[Qemu-devel] [Qemu devel v6 PATCH 4/5] msf2: Add Smartfusion2 SoC.

2017-07-02 Thread Subbaraya Sundeep
Smartfusion2 SoC has hardened Microcontroller subsystem
and flash based FPGA fabric. This patch adds support for
Microcontroller subsystem in the SoC.

Signed-off-by: Subbaraya Sundeep 
---
 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/msf2-soc.c   | 216 
 include/hw/arm/msf2-soc.h   |  67 +
 4 files changed, 285 insertions(+)
 create mode 100644 hw/arm/msf2-soc.c
 create mode 100644 include/hw/arm/msf2-soc.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 78d7af0..7062512 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -122,3 +122,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..c828061 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -18,3 +18,4 @@ obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
 obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
 obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o
+obj-$(CONFIG_MSF2) += msf2-soc.o
diff --git a/hw/arm/msf2-soc.c b/hw/arm/msf2-soc.c
new file mode 100644
index 000..d45827f
--- /dev/null
+++ b/hw/arm/msf2-soc.c
@@ -0,0 +1,216 @@
+/*
+ * SmartFusion2 SoC emulation.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep 
+ *
+ * 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/char/serial.h"
+#include "hw/boards.h"
+#include "sysemu/block-backend.h"
+#include "hw/arm/msf2-soc.h"
+
+#define MSF2_TIMER_BASE 0x40004000
+#define MSF2_SYSREG_BASE0x40038000
+
+#define ENVM_BASE_ADDRESS 0x6000
+
+#define SRAM_BASE_ADDRESS 0x2000
+
+#define MSF2_ENVM_SIZE(512 * K_BYTE)
+#define MSF2_ESRAM_SIZE   (64 * K_BYTE)
+
+static const uint32_t spi_addr[MSF2_NUM_SPIS] = { 0x40001000 , 0x40011000 };
+static const uint32_t uart_addr[MSF2_NUM_UARTS] = { 0x4000 , 0x4001 };
+
+static const int spi_irq[MSF2_NUM_SPIS] = { 2, 3 };
+static const int uart_irq[MSF2_NUM_UARTS] = { 10, 11 };
+static const int timer_irq[MSF2_NUM_TIMERS] = { 14, 15 };
+
+static void m2sxxx_soc_initfn(Object *obj)
+{
+MSF2State *s = MSF2_SOC(obj);
+int i;
+
+object_initialize(&s->armv7m, sizeof(s->armv7m), TYPE_ARMV7M);
+qdev_set_parent_bus(DEVICE(&s->armv7m), sysbus_get_default());
+
+object_initialize(&s->sysreg, sizeof(s->sysreg), TYPE_MSF2_SYSREG);
+qdev_set_parent_bus(DEVICE(&s->sysreg), sysbus_get_default());
+
+object_initialize(&s->timer, sizeof(s->timer), TYPE_MSS_TIMER);
+qdev_set_parent_bus(DEVICE(&s->timer), sysbus_get_default());
+
+for (i = 0; i < MSF2_NUM_SPIS; i++) {
+object_initialize(&s->spi[i], sizeof(s->spi[i]),
+  TYPE_MSS_SPI);
+qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default());
+}
+}
+
+static void m2sxxx_soc_realize(DeviceState *dev_soc, Error **errp)
+{
+MSF2State *s = MSF2_SOC(dev_soc);
+DeviceState *dev, *armv7m;
+SysBusDevice *busdev;
+Error *err = NULL;
+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);
+
+memory_region_init_ram(nvm, NULL, "MSF2.eNVM", s->envm_size,
+   &error_fatal);
+
+/*
+ * On power-on, the eNVM region 0x6000 is automatically
+ * remapped to the Cortex-M3 processor executable r

[Qemu-devel] [Qemu devel v6 PATCH 3/5] msf2: Add Smartfusion2 SPI controller

2017-07-02 Thread Subbaraya Sundeep
Modelled Microsemi's Smartfusion2 SPI controller.

Signed-off-by: Subbaraya Sundeep 
---
 hw/ssi/Makefile.objs |   1 +
 hw/ssi/mss-spi.c | 414 +++
 include/hw/ssi/mss-spi.h |  62 +++
 3 files changed, 477 insertions(+)
 create mode 100644 hw/ssi/mss-spi.c
 create mode 100644 include/hw/ssi/mss-spi.h

diff --git a/hw/ssi/Makefile.objs b/hw/ssi/Makefile.objs
index 487add2..f5bcc65 100644
--- a/hw/ssi/Makefile.objs
+++ b/hw/ssi/Makefile.objs
@@ -4,6 +4,7 @@ common-obj-$(CONFIG_XILINX_SPI) += xilinx_spi.o
 common-obj-$(CONFIG_XILINX_SPIPS) += xilinx_spips.o
 common-obj-$(CONFIG_ASPEED_SOC) += aspeed_smc.o
 common-obj-$(CONFIG_STM32F2XX_SPI) += stm32f2xx_spi.o
+common-obj-$(CONFIG_MSF2) += mss-spi.o
 
 obj-$(CONFIG_OMAP) += omap_spi.o
 obj-$(CONFIG_IMX) += imx_spi.o
diff --git a/hw/ssi/mss-spi.c b/hw/ssi/mss-spi.c
new file mode 100644
index 000..a572abc
--- /dev/null
+++ b/hw/ssi/mss-spi.c
@@ -0,0 +1,414 @@
+/*
+ * Block model of SPI controller present in
+ * Microsemi's SmartFusion2 and SmartFusion SoCs.
+ *
+ * Copyright (C) 2017 Subbaraya Sundeep 
+ *
+ * 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/ssi/mss-spi.h"
+
+#ifndef MSS_SPI_ERR_DEBUG
+#define MSS_SPI_ERR_DEBUG   0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+if (MSS_SPI_ERR_DEBUG >= lvl) { \
+qemu_log("%s: " fmt "\n", __func__, ## args); \
+} \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+#define FIFO_CAPACITY 32
+#define FIFO_CAPACITY 32
+
+#define R_SPI_CONTROL 0
+#define R_SPI_DFSIZE  1
+#define R_SPI_STATUS  2
+#define R_SPI_INTCLR  3
+#define R_SPI_RX  4
+#define R_SPI_TX  5
+#define R_SPI_CLKGEN  6
+#define R_SPI_SS  7
+#define R_SPI_MIS 8
+#define R_SPI_RIS 9
+
+#define S_TXDONE (1 << 0)
+#define S_RXRDY  (1 << 1)
+#define S_RXCHOVRF   (1 << 2)
+#define S_RXFIFOFUL  (1 << 4)
+#define S_RXFIFOFULNXT   (1 << 5)
+#define S_RXFIFOEMP  (1 << 6)
+#define S_RXFIFOEMPNXT   (1 << 7)
+#define S_TXFIFOFUL  (1 << 8)
+#define S_TXFIFOFULNXT   (1 << 9)
+#define S_TXFIFOEMP  (1 << 10)
+#define S_TXFIFOEMPNXT   (1 << 11)
+#define S_FRAMESTART (1 << 12)
+#define S_SSEL   (1 << 13)
+#define S_ACTIVE (1 << 14)
+
+#define C_ENABLE (1 << 0)
+#define C_MODE   (1 << 1)
+#define C_INTRXDATA  (1 << 4)
+#define C_INTTXDATA  (1 << 5)
+#define C_INTRXOVRFLO(1 << 6)
+#define C_SPS(1 << 26)
+#define C_BIGFIFO(1 << 29)
+#define C_RESET  (1 << 31)
+
+#define FRAMESZ_MASK 0x1F
+#define FMCOUNT_MASK 0x0000
+#define FMCOUNT_SHIFT8
+
+static void txfifo_reset(MSSSpiState *s)
+{
+fifo32_reset(&s->tx_fifo);
+
+s->regs[R_SPI_STATUS] &= ~S_TXFIFOFUL;
+s->regs[R_SPI_STATUS] |= S_TXFIFOEMP;
+}
+
+static void rxfifo_reset(MSSSpiState *s)
+{
+fifo32_reset(&s->rx_fifo);
+
+s->regs[R_SPI_STATUS] &= ~S_RXFIFOFUL;
+s->regs[R_SPI_STATUS] |= S_RXFIFOEMP;
+}
+
+static void set_fifodepth(MSSSpiState *s)
+{
+unsigned int size = s->regs[R_SPI_DFSIZE] & FRAMESZ_MASK;
+
+if (size <= 8) {
+s->fifo_depth = 32;
+} else if (size <= 16) {
+s->fifo_depth = 16;
+} else if (size <= 32) {
+s->fifo_depth = 8;
+} else {
+s->fifo_depth = 4;
+}
+}
+
+static void mss_spi_do_reset(MSSSpiState *s)
+{
+memset(s->regs, 0, sizeof s->regs);
+s->regs[R

[Qemu-devel] [Qemu devel v6 PATCH 0/5] Add support for Smartfusion2 SoC

2017-07-02 Thread Subbaraya Sundeep
Hi Qemu-devel,

I am trying to add Smartfusion2 SoC.
SoC is from Microsemi and System on Module(SOM)
board is from Emcraft systems. Smartfusion2 has hardened
Microcontroller(Cortex-M3)based Sub System and FPGA fabric.
At the moment only system timer, sysreg and SPI
controller are modelled.

Testing:
./arm-softmmu/qemu-system-arm -M smartfusion2-som -serial mon:stdio \
-kernel u-boot.bin -display none -drive file=spi.bin,if=mtd,format=raw

Binaries u-boot.bin and spi.bin are at:
https://github.com/Subbaraya-Sundeep/qemu-test-binaries.git

U-boot is from Emcraft with modified
- SPI driver not to use PDMA.
- ugly hack to pass dtb to kernel in r1.
@
https://github.com/Subbaraya-Sundeep/emcraft-uboot-sf2.git

Linux is 4.5 linux with Smartfusion2 SoC dts and clocksource
driver added by myself @
https://github.com/Subbaraya-Sundeep/linux.git

v6:
Moved some defines from header files to source files
Added properties m3clk, apb0div, apb0div1 properties
to soc.
Added properties apb0divisor, apb1divisor to sysreg
Update system_clock_source in msf2-soc.c
Changed machine name smartfusion2-som->emcraft-sf2

v5
As per Philippe comments:
Added abort in Sysreg if guest tries to remap memory
other than default mapping.
Use of CONFIG_MSF2 in Makefile for soc.c
Fixed incorrect logic in timer model.
Renamed msf2-timer.c -> mss-timer.c
msf2-spi.c -> mss-spi.c also type names
Renamed function msf2_init->emcraft_sf2_init in msf2-som.c
Added part-name,eNVM-size,eSRAM-size,pclk0 and pclk1
properties to soc.
Pass soc part-name,memory size and clock rate properties from som.
v4:
Fixed build failure by using PRIx macros.
v3:
Added SoC file and board file as per Alistair comments.
v2:
Added SPI controller so that u-boot loads kernel from spi flash.
v1:
Initial patch set with timer and sysreg

Thanks,
Sundeep

Subbaraya Sundeep (5):
  msf2: Add Smartfusion2 System timer
  msf2: Microsemi Smartfusion2 System Register block.
  msf2: Add Smartfusion2 SPI controller
  msf2: Add Smartfusion2 SoC.
  msf2: Add Emcraft's Smartfusion2 SOM kit.

 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   2 +
 hw/arm/msf2-soc.c   | 216 +
 hw/arm/msf2-som.c   |  94 +
 hw/misc/Makefile.objs   |   1 +
 hw/misc/msf2-sysreg.c   | 200 +++
 hw/ssi/Makefile.objs|   1 +
 hw/ssi/mss-spi.c| 415 
 hw/timer/Makefile.objs  |   1 +
 hw/timer/mss-timer.c| 261 +
 include/hw/arm/msf2-soc.h   |  67 +++
 include/hw/misc/msf2-sysreg.h   |  82 
 include/hw/ssi/mss-spi.h|  62 ++
 include/hw/timer/mss-timer.h|  67 +++
 14 files changed, 1470 insertions(+)
 create mode 100644 hw/arm/msf2-soc.c
 create mode 100644 hw/arm/msf2-som.c
 create mode 100644 hw/misc/msf2-sysreg.c
 create mode 100644 hw/ssi/mss-spi.c
 create mode 100644 hw/timer/mss-timer.c
 create mode 100644 include/hw/arm/msf2-soc.h
 create mode 100644 include/hw/misc/msf2-sysreg.h
 create mode 100644 include/hw/ssi/mss-spi.h
 create mode 100644 include/hw/timer/mss-timer.h

-- 
2.5.0




[Qemu-devel] [Qemu devel v6 PATCH 2/5] msf2: Microsemi Smartfusion2 System Register block.

2017-07-02 Thread Subbaraya Sundeep
Added Sytem register block of Smartfusion2.
This block has PLL registers which are accessed by guest.

Signed-off-by: Subbaraya Sundeep 
---
 hw/misc/Makefile.objs |   1 +
 hw/misc/msf2-sysreg.c | 200 ++
 include/hw/misc/msf2-sysreg.h |  82 +
 3 files changed, 283 insertions(+)
 create mode 100644 hw/misc/msf2-sysreg.c
 create mode 100644 include/hw/misc/msf2-sysreg.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index c8b4893..0f52354 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 000..64ee141
--- /dev/null
+++ b/hw/misc/msf2-sysreg.c
@@ -0,0 +1,200 @@
+/*
+ * System Register block model of Microsemi SmartFusion2.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep 
+ *
+ * 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 "hw/misc/msf2-sysreg.h"
+
+#ifndef MSF2_SYSREG_ERR_DEBUG
+#define MSF2_SYSREG_ERR_DEBUG  0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+if (MSF2_SYSREG_ERR_DEBUG >= lvl) { \
+qemu_log("%s: " fmt "\n", __func__, ## args); \
+} \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+static inline int msf2_divbits(uint32_t div)
+{
+int ret = 0;
+
+switch (div) {
+case 1:
+ret = 0;
+break;
+case 2:
+ret = 1;
+break;
+case 4:
+ret = 2;
+break;
+case 8:
+ret = 4;
+break;
+case 16:
+ret = 5;
+break;
+case 32:
+ret = 6;
+break;
+default:
+break;
+}
+
+return ret;
+}
+
+static void msf2_sysreg_reset(DeviceState *d)
+{
+MSF2SysregState *s = MSF2_SYSREG(d);
+
+DB_PRINT("RESET");
+
+s->regs[MSSDDR_PLL_STATUS_LOW_CR] = 0x021A2358;
+s->regs[MSSDDR_PLL_STATUS] = 0x3;
+s->regs[MSSDDR_FACC1_CR] = msf2_divbits(s->apb0div) << 5 |
+   msf2_divbits(s->apb1div) << 2;
+}
+
+static uint64_t msf2_sysreg_read(void *opaque, hwaddr offset,
+unsigned size)
+{
+MSF2SysregState *s = opaque;
+offset /= 4;
+uint32_t ret = 0;
+
+if (offset < ARRAY_SIZE(s->regs)) {
+ret = s->regs[offset];
+DB_PRINT("addr: 0x%08" HWADDR_PRIx " data: 0x%08" PRIx32,
+offset * 4, ret);
+} else {
+qemu_log_mask(LOG_GUEST_ERROR,
+"%s: Bad offset 0x%08" HWADDR_PRIx "\n", __func__,
+offset * 4);
+}
+
+return ret;
+}
+
+static void msf2_sysreg_write(void *opaque, hwaddr offset,
+  uint64_t val, unsigned size)
+{
+MSF2SysregState *s = (MSF2SysregState *)opaque;
+uint32_t newval = val;
+uint32_t oldval;
+
+DB_PRINT("addr: 0x%08" HWADDR_PRIx " data: 0x%08" PRIx64,
+offset, val);
+
+offset /= 4;
+
+switch (offset) {
+case MSSDDR_PLL_STATUS:
+break;
+
+case ESRAM_CR:
+oldval = s->regs[ESRAM_CR];
+if (oldval ^ newval) {
+qemu_log_mask(LOG_GUEST_ERROR,
+   TYPE_MSF2_SYSREG": eSRAM remapping not supported\n");
+abort();
+}
+break;
+
+case DDR_CR:
+oldval = s->regs[DDR_CR];
+if (oldval ^ newval) {
+qemu_log_mask(LOG_GUEST_ERROR,
+   TYPE_MSF2_SYSREG": DDR remapping not supported\n");
+abort();
+}
+break;
+
+case ENVM_REMAP_BASE_CR:
+oldval = s->regs[ENVM_REMAP_BASE_CR];
+if (oldval ^ newval) {
+qemu_log_mask(LOG_GUEST_ERROR,
+   TYPE_MSF2_SYSREG": eNVM remapping not supported\n");
+abort();
+}
+break;
+
+default:
+if (offset < ARRAY_SIZE(s->regs)) {
+s->regs[offset] = val;
+} else {
+qemu_log_mask(LOG_GUEST_ERROR,
+"%s: Bad offset 0x%08" HWADDR_PRIx "\n", __func__,
+offset * 4);
+}
+break;
+}
+}
+
+static const MemoryRegionOps sysreg_ops = {
+.read = msf2_sysreg_read,
+.write = msf2_sysreg_write,
+

[Qemu-devel] [Qemu devel v6 PATCH 1/5] msf2: Add Smartfusion2 System timer

2017-07-02 Thread Subbaraya Sundeep
Modelled System Timer in Microsemi's Smartfusion2 Soc.
Timer has two 32bit down counters and two interrupts.

Signed-off-by: Subbaraya Sundeep 
---
 hw/timer/Makefile.objs   |   1 +
 hw/timer/mss-timer.c | 261 +++
 include/hw/timer/mss-timer.h |  67 +++
 3 files changed, 329 insertions(+)
 create mode 100644 hw/timer/mss-timer.c
 create mode 100644 include/hw/timer/mss-timer.h

diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index dd6f27e..fc4d2da 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) += mss-timer.o
diff --git a/hw/timer/mss-timer.c b/hw/timer/mss-timer.c
new file mode 100644
index 000..e46d118
--- /dev/null
+++ b/hw/timer/mss-timer.c
@@ -0,0 +1,261 @@
+/*
+ * Block model of System timer present in
+ * Microsemi's SmartFusion2 and SmartFusion SoCs.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep .
+ *
+ * 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/mss-timer.h"
+
+#ifndef MSS_TIMER_ERR_DEBUG
+#define MSS_TIMER_ERR_DEBUG  0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+if (MSS_TIMER_ERR_DEBUG >= lvl) { \
+qemu_log("%s: " fmt "\n", __func__, ## args); \
+} \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+#define R_TIM_VAL 0
+#define R_TIM_LOADVAL 1
+#define R_TIM_BGLOADVAL   2
+#define R_TIM_CTRL3
+#define R_TIM_RIS 4
+#define R_TIM_MIS 5
+
+#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)
+#define TIMER_MODE  (1 << 0)
+
+static void timer_update_irq(struct Msf2Timer *st)
+{
+bool isr, ier;
+
+isr = !!(st->regs[R_TIM_RIS] & TIMER_RIS_ACK);
+ier = !!(st->regs[R_TIM_CTRL] & TIMER_CTRL_INTR);
+qemu_set_irq(st->irq, (ier && isr));
+}
+
+static void timer_update(struct Msf2Timer *st)
+{
+uint64_t count;
+
+if (!(st->regs[R_TIM_CTRL] & TIMER_CTRL_ENBL)) {
+ptimer_stop(st->ptimer);
+return;
+}
+
+count = st->regs[R_TIM_LOADVAL];
+ptimer_set_limit(st->ptimer, count, 1);
+ptimer_run(st->ptimer, 1);
+}
+
+static uint64_t
+timer_read(void *opaque, hwaddr offset, unsigned int size)
+{
+MSSTimerState *t = opaque;
+hwaddr addr;
+struct Msf2Timer *st;
+uint32_t ret = 0;
+int timer = 0;
+int isr;
+int ier;
+
+addr = offset >> 2;
+/*
+ * Two independent timers has same base address.
+ * Based on address passed figure out which timer is being used.
+ */
+if ((addr >= R_TIM1_MAX) && (addr < NUM_TIMERS * R_TIM1_MAX)) {
+timer = 1;
+addr -= R_TIM1_MAX;
+}
+
+st = &t->timers[timer];
+
+switch (addr) {
+case R_TIM_VAL:
+ret = ptimer_get_count(st->ptimer);
+break;
+
+case R_TIM_MIS:
+isr = !!(st->regs[R_TIM_RIS] & TIMER_RIS_ACK);
+ier = !!(st->regs[R_TIM_CTRL] & TIMER_CTRL_INTR);
+ret = ier & isr;
+break;
+
+default:
+if (addr < NUM_TIMERS * R_TIM1_MAX) {
+ret = st->regs[addr];
+} else {
+qemu_log_mask(LOG_GUEST_ERROR,
+TYPE_MSS_TIMER": 64-bit mode not supported\n");
+}
+break;
+}
+
+DB_PRINT("timer=%d 0x%" HWADDR_PRIx "=0x%" PRIx32, timer, offset,
+ret);
+return ret;
+}
+
+static void
+timer_write(void *opaque, hwaddr offs

[Qemu-devel] [Qemu devel v5 PATCH 4/5] msf2: Add Smartfusion2 SoC.

2017-05-16 Thread Subbaraya Sundeep
Smartfusion2 SoC has hardened Microcontroller subsystem
and flash based FPGA fabric. This patch adds support for
Microcontroller subsystem in the SoC.

Signed-off-by: Subbaraya Sundeep 
---
 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/msf2-soc.c   | 201 
 include/hw/arm/msf2-soc.h   |  69 ++
 4 files changed, 272 insertions(+)
 create mode 100644 hw/arm/msf2-soc.c
 create mode 100644 include/hw/arm/msf2-soc.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 78d7af0..7062512 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -122,3 +122,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..c828061 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -18,3 +18,4 @@ obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
 obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
 obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o
+obj-$(CONFIG_MSF2) += msf2-soc.o
diff --git a/hw/arm/msf2-soc.c b/hw/arm/msf2-soc.c
new file mode 100644
index 000..329e30c
--- /dev/null
+++ b/hw/arm/msf2-soc.c
@@ -0,0 +1,201 @@
+/*
+ * SmartFusion2 SoC emulation.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep 
+ *
+ * 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/char/serial.h"
+#include "hw/boards.h"
+#include "sysemu/block-backend.h"
+#include "hw/arm/msf2-soc.h"
+
+#define MSF2_TIMER_BASE 0x40004000
+#define MSF2_SYSREG_BASE0x40038000
+
+#define MSF2_TIMER_IRQ0 14
+#define MSF2_TIMER_IRQ1 15
+
+static const uint32_t spi_addr[MSF2_NUM_SPIS] = { 0x40001000 , 0x40011000 };
+static const uint32_t uart_addr[MSF2_NUM_UARTS] = { 0x4000 , 0x4001 };
+
+static const int spi_irq[MSF2_NUM_SPIS] = { 2, 3 };
+static const int uart_irq[MSF2_NUM_UARTS] = { 10, 11 };
+
+static void m2sxxx_soc_initfn(Object *obj)
+{
+MSF2State *s = MSF2_SOC(obj);
+int i;
+
+object_initialize(&s->armv7m, sizeof(s->armv7m), TYPE_ARMV7M);
+qdev_set_parent_bus(DEVICE(&s->armv7m), sysbus_get_default());
+
+object_initialize(&s->sysreg, sizeof(s->sysreg), TYPE_MSF2_SYSREG);
+qdev_set_parent_bus(DEVICE(&s->sysreg), sysbus_get_default());
+
+object_initialize(&s->timer, sizeof(s->timer), TYPE_MSS_TIMER);
+qdev_set_parent_bus(DEVICE(&s->timer), sysbus_get_default());
+
+for (i = 0; i < MSF2_NUM_SPIS; i++) {
+object_initialize(&s->spi[i], sizeof(s->spi[i]),
+  TYPE_MSS_SPI);
+qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default());
+}
+}
+
+static void m2sxxx_soc_realize(DeviceState *dev_soc, Error **errp)
+{
+MSF2State *s = MSF2_SOC(dev_soc);
+DeviceState *dev, *armv7m;
+SysBusDevice *busdev;
+Error *err = NULL;
+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);
+
+memory_region_init_ram(nvm, NULL, "MSF2.eNVM", s->envm_size,
+   &error_fatal);
+
+/*
+ * On power-on, the eNVM region 0x6000 is automatically
+ * remapped to the Cortex-M3 processor executable region
+ * start address (0x0). We do not support remapping other eNVM,
+ * eSRAM and DDR regions by guest(via Sysreg) currently.
+ */
+  

[Qemu-devel] [Qemu devel v5 PATCH 3/5] msf2: Add Smartfusion2 SPI controller

2017-05-16 Thread Subbaraya Sundeep
Modelled Microsemi's Smartfusion2 SPI controller.

Signed-off-by: Subbaraya Sundeep 
---
 hw/ssi/Makefile.objs |   1 +
 hw/ssi/mss-spi.c | 378 +++
 include/hw/ssi/mss-spi.h | 104 +
 3 files changed, 483 insertions(+)
 create mode 100644 hw/ssi/mss-spi.c
 create mode 100644 include/hw/ssi/mss-spi.h

diff --git a/hw/ssi/Makefile.objs b/hw/ssi/Makefile.objs
index 487add2..f5bcc65 100644
--- a/hw/ssi/Makefile.objs
+++ b/hw/ssi/Makefile.objs
@@ -4,6 +4,7 @@ common-obj-$(CONFIG_XILINX_SPI) += xilinx_spi.o
 common-obj-$(CONFIG_XILINX_SPIPS) += xilinx_spips.o
 common-obj-$(CONFIG_ASPEED_SOC) += aspeed_smc.o
 common-obj-$(CONFIG_STM32F2XX_SPI) += stm32f2xx_spi.o
+common-obj-$(CONFIG_MSF2) += mss-spi.o
 
 obj-$(CONFIG_OMAP) += omap_spi.o
 obj-$(CONFIG_IMX) += imx_spi.o
diff --git a/hw/ssi/mss-spi.c b/hw/ssi/mss-spi.c
new file mode 100644
index 000..0b88ec9
--- /dev/null
+++ b/hw/ssi/mss-spi.c
@@ -0,0 +1,378 @@
+/*
+ * Block model of SPI controller present in
+ * Microsemi's SmartFusion2 and SmartFusion SoCs.
+ *
+ * Copyright (C) 2017 Subbaraya Sundeep 
+ *
+ * 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/ssi/mss-spi.h"
+
+#ifndef MSS_SPI_ERR_DEBUG
+#define MSS_SPI_ERR_DEBUG   0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+if (MSS_SPI_ERR_DEBUG >= lvl) { \
+qemu_log("%s: " fmt, __func__, ## args); \
+} \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+static void txfifo_reset(MSSSpiState *s)
+{
+fifo32_reset(&s->tx_fifo);
+
+s->regs[R_SPI_STATUS] &= ~S_TXFIFOFUL;
+s->regs[R_SPI_STATUS] |= S_TXFIFOEMP;
+}
+
+static void rxfifo_reset(MSSSpiState *s)
+{
+fifo32_reset(&s->rx_fifo);
+
+s->regs[R_SPI_STATUS] &= ~S_RXFIFOFUL;
+s->regs[R_SPI_STATUS] |= S_RXFIFOEMP;
+}
+
+static void set_fifodepth(MSSSpiState *s)
+{
+int size = s->regs[R_SPI_DFSIZE] & FRAMESZ_MASK;
+
+if (0 <= size && size <= 8) {
+s->fifo_depth = 32;
+}
+if (9 <= size && size <= 16) {
+s->fifo_depth = 16;
+}
+if (17 <= size && size <= 32) {
+s->fifo_depth = 8;
+}
+}
+
+static void mss_spi_do_reset(MSSSpiState *s)
+{
+memset(s->regs, 0, sizeof s->regs);
+s->regs[R_SPI_CONTROL] = 0x8102;
+s->regs[R_SPI_DFSIZE] = 0x4;
+s->regs[R_SPI_STATUS] = 0x2440;
+s->regs[R_SPI_CLKGEN] = 0x7;
+s->regs[R_SPI_RIS] = 0x0;
+
+s->fifo_depth = 4;
+s->frame_count = 1;
+s->enabled = false;
+
+rxfifo_reset(s);
+txfifo_reset(s);
+}
+
+static void update_mis(MSSSpiState *s)
+{
+uint32_t reg = s->regs[R_SPI_CONTROL];
+uint32_t tmp;
+
+/*
+ * form the Control register interrupt enable bits
+ * same as RIS, MIS and Interrupt clear registers for simplicity
+ */
+tmp = ((reg & C_INTRXOVRFLO) >> 4) | ((reg & C_INTRXDATA) >> 3) |
+   ((reg & C_INTTXDATA) >> 5);
+s->regs[R_SPI_MIS] |= tmp & s->regs[R_SPI_RIS];
+}
+
+static void spi_update_irq(MSSSpiState *s)
+{
+int irq;
+
+update_mis(s);
+irq = !!(s->regs[R_SPI_MIS]);
+
+qemu_set_irq(s->irq, irq);
+}
+
+static void mss_spi_reset(DeviceState *d)
+{
+mss_spi_do_reset(MSS_SPI(d));
+}
+
+static uint64_t
+spi_read(void *opaque, hwaddr addr, unsigned int size)
+{
+MSSSpiState *s = opaque;
+uint32_t ret = 0;
+
+addr >>= 2;
+switch (addr) {
+case R_SPI_RX:
+s->regs[R_SPI_STATUS] &= ~S_RXFIFOFUL;
+s->regs[R_SPI_STATUS] &= ~RXCHOVRF;
+ret = fifo32_pop(&s->rx_fifo);
+if (fifo32_is_empty(&s->rx_fifo)) {
+s->regs[R_SPI_STATUS] |= S_RXFIFOEMP;
+}
+ 

[Qemu-devel] [Qemu devel v5 PATCH 2/5] msf2: Microsemi Smartfusion2 System Register block.

2017-05-16 Thread Subbaraya Sundeep
Added Sytem register block of Smartfusion2.
This block has PLL registers which are accessed by guest.

Signed-off-by: Subbaraya Sundeep 
---
 hw/misc/Makefile.objs |   1 +
 hw/misc/msf2-sysreg.c | 161 ++
 include/hw/misc/msf2-sysreg.h |  80 +
 3 files changed, 242 insertions(+)
 create mode 100644 hw/misc/msf2-sysreg.c
 create mode 100644 include/hw/misc/msf2-sysreg.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index c8b4893..0f52354 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 000..8d3118f
--- /dev/null
+++ b/hw/misc/msf2-sysreg.c
@@ -0,0 +1,161 @@
+/*
+ * System Register block model of Microsemi SmartFusion2.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep 
+ *
+ * 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 "hw/misc/msf2-sysreg.h"
+
+#ifndef MSF2_SYSREG_ERR_DEBUG
+#define MSF2_SYSREG_ERR_DEBUG  0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+if (MSF2_SYSREG_ERR_DEBUG >= lvl) { \
+qemu_log("%s: " fmt, __func__, ## args); \
+} \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+static void msf2_sysreg_reset(DeviceState *d)
+{
+MSF2SysregState *s = MSF2_SYSREG(d);
+
+DB_PRINT("RESET\n");
+
+s->regs[MSSDDR_PLL_STATUS_LOW_CR] = 0x021A2358;
+s->regs[MSSDDR_FACC1_CR] = 0x0B800124;
+s->regs[MSSDDR_PLL_STATUS] = 0x3;
+}
+
+static uint64_t msf2_sysreg_read(void *opaque, hwaddr offset,
+unsigned size)
+{
+MSF2SysregState *s = opaque;
+offset /= 4;
+uint32_t ret = 0;
+
+if (offset < ARRAY_SIZE(s->regs)) {
+ret = s->regs[offset];
+DB_PRINT("addr: 0x%08" HWADDR_PRIx " data: 0x%08" PRIx32 "\n",
+offset * 4, ret);
+} else {
+qemu_log_mask(LOG_GUEST_ERROR,
+"%s: Bad offset 0x%08" HWADDR_PRIx "\n", __func__,
+offset * 4);
+}
+
+return ret;
+}
+
+static void msf2_sysreg_write(void *opaque, hwaddr offset,
+  uint64_t val, unsigned size)
+{
+MSF2SysregState *s = (MSF2SysregState *)opaque;
+uint32_t newval = val;
+uint32_t oldval;
+
+offset /= 4;
+
+DB_PRINT("addr: 0x%08" HWADDR_PRIx " data: 0x%08" PRIx64 "\n",
+offset * 4, val);
+
+switch (offset) {
+case MSSDDR_PLL_STATUS:
+break;
+
+case ESRAM_CR:
+oldval = s->regs[ESRAM_CR];
+if (oldval ^ newval) {
+qemu_log_mask(LOG_GUEST_ERROR,
+   TYPE_MSF2_SYSREG": eSRAM remapping not supported\n");
+abort();
+}
+break;
+
+case DDR_CR:
+oldval = s->regs[DDR_CR];
+if (oldval ^ newval) {
+qemu_log_mask(LOG_GUEST_ERROR,
+   TYPE_MSF2_SYSREG": DDR remapping not supported\n");
+abort();
+}
+break;
+
+case ENVM_REMAP_BASE_CR:
+oldval = s->regs[ENVM_REMAP_BASE_CR];
+if (oldval ^ newval) {
+qemu_log_mask(LOG_GUEST_ERROR,
+   TYPE_MSF2_SYSREG": eNVM remapping not supported\n");
+abort();
+}
+break;
+
+default:
+if (offset < ARRAY_SIZE(s->regs)) {
+s->regs[offset] = val;
+} else {
+qemu_log_mask(LOG_GUEST_ERROR,
+"%s: Bad offset 0x%08" HWADDR_PRIx "\n", __func__,
+offset * 4);
+}
+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)
+{
+MSF2SysregState *s = MSF2_SYSREG(obj);
+
+memory_region_init_io(&s->iomem, obj, &sysreg_ops, s, TYPE_MSF2_SYSREG,
+  MSF2_SYSREG_MMIO_SIZE);
+sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
+}
+
+static const VMStateDescription vmstate_msf2_sysreg = {
+.name = TYPE_MSF2_SYSREG,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+  

[Qemu-devel] [Qemu devel v5 PATCH 5/5] msf2: Add Emcraft's Smartfusion2 SOM kit.

2017-05-16 Thread Subbaraya Sundeep
Emulated Emcraft's Smartfusion2 System On Module starter
kit.

Signed-off-by: Subbaraya Sundeep 
---
 hw/arm/Makefile.objs |  1 +
 hw/arm/msf2-som.c| 89 
 2 files changed, 90 insertions(+)
 create mode 100644 hw/arm/msf2-som.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index c828061..4b02093 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -5,6 +5,7 @@ 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-$(CONFIG_ACPI) += virt-acpi-build.o
 obj-y += netduino2.o
+obj-y += msf2-som.o
 obj-y += sysbus-fdt.o
 
 obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
diff --git a/hw/arm/msf2-som.c b/hw/arm/msf2-som.c
new file mode 100644
index 000..cd2b759
--- /dev/null
+++ b/hw/arm/msf2-som.c
@@ -0,0 +1,89 @@
+/*
+ * SmartFusion2 SOM starter kit(from Emcraft) emulation.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/boards.h"
+#include "hw/arm/msf2-soc.h"
+#include "hw/arm/arm.h"
+#include "exec/address-spaces.h"
+
+#define DDR_BASE_ADDRESS  0xA000
+#define DDR_SIZE  (64 * M_BYTE)
+
+static void emcraft_sf2_init(MachineState *machine)
+{
+DeviceState *dev;
+DeviceState *spi_flash;
+MSF2State *soc;
+DriveInfo *dinfo = drive_get_next(IF_MTD);
+qemu_irq cs_line;
+SSIBus *spi_bus;
+MemoryRegion *sysmem = get_system_memory();
+MemoryRegion *ddr = g_new(MemoryRegion, 1);
+
+memory_region_init_ram(ddr, NULL, "ddr-ram", DDR_SIZE,
+   &error_fatal);
+vmstate_register_ram_global(ddr);
+memory_region_add_subregion(sysmem, DDR_BASE_ADDRESS, ddr);
+
+dev = qdev_create(NULL, TYPE_MSF2_SOC);
+qdev_prop_set_string(dev, "part-name", "M2S010");
+qdev_prop_set_uint64(dev, "eNVM-size", M2S010_ENVM_SIZE);
+qdev_prop_set_uint64(dev, "eSRAM-size", M2S010_ESRAM_SIZE);
+
+/*
+ * pclk0 and pclk1 are configurable in Libero.
+ * Emcraft's SoM kit comes with these settings by default.
+ */
+qdev_prop_set_uint32(dev, "pclk0", 71 * 100);
+qdev_prop_set_uint32(dev, "pclk1", 71 * 100);
+
+object_property_set_bool(OBJECT(dev), true, "realized", &error_fatal);
+
+soc = MSF2_SOC(dev);
+
+/* Attach SPI flash to SPI0 controller */
+spi_bus = (SSIBus *)qdev_get_child_bus(dev, "spi0");
+spi_flash = ssi_create_slave_no_init(spi_bus, "s25sl12801");
+qdev_prop_set_uint8(spi_flash, "spansion-cr2nv", 1);
+if (dinfo) {
+qdev_prop_set_drive(spi_flash, "drive", blk_by_legacy_dinfo(dinfo),
+&error_fatal);
+}
+qdev_init_nofail(spi_flash);
+cs_line = qdev_get_gpio_in_named(spi_flash, SSI_GPIO_CS, 0);
+sysbus_connect_irq(SYS_BUS_DEVICE(&soc->spi[0]), 1, cs_line);
+
+armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
+   soc->envm_size);
+}
+
+static void emcraft_sf2_machine_init(MachineClass *mc)
+{
+mc->desc = "SmartFusion2 SOM kit from Emcraft";
+mc->init = emcraft_sf2_init;
+}
+
+DEFINE_MACHINE("smartfusion2-som", emcraft_sf2_machine_init)
-- 
2.5.0




[Qemu-devel] [Qemu devel v5 PATCH 0/5] Add support for Smartfusion2 SoC

2017-05-16 Thread Subbaraya Sundeep
Hi Qemu-devel,

I am trying to add Smartfusion2 SoC.
SoC is from Microsemi and System on Module(SOM)
board is from Emcraft systems. Smartfusion2 has hardened
Microcontroller(Cortex-M3)based Sub System and FPGA fabric.
At the moment only system timer, sysreg and SPI
controller are modelled.

Testing:
./arm-softmmu/qemu-system-arm -M smartfusion2-som -serial mon:stdio \
-kernel u-boot.bin -display none -drive file=spi.bin,if=mtd,format=raw

Binaries u-boot.bin and spi.bin are at:
https://github.com/Subbaraya-Sundeep/qemu-test-binaries.git

U-boot is from Emcraft with modified
- SPI driver not to use PDMA.
- ugly hack to pass dtb to kernel in r1.
@
https://github.com/Subbaraya-Sundeep/emcraft-uboot-sf2.git

Linux is 4.5 linux with Smartfusion2 SoC dts and clocksource
driver added by myself @
https://github.com/Subbaraya-Sundeep/linux.git

v5
As per Philippe comments:
Added abort in Sysreg if guest tries to remap memory
other than default mapping.
Use of CONFIG_MSF2 in Makefile for soc.c
Fixed incorrect logic in timer model.
Renamed msf2-timer.c -> mss-timer.c
msf2-spi.c -> mss-spi.c also type names
Renamed function msf2_init->emcraft_sf2_init in msf2-som.c
Added part-name,eNVM-size,eSRAM-size,pclk0 and pclk1
properties to soc.
Pass soc part-name,memory size and clock rate properties from som.
v4:
Fixed build failure by using PRIx macros.
v3:
Added SoC file and board file as per Alistair comments.
v2:
Added SPI controller so that u-boot loads kernel from spi flash.
v1:
Initial patch set with timer and sysreg

Thanks,
Sundeep

Subbaraya Sundeep (5):
  msf2: Add Smartfusion2 System timer
  msf2: Microsemi Smartfusion2 System Register block.
  msf2: Add Smartfusion2 SPI controller
  msf2: Add Smartfusion2 SoC.
  msf2: Add Emcraft's Smartfusion2 SOM kit.

 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   2 +
 hw/arm/msf2-soc.c   | 201 +
 hw/arm/msf2-som.c   |  89 ++
 hw/misc/Makefile.objs   |   1 +
 hw/misc/msf2-sysreg.c   | 161 +
 hw/ssi/Makefile.objs|   1 +
 hw/ssi/mss-spi.c| 378 
 hw/timer/Makefile.objs  |   1 +
 hw/timer/mss-timer.c| 249 ++
 include/hw/arm/msf2-soc.h   |  69 
 include/hw/misc/msf2-sysreg.h   |  80 +
 include/hw/ssi/mss-spi.h| 104 +++
 include/hw/timer/mss-timer.h|  80 +
 14 files changed, 1417 insertions(+)
 create mode 100644 hw/arm/msf2-soc.c
 create mode 100644 hw/arm/msf2-som.c
 create mode 100644 hw/misc/msf2-sysreg.c
 create mode 100644 hw/ssi/mss-spi.c
 create mode 100644 hw/timer/mss-timer.c
 create mode 100644 include/hw/arm/msf2-soc.h
 create mode 100644 include/hw/misc/msf2-sysreg.h
 create mode 100644 include/hw/ssi/mss-spi.h
 create mode 100644 include/hw/timer/mss-timer.h

-- 
2.5.0




[Qemu-devel] [Qemu devel v5 PATCH 1/5] msf2: Add Smartfusion2 System timer

2017-05-16 Thread Subbaraya Sundeep
Modelled System Timer in Microsemi's Smartfusion2 Soc.
Timer has two 32bit down counters and two interrupts.

Signed-off-by: Subbaraya Sundeep 
---
 hw/timer/Makefile.objs   |   1 +
 hw/timer/mss-timer.c | 249 +++
 include/hw/timer/mss-timer.h |  80 ++
 3 files changed, 330 insertions(+)
 create mode 100644 hw/timer/mss-timer.c
 create mode 100644 include/hw/timer/mss-timer.h

diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index dd6f27e..fc4d2da 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) += mss-timer.o
diff --git a/hw/timer/mss-timer.c b/hw/timer/mss-timer.c
new file mode 100644
index 000..7041965
--- /dev/null
+++ b/hw/timer/mss-timer.c
@@ -0,0 +1,249 @@
+/*
+ * Block model of System timer present in
+ * Microsemi's SmartFusion2 and SmartFusion SoCs.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep .
+ *
+ * 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/mss-timer.h"
+
+#ifndef MSS_TIMER_ERR_DEBUG
+#define MSS_TIMER_ERR_DEBUG  0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+if (MSS_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 timer_update_irq(struct Msf2Timer *st)
+{
+bool isr, ier;
+
+isr = !!(st->regs[R_TIM_RIS] & TIMER_RIS_ACK);
+ier = !!(st->regs[R_TIM_CTRL] & TIMER_CTRL_INTR);
+
+qemu_set_irq(st->irq, (ier && isr));
+}
+
+static void timer_update(struct Msf2Timer *st)
+{
+uint64_t count;
+
+if (!(st->regs[R_TIM_CTRL] & TIMER_CTRL_ENBL)) {
+ptimer_stop(st->ptimer);
+return;
+}
+
+count = st->regs[R_TIM_LOADVAL];
+ptimer_set_limit(st->ptimer, count, 1);
+ptimer_run(st->ptimer, 1);
+}
+
+static uint64_t
+timer_read(void *opaque, hwaddr offset, unsigned int size)
+{
+MSSTimerState *t = opaque;
+hwaddr addr;
+struct Msf2Timer *st;
+uint32_t ret = 0;
+int timer = 0;
+int isr;
+int ier;
+
+addr = offset >> 2;
+/*
+ * Two independent timers has same base address.
+ * Based on address passed figure out which timer is being used.
+ */
+if ((addr >= R_TIM1_MAX) && (addr < NUM_TIMERS * R_TIM1_MAX)) {
+timer = 1;
+addr -= R_TIM1_MAX;
+}
+
+st = &t->timers[timer];
+
+switch (addr) {
+case R_TIM_VAL:
+ret = ptimer_get_count(st->ptimer);
+break;
+
+case R_TIM_MIS:
+isr = !!(st->regs[R_TIM_RIS] & TIMER_RIS_ACK);
+ier = !!(st->regs[R_TIM_CTRL] & TIMER_CTRL_INTR);
+ret = ier & isr;
+break;
+
+default:
+if (addr < NUM_TIMERS * R_TIM1_MAX) {
+ret = st->regs[addr];
+} else {
+qemu_log_mask(LOG_GUEST_ERROR,
+TYPE_MSS_TIMER": 64-bit mode not supported\n");
+}
+break;
+}
+
+DB_PRINT("timer=%d 0x%" HWADDR_PRIx "=0x%" PRIx32 "\n", timer, offset,
+ret);
+return ret;
+}
+
+static void
+timer_write(void *opaque, hwaddr offset,
+uint64_t val64, unsigned int size)
+{
+MSSTimerState *t = opaque;
+hwaddr addr;
+struct Msf2Timer *st;
+int timer = 0;
+uint32_t value = val64;
+
+addr = offset >> 2;
+/*
+ * Two independent timers has same base address.
+ * Based on addr passed figure out which timer is being used.
+ */
+if ((addr >= R_TIM1_MAX) && (addr < NUM_TIMERS * R_TIM1_MAX)) {
+

[Qemu-devel] [Qemu-devel PATCH 4/5] msf2: Add Smartfusion2 SoC.

2017-05-09 Thread Subbaraya Sundeep
Smartfusion2 SoC has hardened Microcontroller subsystem
and flash based FPGA fabric. This patch adds support for
Microcontroller subsystem in the SoC.

Signed-off-by: Subbaraya Sundeep 
---
 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   2 +-
 hw/arm/msf2-soc.c   | 188 
 include/hw/arm/msf2-soc.h   |  60 +
 4 files changed, 250 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/msf2-soc.c
 create mode 100644 include/hw/arm/msf2-soc.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 78d7af0..7062512 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -122,3 +122,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..ae5e4a3 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 000..d6341a2
--- /dev/null
+++ b/hw/arm/msf2-soc.c
@@ -0,0 +1,188 @@
+/*
+ * SmartFusion2 SoC emulation.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep 
+ *
+ * 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/char/serial.h"
+#include "hw/boards.h"
+#include "sysemu/block-backend.h"
+#include "hw/arm/msf2-soc.h"
+
+#define MSF2_TIMER_BASE   0x40004000
+#define MSF2_SYSREG_BASE  0x40038000
+
+#define MSF2_TIMER_IRQ0   14
+#define MSF2_TIMER_IRQ1   15
+
+static const uint32_t spi_addr[MSF2_NUM_SPIS] = { 0x40001000 , 0x40011000 };
+static const uint32_t uart_addr[MSF2_NUM_UARTS] = { 0x4000 , 0x4001 };
+
+static const int spi_irq[MSF2_NUM_SPIS] = { 2, 3 };
+static const int uart_irq[MSF2_NUM_UARTS] = { 10, 11 };
+
+static void msf2_soc_initfn(Object *obj)
+{
+MSF2State *s = MSF2_SOC(obj);
+int i;
+
+object_initialize(&s->armv7m, sizeof(s->armv7m), TYPE_ARMV7M);
+qdev_set_parent_bus(DEVICE(&s->armv7m), sysbus_get_default());
+
+object_initialize(&s->sysreg, sizeof(s->sysreg), TYPE_MSF2_SYSREG);
+qdev_set_parent_bus(DEVICE(&s->sysreg), sysbus_get_default());
+
+object_initialize(&s->timer, sizeof(s->timer), TYPE_MSF2_TIMER);
+qdev_set_parent_bus(DEVICE(&s->timer), sysbus_get_default());
+
+for (i = 0; i < MSF2_NUM_SPIS; i++) {
+object_initialize(&s->spi[i], sizeof(s->spi[i]),
+  TYPE_MSF2_SPI);
+qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default());
+}
+}
+
+static void msf2_soc_realize(DeviceState *dev_soc, Error **errp)
+{
+MSF2State *s = MSF2_SOC(dev_soc);
+DeviceState *dev, *armv7m;
+SysBusDevice *busdev;
+Error *err = NULL;
+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);
+
+memory_region_init_ram(nvm, NULL, "MSF2.envm", ENVM_SIZE,
+   &error_fatal);
+memory_region_init_alias(nvm_alias, NULL, "M

[Qemu-devel] [Qemu-devel PATCH 5/5] msf2: Add Emcraft's Smartfusion2 SOM kit.

2017-05-09 Thread Subbaraya Sundeep
Emulated Emcraft's Smartfusion2 System On Module starter
kit.

Signed-off-by: Subbaraya Sundeep 
---
 hw/arm/Makefile.objs |  1 +
 hw/arm/msf2-som.c| 67 
 2 files changed, 68 insertions(+)
 create mode 100644 hw/arm/msf2-som.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index ae5e4a3..b626a43 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -5,6 +5,7 @@ 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
+obj-y += msf2-som.o
 obj-y += sysbus-fdt.o
 
 obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
diff --git a/hw/arm/msf2-som.c b/hw/arm/msf2-som.c
new file mode 100644
index 000..bc44169
--- /dev/null
+++ b/hw/arm/msf2-som.c
@@ -0,0 +1,67 @@
+/*
+ * SmartFusion2 SOM starter kit(from Emcraft) emulation.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/boards.h"
+#include "hw/arm/msf2-soc.h"
+#include "hw/arm/arm.h"
+
+static void msf2_init(MachineState *machine)
+{
+DeviceState *dev;
+DeviceState *spi_flash;
+MSF2State *soc;
+DriveInfo *dinfo = drive_get_next(IF_MTD);
+qemu_irq cs_line;
+SSIBus *spi_bus;
+
+dev = qdev_create(NULL, TYPE_MSF2_SOC);
+object_property_set_bool(OBJECT(dev), true, "realized", &error_fatal);
+
+soc = MSF2_SOC(dev);
+
+/* Attach SPI flash to SPI0 controller */
+spi_bus = (SSIBus *)qdev_get_child_bus(dev, "spi0");
+spi_flash = ssi_create_slave_no_init(spi_bus, "s25sl12801");
+qdev_prop_set_uint8(spi_flash, "spansion-cr2nv", 1);
+if (dinfo) {
+qdev_prop_set_drive(spi_flash, "drive", blk_by_legacy_dinfo(dinfo),
+&error_fatal);
+}
+qdev_init_nofail(spi_flash);
+cs_line = qdev_get_gpio_in_named(spi_flash, SSI_GPIO_CS, 0);
+sysbus_connect_irq(SYS_BUS_DEVICE(&soc->spi[0]), 1, cs_line);
+
+armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
+   ENVM_SIZE);
+}
+
+static void msf2_machine_init(MachineClass *mc)
+{
+mc->desc = "SmartFusion2 SOM kit from Emcraft";
+mc->init = msf2_init;
+}
+
+DEFINE_MACHINE("smartfusion2-som", msf2_machine_init)
-- 
2.5.0




[Qemu-devel] [Qemu-devel PATCH 3/5] msf2: Add Smartfusion2 SPI controller

2017-05-09 Thread Subbaraya Sundeep
Modelled Microsemi's Smartfusion2 SPI controller.

Signed-off-by: Subbaraya Sundeep 
---
 hw/ssi/Makefile.objs  |   1 +
 hw/ssi/msf2-spi.c | 378 ++
 include/hw/ssi/msf2-spi.h | 105 +
 3 files changed, 484 insertions(+)
 create mode 100644 hw/ssi/msf2-spi.c
 create mode 100644 include/hw/ssi/msf2-spi.h

diff --git a/hw/ssi/Makefile.objs b/hw/ssi/Makefile.objs
index 487add2..3105c4b 100644
--- a/hw/ssi/Makefile.objs
+++ b/hw/ssi/Makefile.objs
@@ -4,6 +4,7 @@ common-obj-$(CONFIG_XILINX_SPI) += xilinx_spi.o
 common-obj-$(CONFIG_XILINX_SPIPS) += xilinx_spips.o
 common-obj-$(CONFIG_ASPEED_SOC) += aspeed_smc.o
 common-obj-$(CONFIG_STM32F2XX_SPI) += stm32f2xx_spi.o
+common-obj-$(CONFIG_MSF2) += msf2-spi.o
 
 obj-$(CONFIG_OMAP) += omap_spi.o
 obj-$(CONFIG_IMX) += imx_spi.o
diff --git a/hw/ssi/msf2-spi.c b/hw/ssi/msf2-spi.c
new file mode 100644
index 000..2059ed9
--- /dev/null
+++ b/hw/ssi/msf2-spi.c
@@ -0,0 +1,378 @@
+/*
+ * SPI controller model of Microsemi SmartFusion2.
+ *
+ * Copyright (C) 2017 Subbaraya Sundeep 
+ *
+ * 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/ssi/msf2-spi.h"
+
+#ifndef MSF2_SPI_ERR_DEBUG
+#define MSF2_SPI_ERR_DEBUG   0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+if (MSF2_SPI_ERR_DEBUG >= lvl) { \
+qemu_log("%s: " fmt, __func__, ## args); \
+} \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+static void txfifo_reset(MSF2SpiState *s)
+{
+fifo32_reset(&s->tx_fifo);
+
+s->regs[R_SPI_STATUS] &= ~S_TXFIFOFUL;
+s->regs[R_SPI_STATUS] |= S_TXFIFOEMP;
+}
+
+static void rxfifo_reset(MSF2SpiState *s)
+{
+fifo32_reset(&s->rx_fifo);
+
+s->regs[R_SPI_STATUS] &= ~S_RXFIFOFUL;
+s->regs[R_SPI_STATUS] |= S_RXFIFOEMP;
+}
+
+static void set_fifodepth(MSF2SpiState *s)
+{
+int size = s->regs[R_SPI_DFSIZE] & FRAMESZ_MASK;
+
+if (0 <= size && size <= 8) {
+s->fifo_depth = 32;
+}
+if (9 <= size && size <= 16) {
+s->fifo_depth = 16;
+}
+if (17 <= size && size <= 32) {
+s->fifo_depth = 8;
+}
+}
+
+static void msf2_spi_do_reset(MSF2SpiState *s)
+{
+memset(s->regs, 0, sizeof s->regs);
+s->regs[R_SPI_CONTROL] = 0x8102;
+s->regs[R_SPI_DFSIZE] = 0x4;
+s->regs[R_SPI_STATUS] = 0x2440;
+s->regs[R_SPI_CLKGEN] = 0x7;
+s->regs[R_SPI_STAT8] = 0x7;
+s->regs[R_SPI_RIS] = 0x0;
+
+s->fifo_depth = 4;
+s->frame_count = 1;
+s->enabled = false;
+
+rxfifo_reset(s);
+txfifo_reset(s);
+}
+
+static void update_mis(MSF2SpiState *s)
+{
+uint32_t reg = s->regs[R_SPI_CONTROL];
+uint32_t tmp;
+
+/*
+ * form the Control register interrupt enable bits
+ * same as RIS, MIS and Interrupt clear registers for simplicity
+ */
+tmp = ((reg & C_INTRXOVRFLO) >> 4) | ((reg & C_INTRXDATA) >> 3) |
+   ((reg & C_INTTXDATA) >> 5);
+s->regs[R_SPI_MIS] |= tmp & s->regs[R_SPI_RIS];
+}
+
+static void spi_update_irq(MSF2SpiState *s)
+{
+int irq;
+
+update_mis(s);
+irq = !!(s->regs[R_SPI_MIS]);
+
+qemu_set_irq(s->irq, irq);
+}
+
+static void msf2_spi_reset(DeviceState *d)
+{
+msf2_spi_do_reset(MSF2_SPI(d));
+}
+
+static uint64_t
+spi_read(void *opaque, hwaddr addr, unsigned int size)
+{
+MSF2SpiState *s = opaque;
+uint32_t ret = 0;
+
+addr >>= 2;
+switch (addr) {
+case R_SPI_RX:
+s->regs[R_SPI_STATUS] &= ~S_RXFIFOFUL;
+s->regs[R_SPI_STATUS] &= ~RXCHOVRF;
+ret = fifo32_pop(&s->rx_fifo);
+if (fifo32_is_empty(&s->rx_fifo)) {
+s->regs[R_SPI_STATUS] |= S_RXFIFOEMP;
+}
+   

[Qemu-devel] [Qemu-devel PATCH 1/5] msf2: Add Smartfusion2 System timer

2017-05-09 Thread Subbaraya Sundeep
Modelled System Timer in Microsemi's Smartfusion2 Soc.
Timer has two 32bit down counters and two interrupts.

Signed-off-by: Subbaraya Sundeep 
---
 hw/timer/Makefile.objs|   1 +
 hw/timer/msf2-timer.c | 252 ++
 include/hw/timer/msf2-timer.h |  85 ++
 3 files changed, 338 insertions(+)
 create mode 100644 hw/timer/msf2-timer.c
 create mode 100644 include/hw/timer/msf2-timer.h

diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index dd6f27e..bd1ff15 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 000..466faa6
--- /dev/null
+++ b/hw/timer/msf2-timer.c
@@ -0,0 +1,252 @@
+/*
+ * Timer block model of Microsemi SmartFusion2.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep .
+ *
+ * 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/msf2-timer.h"
+
+#ifndef MSF2_TIMER_ERR_DEBUG
+#define MSF2_TIMER_ERR_DEBUG  0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+if (MSF2_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 timer_update_irq(struct Msf2Timer *st)
+{
+bool isr, ier;
+
+isr = !!(st->regs[R_TIM_RIS] & TIMER_RIS_ACK);
+ier = !!(st->regs[R_TIM_CTRL] & TIMER_CTRL_INTR);
+
+qemu_set_irq(st->irq, (ier && isr));
+}
+
+static void timer_update(struct Msf2Timer *st)
+{
+uint64_t count;
+
+if (!(st->regs[R_TIM_CTRL] & TIMER_CTRL_ENBL)) {
+ptimer_stop(st->ptimer);
+return;
+}
+
+count = st->regs[R_TIM_LOADVAL];
+ptimer_set_limit(st->ptimer, count, 1);
+ptimer_run(st->ptimer, 1);
+}
+
+static uint64_t
+timer_read(void *opaque, hwaddr addr, unsigned int size)
+{
+MSF2TimerState *t = opaque;
+struct Msf2Timer *st;
+uint32_t ret = 0;
+int timer = 0;
+int isr;
+int ier;
+
+addr >>= 2;
+/*
+ * Two independent timers has same base address.
+ * Based on addr passed figure out which timer is being used.
+ */
+if (addr >= R_TIM1_MAX) {
+timer = 1;
+addr -= R_TIM1_MAX;
+}
+
+st = &t->timers[timer];
+
+switch (addr) {
+case R_TIM_VAL:
+ret = ptimer_get_count(st->ptimer);
+break;
+
+case R_TIM_MIS:
+isr = !!(st->regs[R_TIM_RIS] & TIMER_RIS_ACK);
+ier = !!(st->regs[R_TIM_CTRL] & TIMER_CTRL_INTR);
+ret = ier & isr;
+break;
+
+default:
+if (addr < ARRAY_SIZE(st->regs)) {
+ret = st->regs[addr];
+} else {
+qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__,
+ addr * 4);
+}
+break;
+}
+
+DB_PRINT("timer=%d 0x%" HWADDR_PRIx "=0x%" PRIx32 "\n", timer, addr * 4,
+ret);
+return ret;
+}
+
+static void
+timer_write(void *opaque, hwaddr addr,
+uint64_t val64, unsigned int size)
+{
+MSF2TimerState *t = opaque;
+struct Msf2Timer *st;
+int timer = 0;
+uint32_t value = val64;
+
+addr >>= 2;
+/*
+ * Two independent timers has same base address.
+ * Based on addr passed figure out which timer is being used.
+ */
+if (addr >= R_TIM1_MAX) {
+timer = 1;
+addr -= R_TIM1_MAX;
+}
+
+st = &t->timers[timer];
+
+DB_PRINT("addr=0x%" HWADDR_PRI

[Qemu-devel] [Qemu-devel PATCH 0/5] Add support for Smartfusion2 SoC

2017-05-09 Thread Subbaraya Sundeep
Hi Qemu-devel,

I am trying to add Smartfusion2 SoC.
SoC is from Microsemi and System on Module(SOM)
board is from Emcraft systems. Smartfusion2 has hardened
Microcontroller(Cortex-M3)based Sub System and FPGA fabric.
At the moment only system timer, sysreg and SPI
controller are modelled.

Testing:
./arm-softmmu/qemu-system-arm -M smartfusion2-som -serial mon:stdio \
-kernel u-boot.bin -display none -drive file=spi.bin,if=mtd,format=raw

U-boot is from Emcraft with modified SPI driver not to use PDMA.
Linux is 4.5 linux with Smartfusion2 SoC dts and clocksource 
driver added by myself @
https://github.com/Subbaraya-Sundeep/linux.git

Baremetal elfs from Microsemi Softconsole IDE are also working.

Thanks,
Sundeep

Subbaraya Sundeep (5):
  msf2: Add Smartfusion2 System timer
  msf2: Microsemi Smartfusion2 System Register block.
  msf2: Add Smartfusion2 SPI controller
  msf2: Add Smartfusion2 SoC.
  msf2: Add Emcraft's Smartfusion2 SOM kit.

 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   3 +-
 hw/arm/msf2-soc.c   | 188 
 hw/arm/msf2-som.c   |  67 +++
 hw/misc/Makefile.objs   |   1 +
 hw/misc/msf2-sysreg.c   | 131 ++
 hw/ssi/Makefile.objs|   1 +
 hw/ssi/msf2-spi.c   | 378 
 hw/timer/Makefile.objs  |   1 +
 hw/timer/msf2-timer.c   | 252 +++
 include/hw/arm/msf2-soc.h   |  60 +++
 include/hw/misc/msf2-sysreg.h   |  80 +
 include/hw/ssi/msf2-spi.h   | 105 +++
 include/hw/timer/msf2-timer.h   |  85 +
 14 files changed, 1352 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/msf2-soc.c
 create mode 100644 hw/arm/msf2-som.c
 create mode 100644 hw/misc/msf2-sysreg.c
 create mode 100644 hw/ssi/msf2-spi.c
 create mode 100644 hw/timer/msf2-timer.c
 create mode 100644 include/hw/arm/msf2-soc.h
 create mode 100644 include/hw/misc/msf2-sysreg.h
 create mode 100644 include/hw/ssi/msf2-spi.h
 create mode 100644 include/hw/timer/msf2-timer.h

-- 
2.5.0




[Qemu-devel] [Qemu-devel PATCH 2/5] msf2: Microsemi Smartfusion2 System Register block.

2017-05-09 Thread Subbaraya Sundeep
Added Sytem register block of Smartfusion2.
This block has PLL registers which are accessed by guest.

Signed-off-by: Subbaraya Sundeep 
---
 hw/misc/Makefile.objs |   1 +
 hw/misc/msf2-sysreg.c | 131 ++
 include/hw/misc/msf2-sysreg.h |  80 ++
 3 files changed, 212 insertions(+)
 create mode 100644 hw/misc/msf2-sysreg.c
 create mode 100644 include/hw/misc/msf2-sysreg.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index c8b4893..0f52354 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 000..53e9cba
--- /dev/null
+++ b/hw/misc/msf2-sysreg.c
@@ -0,0 +1,131 @@
+/*
+ * System Register block model of Microsemi SmartFusion2.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep 
+ *
+ * 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 "hw/misc/msf2-sysreg.h"
+
+#ifndef MSF2_SYSREG_ERR_DEBUG
+#define MSF2_SYSREG_ERR_DEBUG  0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+if (MSF2_SYSREG_ERR_DEBUG >= lvl) { \
+qemu_log("%s: " fmt, __func__, ## args); \
+} \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+static void msf2_sysreg_reset(DeviceState *d)
+{
+MSF2SysregState *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)
+{
+MSF2SysregState *s = opaque;
+offset /= 4;
+uint32_t ret = 0;
+
+if (offset < ARRAY_SIZE(s->regs)) {
+ret = s->regs[offset];
+DB_PRINT("addr: 0x%08" HWADDR_PRIx " data: 0x%08" PRIx32 "\n",
+offset * 4, ret);
+} else {
+qemu_log_mask(LOG_GUEST_ERROR,
+"%s: Bad offset 0x%08" HWADDR_PRIx "\n", __func__,
+offset * 4);
+}
+
+return ret;
+}
+
+static void msf2_sysreg_write(void *opaque, hwaddr offset,
+  uint64_t val, unsigned size)
+{
+MSF2SysregState *s = (MSF2SysregState *)opaque;
+offset /= 4;
+
+DB_PRINT("addr: 0x%08" HWADDR_PRIx " data: 0x%08" PRIx64 "\n",
+offset * 4, val);
+
+switch (offset) {
+case MSSDDR_PLL_STATUS:
+break;
+
+default:
+if (offset < ARRAY_SIZE(s->regs)) {
+s->regs[offset] = val;
+} else {
+qemu_log_mask(LOG_GUEST_ERROR,
+"%s: Bad offset 0x%08" HWADDR_PRIx "\n", __func__,
+offset * 4);
+}
+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)
+{
+MSF2SysregState *s = MSF2_SYSREG(obj);
+
+memory_region_init_io(&s->iomem, obj, &sysreg_ops, s, TYPE_MSF2_SYSREG,
+  MSF2_SYSREG_MMIO_SIZE);
+sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
+}
+
+static const VMStateDescription vmstate_msf2_sysreg = {
+.name = TYPE_MSF2_SYSREG,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32_ARRAY(regs, MSF2SysregState, 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 = {
+.name  = TYPE_MSF2_SYSREG,
+.parent = TYPE_SYS_BUS_DEVICE,
+.class_init = msf2_sysreg_class_init,
+.instance_size  = sizeof(MSF2SysregState),
+.instance_init = msf2_sysreg_init,
+};
+
+static void msf2_sysreg_register_types(void)
+{
+type_register_static(&msf2_sysreg_info);
+}
+
+type_init(msf2_sysreg_register_types)
diff --git a/include/hw/misc/msf2-sysreg.h b/include/hw/misc/msf2-sysreg.h
new file mode 100644
index 000..a485ed6
--- /dev/null
+++ b/include/hw/misc/msf2-sysreg.h

[Qemu-devel] [Qemu-devel RFC v3 5/5] msf2: Add Emcraft's Smartfusion2 SOM kit.

2017-04-28 Thread Subbaraya Sundeep
Emulated Emcraft's Smartfusion2 System On Module starter
kit.

Signed-off-by: Subbaraya Sundeep 
---
 hw/arm/Makefile.objs |  1 +
 hw/arm/msf2_som.c| 68 
 2 files changed, 69 insertions(+)
 create mode 100644 hw/arm/msf2_som.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index cce2759..d0b7093 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -5,6 +5,7 @@ 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
+obj-y += msf2_som.o
 obj-y += sysbus-fdt.o
 
 obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
diff --git a/hw/arm/msf2_som.c b/hw/arm/msf2_som.c
new file mode 100644
index 000..c41edd5
--- /dev/null
+++ b/hw/arm/msf2_som.c
@@ -0,0 +1,68 @@
+/*
+ * SmartFusion2 SOM starter kit(from Emcraft) emulation.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/boards.h"
+#include "hw/arm/msf2_soc.h"
+#include "hw/arm/arm.h"
+
+static void msf2_init(MachineState *machine)
+{
+DeviceState *dev;
+DeviceState *spi_flash;
+MSF2State *soc;
+DriveInfo *dinfo = drive_get_next(IF_MTD);
+qemu_irq cs_line;
+SSIBus *spi_bus;
+
+dev = qdev_create(NULL, TYPE_MSF2_SOC);
+qdev_prop_set_string(dev, "cpu-model", "cortex-m3");
+object_property_set_bool(OBJECT(dev), true, "realized", &error_fatal);
+
+soc = MSF2_SOC(dev);
+
+/* Attach SPI flash to SPI0 controller */
+spi_bus = (SSIBus *)qdev_get_child_bus(dev, "spi0");
+spi_flash = ssi_create_slave_no_init(spi_bus, "s25sl12801");
+qdev_prop_set_uint8(spi_flash, "spansion-cr2nv", 1);
+if (dinfo) {
+qdev_prop_set_drive(spi_flash, "drive", blk_by_legacy_dinfo(dinfo),
+&error_fatal);
+}
+qdev_init_nofail(spi_flash);
+cs_line = qdev_get_gpio_in_named(spi_flash, SSI_GPIO_CS, 0);
+sysbus_connect_irq(SYS_BUS_DEVICE(&soc->spi[0]), 1, cs_line);
+
+armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
+   ENVM_SIZE);
+}
+
+static void msf2_machine_init(MachineClass *mc)
+{
+mc->desc = "SmartFusion2 SOM kit from Emcraft";
+mc->init = msf2_init;
+}
+
+DEFINE_MACHINE("smartfusion2-som", msf2_machine_init)
-- 
2.5.0




[Qemu-devel] [Qemu-devel RFC v3 4/5] msf2: Add Smartfusion2 SoC.

2017-04-28 Thread Subbaraya Sundeep
Smartfusion2 SoC has hardened Microcontroller subsystem
and flash based FPGA fabric. This patch adds support for
Microcontroller subsystem in the SoC.

Signed-off-by: Subbaraya Sundeep 
---
 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   2 +-
 hw/arm/msf2_soc.c   | 194 
 include/hw/arm/msf2_soc.h   |  62 +
 4 files changed, 258 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/msf2_soc.c
 create mode 100644 include/hw/arm/msf2_soc.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 78d7af0..7062512 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -122,3 +122,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 000..a470872
--- /dev/null
+++ b/hw/arm/msf2_soc.c
@@ -0,0 +1,194 @@
+/*
+ * SmartFusion2 SoC emulation.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep 
+ *
+ * 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/char/serial.h"
+#include "hw/boards.h"
+#include "sysemu/block-backend.h"
+#include "hw/arm/msf2_soc.h"
+
+#define MSF2_TIMER_BASE   0x40004000
+#define MSF2_SYSREG_BASE  0x40038000
+
+#define MSF2_TIMER_IRQ0   14
+#define MSF2_TIMER_IRQ1   15
+
+static const uint32_t spi_addr[MSF2_NUM_SPIS] = { 0x40001000 , 0x40011000 };
+static const uint32_t uart_addr[MSF2_NUM_UARTS] = { 0x4000 , 0x4001 };
+
+static const int spi_irq[MSF2_NUM_SPIS] = { 2, 3 };
+static const int uart_irq[MSF2_NUM_UARTS] = { 10, 11 };
+
+static void msf2_soc_initfn(Object *obj)
+{
+MSF2State *s = MSF2_SOC(obj);
+int i;
+
+object_initialize(&s->armv7m, sizeof(s->armv7m), TYPE_ARMV7M);
+qdev_set_parent_bus(DEVICE(&s->armv7m), sysbus_get_default());
+
+object_initialize(&s->sysreg, sizeof(s->sysreg), TYPE_MSF2_SYSREG);
+qdev_set_parent_bus(DEVICE(&s->sysreg), sysbus_get_default());
+
+object_initialize(&s->timer, sizeof(s->timer), TYPE_MSF2_TIMER);
+qdev_set_parent_bus(DEVICE(&s->timer), sysbus_get_default());
+
+for (i = 0; i < MSF2_NUM_SPIS; i++) {
+object_initialize(&s->spi[i], sizeof(s->spi[i]),
+  TYPE_MSF2_SPI);
+qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default());
+}
+}
+
+static void msf2_soc_realize(DeviceState *dev_soc, Error **errp)
+{
+MSF2State *s = MSF2_SOC(dev_soc);
+DeviceState *dev, *armv7m;
+SysBusDevice *busdev;
+Error *err = NULL;
+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);
+
+memory_region_init_ram(nvm, NULL, "MSF2.envm", ENVM_SIZE,
+   &error_fatal);
+memory_region_init_alias(nvm_alias, NULL, "M

[Qemu-devel] [Qemu-devel RFC v3 3/5] msf2: Add Smartfusion2 SPI controller

2017-04-28 Thread Subbaraya Sundeep
Modelled Microsemi's Smartfusion2 SPI controller.

Signed-off-by: Subbaraya Sundeep 
---
Hi Peter and Alistair,

I created two SPI controllers as per SoC spec 
in hw/arm/msf2_soc.c. I am assuming there has to be two
busses spi0 and spi1 one for each controller. In board file
(hw/arm/msf2_som.c) attached SPI flash to SPI0 controller.
I am not able to understand(from hw/ssi/xilinx_spips.c)
how to create two busses in hw/ssi/msf2_spi.c. 
Please help me here. Below is the output of info qtree:

(qemu) info qtree
bus: main-system-bus
  type System
  dev: msf2-soc, id ""
cpu-model = "cortex-m3"
  dev: msf2-spi, id ""
gpio-out "sysbus-irq" 2
mmio 40011000/0040
bus: spi0
  type SSI
  dev: msf2-spi, id ""
gpio-out "sysbus-irq" 2
mmio 40001000/0040
bus: spi0
  type SSI
  dev: s25sl12801, id ""
gpio-in "ssi-gpio-cs" 1
nonvolatile-cfg = 36863 (0x8fff)
spansion-cr1nv = 0 (0x0)
spansion-cr2nv = 1 (0x1)
spansion-cr3nv = 2 (0x2)
spansion-cr4nv = 16 (0x10)
drive = "mtd0"

Thanks,
Sundeep

 hw/ssi/Makefile.objs  |   1 +
 hw/ssi/msf2_spi.c | 373 ++
 include/hw/ssi/msf2_spi.h | 102 +
 3 files changed, 476 insertions(+)
 create mode 100644 hw/ssi/msf2_spi.c
 create mode 100644 include/hw/ssi/msf2_spi.h

diff --git a/hw/ssi/Makefile.objs b/hw/ssi/Makefile.objs
index 487add2..86445d7 100644
--- a/hw/ssi/Makefile.objs
+++ b/hw/ssi/Makefile.objs
@@ -4,6 +4,7 @@ common-obj-$(CONFIG_XILINX_SPI) += xilinx_spi.o
 common-obj-$(CONFIG_XILINX_SPIPS) += xilinx_spips.o
 common-obj-$(CONFIG_ASPEED_SOC) += aspeed_smc.o
 common-obj-$(CONFIG_STM32F2XX_SPI) += stm32f2xx_spi.o
+common-obj-$(CONFIG_MSF2) += msf2_spi.o
 
 obj-$(CONFIG_OMAP) += omap_spi.o
 obj-$(CONFIG_IMX) += imx_spi.o
diff --git a/hw/ssi/msf2_spi.c b/hw/ssi/msf2_spi.c
new file mode 100644
index 000..e7ffa21
--- /dev/null
+++ b/hw/ssi/msf2_spi.c
@@ -0,0 +1,373 @@
+/*
+ * SPI controller model of Microsemi SmartFusion2.
+ *
+ * Copyright (C) 2017 Subbaraya Sundeep 
+ *
+ * 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/ssi/msf2_spi.h"
+#include "sysemu/sysemu.h"
+#include "qemu/log.h"
+
+#ifndef MSF2_SPI_ERR_DEBUG
+#define MSF2_SPI_ERR_DEBUG   0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+if (MSF2_SPI_ERR_DEBUG >= lvl) { \
+qemu_log("%s: " fmt, __func__, ## args); \
+} \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+static void txfifo_reset(MSF2SpiState *s)
+{
+fifo32_reset(&s->tx_fifo);
+
+s->regs[R_SPI_STATUS] &= ~S_TXFIFOFUL;
+s->regs[R_SPI_STATUS] |= S_TXFIFOEMP;
+}
+
+static void rxfifo_reset(MSF2SpiState *s)
+{
+fifo32_reset(&s->rx_fifo);
+
+s->regs[R_SPI_STATUS] &= ~S_RXFIFOFUL;
+s->regs[R_SPI_STATUS] |= S_RXFIFOEMP;
+}
+
+static void set_fifodepth(MSF2SpiState *s)
+{
+int size = s->regs[R_SPI_DFSIZE] & FRAMESZ_MASK;
+
+if (0 <= size && size <= 8) {
+s->fifo_depth = 32;
+}
+if (9 <= size && size <= 16) {
+s->fifo_depth = 16;
+}
+if (17 <= size && size <= 32) {
+s->fifo_depth = 8;
+}
+}
+
+static void msf2_spi_do_reset(MSF2SpiState *s)
+{
+memset(s->regs, 0, sizeof s->regs);
+s->regs[R_SPI_CONTROL] = 0x8102;
+s->regs[R_SPI_DFSIZE] = 0x4;
+s->regs[R_SPI_STATUS] = 0x2440;
+s->regs[R_SPI_CLKGEN] = 0x7;
+s->regs[R_SPI_STAT8] = 0x7;
+s->regs[R_SPI_RIS] = 0x0;
+
+s->fifo_depth = 4;
+s->frame_count = 1;
+s->enabled = false;
+
+rxfifo_rese

[Qemu-devel] [Qemu-devel RFC v3 2/5] msf2: Microsemi Smartfusion2 System Register block.

2017-04-28 Thread Subbaraya Sundeep
Added Sytem register block of Smartfusion2.
This block has PLL registers which are accessed by guest.

Signed-off-by: Subbaraya Sundeep 
---
 hw/misc/Makefile.objs |   1 +
 hw/misc/msf2_sysreg.c | 127 ++
 include/hw/misc/msf2_sysreg.h |  77 +
 3 files changed, 205 insertions(+)
 create mode 100644 hw/misc/msf2_sysreg.c
 create mode 100644 include/hw/misc/msf2_sysreg.h

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 000..6386953
--- /dev/null
+++ b/hw/misc/msf2_sysreg.c
@@ -0,0 +1,127 @@
+/*
+ * System Register block model of Microsemi SmartFusion2.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep 
+ *
+ * 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/misc/msf2_sysreg.h"
+#include "sysemu/sysemu.h"
+#include "qemu/log.h"
+
+#ifndef MSF2_SYSREG_ERR_DEBUG
+#define MSF2_SYSREG_ERR_DEBUG  0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+if (MSF2_SYSREG_ERR_DEBUG >= lvl) { \
+qemu_log("%s: " fmt, __func__, ## args); \
+} \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+static void msf2_sysreg_reset(DeviceState *d)
+{
+MSF2SysregState *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)
+{
+MSF2SysregState *s = opaque;
+offset /= 4;
+uint32_t ret = 0;
+
+if (offset < ARRAY_SIZE(s->regs)) {
+ret = s->regs[offset];
+DB_PRINT("addr: %08" HWADDR_PRIx " data: %08" PRIx32 "\n",
+offset * 4, ret);
+} else {
+DB_PRINT("addr: %08" HWADDR_PRIx " not valid\n", offset * 4);
+}
+
+return ret;
+}
+
+static void msf2_sysreg_write(void *opaque, hwaddr offset,
+  uint64_t val, unsigned size)
+{
+MSF2SysregState *s = (MSF2SysregState *)opaque;
+offset /= 4;
+
+DB_PRINT("addr: %08" HWADDR_PRIx " data: %08" PRIx64 "\n", offset * 4, 
val);
+
+switch (offset) {
+case MSSDDR_PLL_STATUS:
+break;
+
+default:
+if (offset < ARRAY_SIZE(s->regs)) {
+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)
+{
+MSF2SysregState *s = MSF2_SYSREG(obj);
+
+memory_region_init_io(&s->iomem, obj, &sysreg_ops, s, TYPE_MSF2_SYSREG,
+  MSF2_SYSREG_MMIO_SIZE);
+sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
+}
+
+static const VMStateDescription vmstate_msf2_sysreg = {
+.name = TYPE_MSF2_SYSREG,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32_ARRAY(regs, MSF2SysregState, 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 = {
+.name  = TYPE_MSF2_SYSREG,
+.parent = TYPE_SYS_BUS_DEVICE,
+.class_init = msf2_sysreg_class_init,
+.instance_size  = sizeof(MSF2SysregState),
+.instance_init = msf2_sysreg_init,
+};
+
+static void msf2_sysreg_register_types(void)
+{
+type_register_static(&msf2_sysreg_info);
+}
+
+type_init(msf2_sysreg_register_types)
diff --git a/include/hw/misc/msf2_sysreg.h b/include/hw/misc/msf2_sysreg.h
new file mode 100644
index 000..03c5773
--- /dev/null
+++ b/include/hw/misc/msf2_sysreg.h
@@ -0,0 +1,77 @@
+/*
+ * Microsemi SmartFusion2 SYSREG
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a c

[Qemu-devel] [Qemu-devel RFC v3 0/5] Add support for Smartfusion2 SoC

2017-04-28 Thread Subbaraya Sundeep
Hi Qemu-devel,

I am trying to add Smartfusion2 SoC.
SoC is from Microsemi and System on Module(SOM)
board is from Emcraft systems. Smartfusion2 has hardened
Microcontroller(Cortex-M3)based Sub System and FPGA fabric.
At the moment only system timer, sysreg and SPI
controller are modelled.

Testing:
./arm-softmmu/qemu-system-arm -M smartfusion2-som -serial mon:stdio \
-kernel u-boot.bin -display none -drive file=spi.bin,if=mtd,format=raw

U-boot is from Emcraft with modified SPI driver not to use PDMA.
Linux is 4.5 linux with Smartfusion2 SoC dts and clocksource 
driver added by myself @
https://github.com/Subbaraya-Sundeep/linux.git

Baremetal elfs from Microsemi Softconsole IDE are also working.

Changes from v2:
Added SoC file and board file.
Changes from v1:
Added SPI controller.

Thanks,
Sundeep


Subbaraya Sundeep (5):
  msf2: Add Smartfusion2 System timer
  msf2: Microsemi Smartfusion2 System Register block.
  msf2: Add Smartfusion2 SPI controller
  msf2: Add Smartfusion2 SoC.
  msf2: Add Emcraft's Smartfusion2 SOM kit.

 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   3 +-
 hw/arm/msf2_soc.c   | 194 +
 hw/arm/msf2_som.c   |  68 
 hw/misc/Makefile.objs   |   1 +
 hw/misc/msf2_sysreg.c   | 127 ++
 hw/ssi/Makefile.objs|   1 +
 hw/ssi/msf2_spi.c   | 373 
 hw/timer/Makefile.objs  |   1 +
 hw/timer/msf2_timer.c   | 250 +++
 include/hw/arm/msf2_soc.h   |  62 +++
 include/hw/misc/msf2_sysreg.h   |  77 +
 include/hw/ssi/msf2_spi.h   | 102 +++
 include/hw/timer/msf2_timer.h   |  82 +
 14 files changed, 1341 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/msf2_soc.c
 create mode 100644 hw/arm/msf2_som.c
 create mode 100644 hw/misc/msf2_sysreg.c
 create mode 100644 hw/ssi/msf2_spi.c
 create mode 100644 hw/timer/msf2_timer.c
 create mode 100644 include/hw/arm/msf2_soc.h
 create mode 100644 include/hw/misc/msf2_sysreg.h
 create mode 100644 include/hw/ssi/msf2_spi.h
 create mode 100644 include/hw/timer/msf2_timer.h

-- 
2.5.0




[Qemu-devel] [Qemu-devel RFC v3 1/5] msf2: Add Smartfusion2 System timer

2017-04-28 Thread Subbaraya Sundeep
Modelled System Timer in Microsemi's Smartfusion2 Soc.
Timer has two 32bit down counters and two interrupts.

Signed-off-by: Subbaraya Sundeep 
---
 hw/timer/Makefile.objs|   1 +
 hw/timer/msf2_timer.c | 250 ++
 include/hw/timer/msf2_timer.h |  82 ++
 3 files changed, 333 insertions(+)
 create mode 100644 hw/timer/msf2_timer.c
 create mode 100644 include/hw/timer/msf2_timer.h

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 000..d1dbde5
--- /dev/null
+++ b/hw/timer/msf2_timer.c
@@ -0,0 +1,250 @@
+/*
+ * Timer block model of Microsemi SmartFusion2.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep .
+ *
+ * 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/timer/msf2_timer.h"
+#include "hw/sysbus.h"
+#include "qemu/log.h"
+#include "qemu/main-loop.h"
+
+#ifndef MSF2_TIMER_ERR_DEBUG
+#define MSF2_TIMER_ERR_DEBUG  0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+if (MSF2_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 timer_update_irq(struct Msf2Timer *st)
+{
+bool isr, ier;
+
+isr = !!(st->regs[R_TIM_RIS] & TIMER_RIS_ACK);
+ier = !!(st->regs[R_TIM_CTRL] & TIMER_CTRL_INTR);
+
+qemu_set_irq(st->irq, (ier && isr));
+}
+
+static void timer_update(struct Msf2Timer *st)
+{
+uint64_t count;
+
+DB_PRINT("timer=%d\n", st->nr);
+
+if (!(st->regs[R_TIM_CTRL] & TIMER_CTRL_ENBL)) {
+ptimer_stop(st->ptimer);
+return;
+}
+
+count = st->regs[R_TIM_LOADVAL];
+ptimer_set_limit(st->ptimer, count, 1);
+ptimer_run(st->ptimer, 1);
+}
+
+static uint64_t
+timer_read(void *opaque, hwaddr addr, unsigned int size)
+{
+MSF2TimerState *t = opaque;
+struct Msf2Timer *st;
+uint32_t r = 0;
+unsigned int timer = 0;
+int isr;
+int ier;
+
+addr >>= 2;
+/*
+ * Two independent timers has same base address.
+ * Based on addr passed figure out which timer is being used.
+ */
+if (addr >= R_TIM1_MAX) {
+timer = 1;
+addr -= R_TIM1_MAX;
+}
+
+st = &t->timers[timer];
+
+switch (addr) {
+case R_TIM_VAL:
+r = ptimer_get_count(st->ptimer);
+DB_PRINT("msf2_timer t=%d read counter=%x\n", timer, r);
+break;
+
+case R_TIM_MIS:
+isr = !!(st->regs[R_TIM_RIS] & TIMER_RIS_ACK);
+ier = !!(st->regs[R_TIM_CTRL] & TIMER_CTRL_INTR);
+r = ier && isr;
+break;
+
+default:
+if (addr < ARRAY_SIZE(st->regs)) {
+r = st->regs[addr];
+}
+break;
+}
+DB_PRINT("timer=%d %lu=%x\n", timer, addr * 4, r);
+return r;
+}
+
+static void
+timer_write(void *opaque, hwaddr addr,
+uint64_t val64, unsigned int size)
+{
+MSF2TimerState *t = opaque;
+struct Msf2Timer *st;
+unsigned int timer = 0;
+uint32_t value = val64;
+
+addr >>= 2;
+/*
+ * Two independent timers has same base address.
+ * Based on addr passed figure out which timer is being used.
+ */
+if (addr >= R_TIM1_MAX) {
+timer = 1;
+addr -= R_TIM1_MAX;
+}
+
+st = &t->timers[timer];
+
+DB_PRINT("addr

[Qemu-devel] [Qemu-devel RFC v2 2/4] msf2: Microsemi Smartfusion2 System Register block.

2017-04-09 Thread Subbaraya Sundeep
Added Sytem register block of Smartfusion2.
This block has PLL registers which are accessed by guest.

Signed-off-by: Subbaraya Sundeep 
---
 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 000..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 
+ *
+ * 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_sysre

[Qemu-devel] [Qemu-devel RFC v2 4/4] msf2: Add Emcraft's Smartfusion2 SOM kit.

2017-04-09 Thread Subbaraya Sundeep
Emulated Emcraft's Smartfusion2 System On Module starter
kit.

Signed-off-by: Subbaraya Sundeep 
---
 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   2 +-
 hw/arm/msf2_soc.c   | 141 
 3 files changed, 143 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 000..7277b51
--- /dev/null
+++ b/hw/arm/msf2_soc.c
@@ -0,0 +1,141 @@
+/*
+ * Smartfusion2 SOM starter kit(from Emcraft) emulation.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep 
+ *
+ * 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"
+#include "hw/ssi/ssi.h"
+
+#define MSF2_NUM_USARTS   1
+#define MSF2_NUM_TIMERS   2
+
+#define ENVM_BASE_ADDRESS 0x6000
+#define ENVM_SIZE (128 * 1024)
+
+#define DDR_BASE_ADDRESS  0xA000
+#define DDR_SIZE  (64 * 1024 * 1024)
+
+#define SRAM_BASE_ADDRESS 0x2000
+#define SRAM_SIZE (64 * 1024)
+
+#define MSF2_TIMER_BASE   0x40004000
+#define MSF2_UART0_BASE   0x4000
+#define MSF2_SYSREG_BASE  0x40038000
+#define MSF2_SPI0_BASE0x40001000
+
+#define MSF2_SPI0_IRQ 2
+#define MSF2_UART0_IRQ10
+#define MSF2_TIMER_IRQ0   14
+#define MSF2_TIMER_IRQ1   15
+
+static void msf2_init(MachineState *machine)
+{
+const char *kernel_filename = NULL;
+DeviceState *dev, *nvic;
+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();
+SysBusDevice *busdev;
+DriveInfo *dinfo = drive_get_next(IF_MTD);
+qemu_irq cs_line;
+SSIBus *spi;
+
+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, "MSF2.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_memor

[Qemu-devel] [Qemu-devel RFC v2 3/4] msf2: Add Smartfusion2 SPI controller

2017-04-09 Thread Subbaraya Sundeep
Modelled Microsemi's Smartfusion2 SPI controller.

Signed-off-by: Subbaraya Sundeep 
---
 hw/ssi/Makefile.objs |   1 +
 hw/ssi/msf2_spi.c| 449 +++
 2 files changed, 450 insertions(+)
 create mode 100644 hw/ssi/msf2_spi.c

diff --git a/hw/ssi/Makefile.objs b/hw/ssi/Makefile.objs
index 487add2..86445d7 100644
--- a/hw/ssi/Makefile.objs
+++ b/hw/ssi/Makefile.objs
@@ -4,6 +4,7 @@ common-obj-$(CONFIG_XILINX_SPI) += xilinx_spi.o
 common-obj-$(CONFIG_XILINX_SPIPS) += xilinx_spips.o
 common-obj-$(CONFIG_ASPEED_SOC) += aspeed_smc.o
 common-obj-$(CONFIG_STM32F2XX_SPI) += stm32f2xx_spi.o
+common-obj-$(CONFIG_MSF2) += msf2_spi.o
 
 obj-$(CONFIG_OMAP) += omap_spi.o
 obj-$(CONFIG_IMX) += imx_spi.o
diff --git a/hw/ssi/msf2_spi.c b/hw/ssi/msf2_spi.c
new file mode 100644
index 000..6054cd8
--- /dev/null
+++ b/hw/ssi/msf2_spi.c
@@ -0,0 +1,449 @@
+/*
+ * SPI controller model of Microsemi Smartfusion2.
+ *
+ * Copyright (C) 2017 Subbaraya Sundeep 
+ *
+ * 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 "sysemu/sysemu.h"
+#include "qemu/log.h"
+#include "qemu/fifo32.h"
+
+#include "hw/ssi/ssi.h"
+
+#ifdef MSF2_SPI_ERR_DEBUG
+#define DB_PRINT(...) do { \
+fprintf(stderr,  ": %s: ", __func__); \
+fprintf(stderr, ## __VA_ARGS__); \
+} while (0);
+#else
+#define DB_PRINT(...)
+#endif
+
+#define FIFO_CAPACITY 32
+#define FIFO_CAPACITY 32
+
+#define R_CONTROL 0
+#define R_DFSIZE  1
+#define R_STATUS  2
+#define R_INTCLR  3
+#define R_RX  4
+#define R_TX  5
+#define R_CLKGEN  6
+#define R_SS  7
+#define R_MIS 8
+#define R_RIS 9
+#define R_CONTROL210
+#define R_COMMAND 11
+#define R_PKTSIZE 12
+#define R_CMDSIZE 13
+#define R_HWSTATUS14
+#define R_STAT8   15
+#define R_MAX 16
+
+#define S_RXFIFOFUL   (1 << 4)
+#define S_RXFIFOFULNXT(1 << 5)
+#define S_RXFIFOEMP   (1 << 6)
+#define S_RXFIFOEMPNXT(1 << 7)
+#define S_TXFIFOFUL   (1 << 8)
+#define S_TXFIFOFULNXT(1 << 9)
+#define S_TXFIFOEMP   (1 << 10)
+#define S_TXFIFOEMPNXT(1 << 11)
+#define S_FRAMESTART  (1 << 12)
+#define S_SSEL(1 << 13)
+#define S_ACTIVE  (1 << 14)
+
+#define C_ENABLE  (1 << 0)
+#define C_MODE(1 << 1)
+#define C_INTRXDATA   (1 << 4)
+#define C_INTTXDATA   (1 << 5)
+#define C_INTRXOVRFLO (1 << 6)
+#define C_SPS (1 << 26)
+#define C_BIGFIFO (1 << 29)
+#define C_RESET   (1 << 31)
+
+#define FRAMESZ_MASK  0x1F
+#define FMCOUNT_MASK  0x0000
+#define FMCOUNT_SHIFT 8
+
+#define TXDONE(1 << 0)
+#define RXRDY (1 << 1)
+#define RXCHOVRF  (1 << 2)
+
+#define TYPE_MSF2_SPI   "msf2-spi"
+#define MSF2_SPI(obj)   OBJECT_CHECK(Msf2SPI, (obj), TYPE_MSF2_SPI)
+
+typedef struct Msf2SPI {
+SysBusDevice parent_obj;
+
+MemoryRegion mmio;
+
+qemu_irq irq;
+
+qemu_irq cs_line;
+
+SSIBus *spi;
+
+Fifo32 rx_fifo;
+Fifo32 tx_fifo;
+
+int fifo_depth;
+uint32_t frame_count;
+bool enabled;
+
+uint32_t regs[R_MAX];
+} Msf2SPI;
+
+static void txfifo_reset(Msf2SPI *s)
+{
+fifo32_reset(&s->tx_fifo);
+
+s->regs[R_STATUS] &= ~S_TXFIFOFUL;
+s->regs[R_STATUS] |= S_TXFIFOEMP;
+}
+
+static void rxfifo_reset(Msf2SPI *s)
+{
+fifo32_reset(&s->rx_fifo);
+
+s->regs[R_STATUS] &= ~S_RXFIFOFUL;
+s->regs[R_STATUS] |= S_RXFIFOEMP;
+}
+
+static void set_fifodepth(Msf2SPI *s)
+{
+int size

[Qemu-devel] [Qemu-devel RFC v2 0/4] Add support for Smartfusion2 SoC

2017-04-09 Thread Subbaraya Sundeep
Hi Qemu-devel,

I am trying to add Smartfusion2 SoC.
SoC is from Microsemi and System on Module(SOM)
board is from Emcraft systems. Smartfusion2 has hardened
Microcontroller(Cortex-M3)based Sub System and FPGA fabric.
At the moment only system timer, sysreg and SPI
controller are modelled.

Testing:
./arm-softmmu/qemu-system-arm -M smartfusion2-som -serial mon:stdio \
-kernel u-boot.bin -display none -drive file=spi.bin,if=mtd,format=raw

U-boot is from Emcraft with modified SPI driver not to use PDMA.
Linux is 4.5 linux with Smartfusion2 SoC dts and clocksource 
driver added by myself @
https://github.com/Subbaraya-Sundeep/linux.git

Baremetal elfs from Microsemi Softconsole IDE are also working.

Changes from v1:
Added SPI controller.

Thanks,
Sundeep

Subbaraya Sundeep (4):
  msf2: Add Smartfusion2 System timer
  msf2: Microsemi Smartfusion2 System Register block.
  msf2: Add Smartfusion2 SPI controller
  msf2: Add Emcraft's Smartfusion2 SOM kit.

 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   2 +-
 hw/arm/msf2_soc.c   | 141 +
 hw/misc/Makefile.objs   |   1 +
 hw/misc/msf2_sysreg.c   | 168 +++
 hw/ssi/Makefile.objs|   1 +
 hw/ssi/msf2_spi.c   | 449 
 hw/timer/Makefile.objs  |   1 +
 hw/timer/msf2_timer.c   | 273 
 9 files changed, 1036 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/msf2_soc.c
 create mode 100644 hw/misc/msf2_sysreg.c
 create mode 100644 hw/ssi/msf2_spi.c
 create mode 100644 hw/timer/msf2_timer.c

-- 
2.5.0




[Qemu-devel] [Qemu-devel RFC v2 1/4] msf2: Add Smartfusion2 System timer

2017-04-09 Thread Subbaraya Sundeep
Modelled System Timer in Microsemi's Smartfusion2 Soc.
Timer has two 32bit down counters and two interrupts.

Signed-off-by: Subbaraya Sundeep 
---
 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 000..962ada4
--- /dev/null
+++ b/hw/timer/msf2_timer.c
@@ -0,0 +1,273 @@
+/*
+ * Timer block model of Microsemi SmartFusion2.
+ *
+ * Copyright (c) 2017 Subbaraya Sundeep .
+ *
+ * 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_BGLOADVAL2
+#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

[Qemu-devel] [Qemu-devel RFC 2/3] msf2: Microsemi Smartfusion2 System Register block.

2017-03-19 Thread Subbaraya Sundeep
Added Sytem register block of Smartfusion2.
This block has PLL registers which are accessed by guest.

Signed-off-by: Subbaraya Sundeep 
---
 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 000..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 
+ *
+ * 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_sysre

[Qemu-devel] [Qemu-devel RFC 3/3] msf2: Add Emcraft's Smartfusion2 SOM kit.

2017-03-19 Thread Subbaraya Sundeep
Emulated Emcraft's Smartfusion2 System On Module starter
kit.

Signed-off-by: Subbaraya Sundeep 
---
 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 000..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 
+ *
+ * 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_ADDRESS0x6000
+#define ENVM_SIZE(128 * 1024)
+
+#define DDR_BASE_ADDRESS 0xA000
+#define DDR_SIZE (1024 * 1024 * 1024)
+
+#define SRAM_BASE_ADDRESS0x2000
+#define SRAM_SIZE(64 * 1024)
+
+#define MSF2_TIMER_BASE  0x40004000
+#define MSF2_SYSREG_BASE 0x40038000
+
+static const uint32_t usart_addr[MSF2_NUM_USARTS] = { 0x4000 };
+
+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);
+   

[Qemu-devel] [Qemu-devel RFC 1/3] msf2: Add Smartfusion2 System timer

2017-03-19 Thread Subbaraya Sundeep
Modelled System Timer in Microsemi's Smartfusion2 Soc.
Timer has two 32bit down counters and two interrupts.

Signed-off-by: Subbaraya Sundeep 
---
 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 000..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 .
+ *
+ * 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_BGLOADVAL2
+#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