[Qemu-devel] [[Qemu devel] RFC] hw/net: Add Smartfusion2 emac block
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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.
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.
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
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
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.
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
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.
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
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.
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.
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
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
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.
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.
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
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
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
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.
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.
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.
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
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.
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
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
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.
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.
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
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
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
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.
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.
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
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