qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH qemu v3 1/2] hw/arm: Add minimal support for the STM32L4x5 SoC
  2023-12-14 15:23 [PATCH qemu v3 0/2] Add minimal support for the B-L475E-IOT01A board ~inesvarhol
@ 2023-11-15  7:59 ` ~inesvarhol
  2023-12-15  5:29   ` Alistair Francis
  2023-11-15  8:04 ` [PATCH qemu v3 2/2] hw/arm: Add minimal support for the B-L475E-IOT01A board ~inesvarhol
  2023-12-18 14:53 ` [PATCH qemu v3 0/2] " Peter Maydell
  2 siblings, 1 reply; 6+ messages in thread
From: ~inesvarhol @ 2023-11-15  7:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-arm, alistair, philmd, peter.maydell, ines.varhol,
	arnaud.minier

From: Inès Varhol <ines.varhol@telecom-paris.fr>

This patch adds a new STM32L4x5 SoC, it is necessary to add support for
the B-L475E-IOT01A board.
The implementation is derived from the STM32F405 SoC.
The implementation contains no peripherals, only memory regions are
implemented.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>

Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
---
 MAINTAINERS                    |   8 +
 hw/arm/Kconfig                 |   5 +
 hw/arm/meson.build             |   1 +
 hw/arm/stm32l4x5_soc.c         | 268 +++++++++++++++++++++++++++++++++
 include/hw/arm/stm32l4x5_soc.h |  59 ++++++++
 5 files changed, 341 insertions(+)
 create mode 100644 hw/arm/stm32l4x5_soc.c
 create mode 100644 include/hw/arm/stm32l4x5_soc.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 695e0bd34f..e5b28aee28 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1123,6 +1123,14 @@ L: qemu-arm@nongnu.org
 S: Maintained
 F: hw/arm/olimex-stm32-h405.c
 
+STM32L4x5 SoC Family
+M: Arnaud Minier <arnaud.minier@telecom-paris.fr>
+M: Inès Varhol <ines.varhol@telecom-paris.fr>
+L: qemu-arm@nongnu.org
+S: Maintained
+F: hw/arm/stm32l4x5_soc.c
+F: include/hw/arm/stm32l4x5_soc.h
+
 SmartFusion2
 M: Subbaraya Sundeep <sundeep.lkml@gmail.com>
 M: Peter Maydell <peter.maydell@linaro.org>
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 3ada335a24..d2b94d9a47 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -448,6 +448,11 @@ config STM32F405_SOC
     select STM32F4XX_SYSCFG
     select STM32F4XX_EXTI
 
+config STM32L4X5_SOC
+    bool
+    select ARM_V7M
+    select OR_IRQ
+
 config XLNX_ZYNQMP_ARM
     bool
     default y if PIXMAN
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
index 68245d3ad1..9766da10c4 100644
--- a/hw/arm/meson.build
+++ b/hw/arm/meson.build
@@ -42,6 +42,7 @@ arm_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2836.c', 'raspi.c'))
 arm_ss.add(when: 'CONFIG_STM32F100_SOC', if_true: files('stm32f100_soc.c'))
 arm_ss.add(when: 'CONFIG_STM32F205_SOC', if_true: files('stm32f205_soc.c'))
 arm_ss.add(when: 'CONFIG_STM32F405_SOC', if_true: files('stm32f405_soc.c'))
+arm_ss.add(when: 'CONFIG_STM32L4X5_SOC', if_true: files('stm32l4x5_soc.c'))
 arm_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp.c', 'xlnx-zcu102.c'))
 arm_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal.c', 'xlnx-versal-virt.c'))
 arm_ss.add(when: 'CONFIG_FSL_IMX25', if_true: files('fsl-imx25.c', 'imx25_pdk.c'))
diff --git a/hw/arm/stm32l4x5_soc.c b/hw/arm/stm32l4x5_soc.c
new file mode 100644
index 0000000000..7513db0d6a
--- /dev/null
+++ b/hw/arm/stm32l4x5_soc.c
@@ -0,0 +1,268 @@
+/*
+ * STM32L4x5 SoC family
+ *
+ * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr>
+ * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * This work is heavily inspired by the stm32f405_soc by Alistair Francis.
+ * Original code is licensed under the MIT License:
+ *
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
+ */
+
+/*
+ * The reference used is the STMicroElectronics RM0351 Reference manual
+ * for STM32L4x5 and STM32L4x6 advanced Arm ® -based 32-bit MCUs.
+ * https://www.st.com/en/microcontrollers-microprocessors/stm32l4x5/documentation.html
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "exec/address-spaces.h"
+#include "sysemu/sysemu.h"
+#include "hw/arm/stm32l4x5_soc.h"
+#include "hw/qdev-clock.h"
+#include "hw/misc/unimp.h"
+
+#define FLASH_BASE_ADDRESS 0x08000000
+#define SRAM1_BASE_ADDRESS 0x20000000
+#define SRAM1_SIZE (96 * KiB)
+#define SRAM2_BASE_ADDRESS 0x10000000
+#define SRAM2_SIZE (32 * KiB)
+
+static void stm32l4x5_soc_initfn(Object *obj)
+{
+    Stm32l4x5SocState *s = STM32L4X5_SOC(obj);
+
+    s->sysclk = qdev_init_clock_in(DEVICE(s), "sysclk", NULL, NULL, 0);
+    s->refclk = qdev_init_clock_in(DEVICE(s), "refclk", NULL, NULL, 0);
+}
+
+static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp)
+{
+    ERRP_GUARD();
+    Stm32l4x5SocState *s = STM32L4X5_SOC(dev_soc);
+    const Stm32l4x5SocClass *sc = STM32L4X5_SOC_GET_CLASS(dev_soc);
+    MemoryRegion *system_memory = get_system_memory();
+    DeviceState *armv7m;
+
+    /*
+     * We use s->refclk internally and only define it with qdev_init_clock_in()
+     * so it is correctly parented and not leaked on an init/deinit; it is not
+     * intended as an externally exposed clock.
+     */
+    if (clock_has_source(s->refclk)) {
+        error_setg(errp, "refclk clock must not be wired up by the board code");
+        return;
+    }
+
+    if (!clock_has_source(s->sysclk)) {
+        error_setg(errp, "sysclk clock must be wired up by the board code");
+        return;
+    }
+
+    /*
+     * TODO: ideally we should model the SoC RCC and its ability to
+     * change the sysclk frequency and define different sysclk sources.
+     */
+
+    /* The refclk always runs at frequency HCLK / 8 */
+    clock_set_mul_div(s->refclk, 8, 1);
+    clock_set_source(s->refclk, s->sysclk);
+
+    memory_region_init_rom(&s->flash, OBJECT(dev_soc), "flash",
+                           sc->flash_size, errp);
+    if (*errp) {
+        return;
+    }
+    memory_region_init_alias(&s->flash_alias, OBJECT(dev_soc),
+                             "flash_boot_alias", &s->flash, 0,
+                             sc->flash_size);
+
+    memory_region_add_subregion(system_memory, FLASH_BASE_ADDRESS, &s->flash);
+    memory_region_add_subregion(system_memory, 0, &s->flash_alias);
+
+    memory_region_init_ram(&s->sram1, OBJECT(dev_soc), "SRAM1", SRAM1_SIZE,
+                           errp);
+    if (*errp) {
+        return;
+    }
+    memory_region_add_subregion(system_memory, SRAM1_BASE_ADDRESS, &s->sram1);
+
+    memory_region_init_ram(&s->sram2, OBJECT(dev_soc), "SRAM2", SRAM2_SIZE,
+                           errp);
+    if (*errp) {
+        return;
+    }
+    memory_region_add_subregion(system_memory, SRAM2_BASE_ADDRESS, &s->sram2);
+
+    object_initialize_child(OBJECT(dev_soc), "armv7m", &s->armv7m, TYPE_ARMV7M);
+    armv7m = DEVICE(&s->armv7m);
+    qdev_prop_set_uint32(armv7m, "num-irq", 96);
+    qdev_prop_set_string(armv7m, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m4"));
+    qdev_prop_set_bit(armv7m, "enable-bitband", true);
+    qdev_connect_clock_in(armv7m, "cpuclk", s->sysclk);
+    qdev_connect_clock_in(armv7m, "refclk", s->refclk);
+    object_property_set_link(OBJECT(&s->armv7m), "memory",
+                             OBJECT(system_memory), &error_abort);
+    if (!sysbus_realize(SYS_BUS_DEVICE(&s->armv7m), errp)) {
+        return;
+    }
+
+    /* APB1 BUS */
+    create_unimplemented_device("TIM2",      0x40000000, 0x400);
+    create_unimplemented_device("TIM3",      0x40000400, 0x400);
+    create_unimplemented_device("TIM4",      0x40000800, 0x400);
+    create_unimplemented_device("TIM5",      0x40000C00, 0x400);
+    create_unimplemented_device("TIM6",      0x40001000, 0x400);
+    create_unimplemented_device("TIM7",      0x40001400, 0x400);
+    /* RESERVED:    0x40001800, 0x1000 */
+    create_unimplemented_device("RTC",       0x40002800, 0x400);
+    create_unimplemented_device("WWDG",      0x40002C00, 0x400);
+    create_unimplemented_device("IWDG",      0x40003000, 0x400);
+    /* RESERVED:    0x40001800, 0x400 */
+    create_unimplemented_device("SPI2",      0x40003800, 0x400);
+    create_unimplemented_device("SPI3",      0x40003C00, 0x400);
+    /* RESERVED:    0x40004000, 0x400 */
+    create_unimplemented_device("USART2",    0x40004400, 0x400);
+    create_unimplemented_device("USART3",    0x40004800, 0x400);
+    create_unimplemented_device("UART4",     0x40004C00, 0x400);
+    create_unimplemented_device("UART5",     0x40005000, 0x400);
+    create_unimplemented_device("I2C1",      0x40005400, 0x400);
+    create_unimplemented_device("I2C2",      0x40005800, 0x400);
+    create_unimplemented_device("I2C3",      0x40005C00, 0x400);
+    /* RESERVED:    0x40006000, 0x400 */
+    create_unimplemented_device("CAN1",      0x40006400, 0x400);
+    /* RESERVED:    0x40006800, 0x400 */
+    create_unimplemented_device("PWR",       0x40007000, 0x400);
+    create_unimplemented_device("DAC1",      0x40007400, 0x400);
+    create_unimplemented_device("OPAMP",     0x40007800, 0x400);
+    create_unimplemented_device("LPTIM1",    0x40007C00, 0x400);
+    create_unimplemented_device("LPUART1",   0x40008000, 0x400);
+    /* RESERVED:    0x40008400, 0x400 */
+    create_unimplemented_device("SWPMI1",    0x40008800, 0x400);
+    /* RESERVED:    0x40008C00, 0x800 */
+    create_unimplemented_device("LPTIM2",    0x40009400, 0x400);
+    /* RESERVED:    0x40009800, 0x6800 */
+
+    /* APB2 BUS */
+    create_unimplemented_device("SYSCFG",    0x40010000, 0x30);
+    create_unimplemented_device("VREFBUF",   0x40010030, 0x1D0);
+    create_unimplemented_device("COMP",      0x40010200, 0x200);
+    create_unimplemented_device("EXTI",      0x40010400, 0x400);
+    /* RESERVED:    0x40010800, 0x1400 */
+    create_unimplemented_device("FIREWALL",  0x40011C00, 0x400);
+    /* RESERVED:    0x40012000, 0x800 */
+    create_unimplemented_device("SDMMC1",    0x40012800, 0x400);
+    create_unimplemented_device("TIM1",      0x40012C00, 0x400);
+    create_unimplemented_device("SPI1",      0x40013000, 0x400);
+    create_unimplemented_device("TIM8",      0x40013400, 0x400);
+    create_unimplemented_device("USART1",    0x40013800, 0x400);
+    /* RESERVED:    0x40013C00, 0x400 */
+    create_unimplemented_device("TIM15",     0x40014000, 0x400);
+    create_unimplemented_device("TIM16",     0x40014400, 0x400);
+    create_unimplemented_device("TIM17",     0x40014800, 0x400);
+    /* RESERVED:    0x40014C00, 0x800 */
+    create_unimplemented_device("SAI1",      0x40015400, 0x400);
+    create_unimplemented_device("SAI2",      0x40015800, 0x400);
+    /* RESERVED:    0x40015C00, 0x400 */
+    create_unimplemented_device("DFSDM1",    0x40016000, 0x400);
+    /* RESERVED:    0x40016400, 0x9C00 */
+
+    /* AHB1 BUS */
+    create_unimplemented_device("DMA1",      0x40020000, 0x400);
+    create_unimplemented_device("DMA2",      0x40020400, 0x400);
+    /* RESERVED:    0x40020800, 0x800 */
+    create_unimplemented_device("RCC",       0x40021000, 0x400);
+    /* RESERVED:    0x40021400, 0xC00 */
+    create_unimplemented_device("FLASH",     0x40022000, 0x400);
+    /* RESERVED:    0x40022400, 0xC00 */
+    create_unimplemented_device("CRC",       0x40023000, 0x400);
+    /* RESERVED:    0x40023400, 0x400 */
+    create_unimplemented_device("TSC",       0x40024000, 0x400);
+
+    /* RESERVED:    0x40024400, 0x7FDBC00 */
+
+    /* AHB2 BUS */
+    create_unimplemented_device("GPIOA",     0x48000000, 0x400);
+    create_unimplemented_device("GPIOB",     0x48000400, 0x400);
+    create_unimplemented_device("GPIOC",     0x48000800, 0x400);
+    create_unimplemented_device("GPIOD",     0x48000C00, 0x400);
+    create_unimplemented_device("GPIOE",     0x48001000, 0x400);
+    create_unimplemented_device("GPIOF",     0x48001400, 0x400);
+    create_unimplemented_device("GPIOG",     0x48001800, 0x400);
+    create_unimplemented_device("GPIOH",     0x48001C00, 0x400);
+    /* RESERVED:    0x48002000, 0x7FDBC00 */
+    create_unimplemented_device("OTG_FS",    0x50000000, 0x40000);
+    create_unimplemented_device("ADC",       0x50040000, 0x400);
+    /* RESERVED:    0x50040400, 0x20400 */
+    create_unimplemented_device("RNG",       0x50060800, 0x400);
+
+    /* AHB3 BUS */
+    create_unimplemented_device("FMC",       0xA0000000, 0x1000);
+    create_unimplemented_device("QUADSPI",   0xA0001000, 0x400);
+}
+
+static void stm32l4x5_soc_class_init(ObjectClass *klass, void *data)
+{
+
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = stm32l4x5_soc_realize;
+    /* Reason: Mapped at fixed location on the system bus */
+    dc->user_creatable = false;
+    /* No vmstate or reset required: device has no internal state */
+}
+
+static void stm32l4x5xc_soc_class_init(ObjectClass *oc, void *data)
+{
+    Stm32l4x5SocClass *ssc = STM32L4X5_SOC_CLASS(oc);
+
+    ssc->flash_size = 256 * KiB;
+}
+
+static void stm32l4x5xe_soc_class_init(ObjectClass *oc, void *data)
+{
+    Stm32l4x5SocClass *ssc = STM32L4X5_SOC_CLASS(oc);
+
+    ssc->flash_size = 512 * KiB;
+}
+
+static void stm32l4x5xg_soc_class_init(ObjectClass *oc, void *data)
+{
+    Stm32l4x5SocClass *ssc = STM32L4X5_SOC_CLASS(oc);
+
+    ssc->flash_size = 1 * MiB;
+}
+
+static const TypeInfo stm32l4x5_soc_types[] = {
+    {
+        .name           = TYPE_STM32L4X5XC_SOC,
+        .parent         = TYPE_STM32L4X5_SOC,
+        .class_init     = stm32l4x5xc_soc_class_init,
+    }, {
+        .name           = TYPE_STM32L4X5XE_SOC,
+        .parent         = TYPE_STM32L4X5_SOC,
+        .class_init     = stm32l4x5xe_soc_class_init,
+    }, {
+        .name           = TYPE_STM32L4X5XG_SOC,
+        .parent         = TYPE_STM32L4X5_SOC,
+        .class_init     = stm32l4x5xg_soc_class_init,
+    }, {
+        .name           = TYPE_STM32L4X5_SOC,
+        .parent         = TYPE_SYS_BUS_DEVICE,
+        .instance_size  = sizeof(Stm32l4x5SocState),
+        .instance_init  = stm32l4x5_soc_initfn,
+        .class_size     = sizeof(Stm32l4x5SocClass),
+        .class_init     = stm32l4x5_soc_class_init,
+        .abstract       = true,
+    }
+};
+
+DEFINE_TYPES(stm32l4x5_soc_types)
diff --git a/include/hw/arm/stm32l4x5_soc.h b/include/hw/arm/stm32l4x5_soc.h
new file mode 100644
index 0000000000..dce13a023d
--- /dev/null
+++ b/include/hw/arm/stm32l4x5_soc.h
@@ -0,0 +1,59 @@
+/*
+ * STM32L4x5 SoC family
+ *
+ * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr>
+ * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * This work is heavily inspired by the stm32f405_soc by Alistair Francis.
+ * Original code is licensed under the MIT License:
+ *
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
+ */
+
+/*
+ * The reference used is the STMicroElectronics RM0351 Reference manual
+ * for STM32L4x5 and STM32L4x6 advanced Arm ® -based 32-bit MCUs.
+ * https://www.st.com/en/microcontrollers-microprocessors/stm32l4x5/documentation.html
+ */
+
+#ifndef HW_ARM_STM32L4x5_SOC_H
+#define HW_ARM_STM32L4x5_SOC_H
+
+#include "exec/memory.h"
+#include "qemu/units.h"
+#include "hw/qdev-core.h"
+#include "hw/arm/armv7m.h"
+#include "qom/object.h"
+
+#define TYPE_STM32L4X5_SOC "stm32l4x5-soc"
+#define TYPE_STM32L4X5XC_SOC "stm32l4x5xc-soc"
+#define TYPE_STM32L4X5XE_SOC "stm32l4x5xe-soc"
+#define TYPE_STM32L4X5XG_SOC "stm32l4x5xg-soc"
+OBJECT_DECLARE_TYPE(Stm32l4x5SocState, Stm32l4x5SocClass, STM32L4X5_SOC)
+
+struct Stm32l4x5SocState {
+    SysBusDevice parent_obj;
+
+    ARMv7MState armv7m;
+
+    MemoryRegion sram1;
+    MemoryRegion sram2;
+    MemoryRegion flash;
+    MemoryRegion flash_alias;
+
+    Clock *sysclk;
+    Clock *refclk;
+};
+
+struct Stm32l4x5SocClass {
+    SysBusDeviceClass parent_class;
+
+    size_t flash_size;
+};
+
+#endif
-- 
2.38.5



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

* [PATCH qemu v3 2/2] hw/arm: Add minimal support for the B-L475E-IOT01A board
  2023-12-14 15:23 [PATCH qemu v3 0/2] Add minimal support for the B-L475E-IOT01A board ~inesvarhol
  2023-11-15  7:59 ` [PATCH qemu v3 1/2] hw/arm: Add minimal support for the STM32L4x5 SoC ~inesvarhol
@ 2023-11-15  8:04 ` ~inesvarhol
  2023-12-15  5:30   ` Alistair Francis
  2023-12-18 14:53 ` [PATCH qemu v3 0/2] " Peter Maydell
  2 siblings, 1 reply; 6+ messages in thread
From: ~inesvarhol @ 2023-11-15  8:04 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-arm, alistair, philmd, peter.maydell, ines.varhol,
	arnaud.minier

From: Inès Varhol <ines.varhol@telecom-paris.fr>

This commit adds a new B-L475E-IOT01A board using the STM32L475VG SoC.
The implementation is derived from the Netduino Plus 2 machine.
There are no peripherals implemented yet, only memory regions.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>

Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
---
 MAINTAINERS                             |  7 +++
 configs/devices/arm-softmmu/default.mak |  1 +
 hw/arm/Kconfig                          |  6 +++
 hw/arm/b-l475e-iot01a.c                 | 70 +++++++++++++++++++++++++
 hw/arm/meson.build                      |  1 +
 5 files changed, 85 insertions(+)
 create mode 100644 hw/arm/b-l475e-iot01a.c

diff --git a/MAINTAINERS b/MAINTAINERS
index e5b28aee28..3f3831c92a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1131,6 +1131,13 @@ S: Maintained
 F: hw/arm/stm32l4x5_soc.c
 F: include/hw/arm/stm32l4x5_soc.h
 
+B-L475E-IOT01A IoT Node
+M: Arnaud Minier <arnaud.minier@telecom-paris.fr>
+M: Inès Varhol <ines.varhol@telecom-paris.fr>
+L: qemu-arm@nongnu.org
+S: Maintained
+F: hw/arm/b-l475e-iot01a.c
+
 SmartFusion2
 M: Subbaraya Sundeep <sundeep.lkml@gmail.com>
 M: Peter Maydell <peter.maydell@linaro.org>
diff --git a/configs/devices/arm-softmmu/default.mak b/configs/devices/arm-softmmu/default.mak
index 980c48a7d9..023faa2f75 100644
--- a/configs/devices/arm-softmmu/default.mak
+++ b/configs/devices/arm-softmmu/default.mak
@@ -19,6 +19,7 @@ CONFIG_ARM_VIRT=y
 # CONFIG_NSERIES=n
 # CONFIG_STELLARIS=n
 # CONFIG_STM32VLDISCOVERY=n
+# CONFIG_B_L475E_IOT01A=n
 # CONFIG_REALVIEW=n
 # CONFIG_VERSATILE=n
 # CONFIG_VEXPRESS=n
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index d2b94d9a47..7520dc5cc0 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -448,6 +448,12 @@ config STM32F405_SOC
     select STM32F4XX_SYSCFG
     select STM32F4XX_EXTI
 
+config B_L475E_IOT01A
+    bool
+    default y
+    depends on TCG && ARM
+    select STM32L4X5_SOC
+
 config STM32L4X5_SOC
     bool
     select ARM_V7M
diff --git a/hw/arm/b-l475e-iot01a.c b/hw/arm/b-l475e-iot01a.c
new file mode 100644
index 0000000000..c3790e3dc8
--- /dev/null
+++ b/hw/arm/b-l475e-iot01a.c
@@ -0,0 +1,70 @@
+/*
+ * B-L475E-IOT01A Discovery Kit machine
+ * (B-L475E-IOT01A IoT Node)
+ *
+ * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr>
+ * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * This work is heavily inspired by the netduinoplus2 by Alistair Francis.
+ * Original code is licensed under the MIT License:
+ *
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
+ */
+
+/*
+ * The reference used is the STMicroElectronics UM2153 User manual
+ * Discovery kit for IoT node, multi-channel communication with STM32L4.
+ * https://www.st.com/en/evaluation-tools/b-l475e-iot01a.html#documentation
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/boards.h"
+#include "hw/qdev-properties.h"
+#include "hw/qdev-clock.h"
+#include "qemu/error-report.h"
+#include "hw/arm/stm32l4x5_soc.h"
+#include "hw/arm/boot.h"
+
+/* Main SYSCLK frequency in Hz (80MHz) */
+#define SYSCLK_FRQ 80000000ULL
+
+static void b_l475e_iot01a_init(MachineState *machine)
+{
+    const Stm32l4x5SocClass *sc;
+    DeviceState *dev;
+    Clock *sysclk;
+
+    /* This clock doesn't need migration because it is fixed-frequency */
+    sysclk = clock_new(OBJECT(machine), "SYSCLK");
+    clock_set_hz(sysclk, SYSCLK_FRQ);
+
+    dev = qdev_new(TYPE_STM32L4X5XG_SOC);
+    sc = STM32L4X5_SOC_GET_CLASS(dev);
+    qdev_connect_clock_in(dev, "sysclk", sysclk);
+    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+
+    armv7m_load_kernel(ARM_CPU(first_cpu),
+                       machine->kernel_filename,
+                       0, sc->flash_size);
+}
+
+static void b_l475e_iot01a_machine_init(MachineClass *mc)
+{
+    static const char *machine_valid_cpu_types[] = {
+        ARM_CPU_TYPE_NAME("cortex-m4"),
+        NULL};
+    mc->desc = "B-L475E-IOT01A Discovery Kit (Cortex-M4)";
+    mc->init = b_l475e_iot01a_init;
+    mc->valid_cpu_types = machine_valid_cpu_types;
+
+    /* SRAM pre-allocated as part of the SoC instantiation */
+    mc->default_ram_size = 0;
+}
+
+DEFINE_MACHINE("b-l475e-iot01a", b_l475e_iot01a_machine_init)
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
index 9766da10c4..bb92b27db3 100644
--- a/hw/arm/meson.build
+++ b/hw/arm/meson.build
@@ -42,6 +42,7 @@ arm_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2836.c', 'raspi.c'))
 arm_ss.add(when: 'CONFIG_STM32F100_SOC', if_true: files('stm32f100_soc.c'))
 arm_ss.add(when: 'CONFIG_STM32F205_SOC', if_true: files('stm32f205_soc.c'))
 arm_ss.add(when: 'CONFIG_STM32F405_SOC', if_true: files('stm32f405_soc.c'))
+arm_ss.add(when: 'CONFIG_B_L475E_IOT01A', if_true: files('b-l475e-iot01a.c'))
 arm_ss.add(when: 'CONFIG_STM32L4X5_SOC', if_true: files('stm32l4x5_soc.c'))
 arm_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp.c', 'xlnx-zcu102.c'))
 arm_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal.c', 'xlnx-versal-virt.c'))
-- 
2.38.5


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

* [PATCH qemu v3 0/2] Add minimal support for the B-L475E-IOT01A board
@ 2023-12-14 15:23 ~inesvarhol
  2023-11-15  7:59 ` [PATCH qemu v3 1/2] hw/arm: Add minimal support for the STM32L4x5 SoC ~inesvarhol
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: ~inesvarhol @ 2023-12-14 15:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-arm, alistair, philmd, peter.maydell, ines.varhol,
	arnaud.minier

This patch adds a new STM32L4x5 SoC, it is necessary to add support for
the B-L475E-IOT01A board.
The implementation is derived from the STM32F405 SoC and NetduinoPlus2
board.
The implementation contains no peripherals, only memory regions are
implemented.

Sorry about the inconsistency in licenses in v2, I changed them.
Should I clarify anything further? Thank you.

Changes from v1 to v3:
Changing the MIT license to GPL.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>

Inès Varhol (2):
  hw/arm: Add minimal support for the STM32L4x5 SoC
  hw/arm: Add minimal support for the B-L475E-IOT01A board

 MAINTAINERS                             |  15 ++
 configs/devices/arm-softmmu/default.mak |   1 +
 hw/arm/Kconfig                          |  11 +
 hw/arm/b-l475e-iot01a.c                 |  70 +++++++
 hw/arm/meson.build                      |   2 +
 hw/arm/stm32l4x5_soc.c                  | 268 ++++++++++++++++++++++++
 include/hw/arm/stm32l4x5_soc.h          |  59 ++++++
 7 files changed, 426 insertions(+)
 create mode 100644 hw/arm/b-l475e-iot01a.c
 create mode 100644 hw/arm/stm32l4x5_soc.c
 create mode 100644 include/hw/arm/stm32l4x5_soc.h

-- 
2.38.5


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

* Re: [PATCH qemu v3 1/2] hw/arm: Add minimal support for the STM32L4x5 SoC
  2023-11-15  7:59 ` [PATCH qemu v3 1/2] hw/arm: Add minimal support for the STM32L4x5 SoC ~inesvarhol
@ 2023-12-15  5:29   ` Alistair Francis
  0 siblings, 0 replies; 6+ messages in thread
From: Alistair Francis @ 2023-12-15  5:29 UTC (permalink / raw)
  To: ~inesvarhol
  Cc: qemu-devel, qemu-arm, alistair, philmd, peter.maydell,
	ines.varhol, arnaud.minier

On Fri, Dec 15, 2023 at 1:24 AM ~inesvarhol <inesvarhol@git.sr.ht> wrote:
>
> From: Inès Varhol <ines.varhol@telecom-paris.fr>
>
> This patch adds a new STM32L4x5 SoC, it is necessary to add support for
> the B-L475E-IOT01A board.
> The implementation is derived from the STM32F405 SoC.
> The implementation contains no peripherals, only memory regions are
> implemented.
>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
>
> Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
> Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>

Acked-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  MAINTAINERS                    |   8 +
>  hw/arm/Kconfig                 |   5 +
>  hw/arm/meson.build             |   1 +
>  hw/arm/stm32l4x5_soc.c         | 268 +++++++++++++++++++++++++++++++++
>  include/hw/arm/stm32l4x5_soc.h |  59 ++++++++
>  5 files changed, 341 insertions(+)
>  create mode 100644 hw/arm/stm32l4x5_soc.c
>  create mode 100644 include/hw/arm/stm32l4x5_soc.h
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 695e0bd34f..e5b28aee28 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1123,6 +1123,14 @@ L: qemu-arm@nongnu.org
>  S: Maintained
>  F: hw/arm/olimex-stm32-h405.c
>
> +STM32L4x5 SoC Family
> +M: Arnaud Minier <arnaud.minier@telecom-paris.fr>
> +M: Inès Varhol <ines.varhol@telecom-paris.fr>
> +L: qemu-arm@nongnu.org
> +S: Maintained
> +F: hw/arm/stm32l4x5_soc.c
> +F: include/hw/arm/stm32l4x5_soc.h
> +
>  SmartFusion2
>  M: Subbaraya Sundeep <sundeep.lkml@gmail.com>
>  M: Peter Maydell <peter.maydell@linaro.org>
> diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
> index 3ada335a24..d2b94d9a47 100644
> --- a/hw/arm/Kconfig
> +++ b/hw/arm/Kconfig
> @@ -448,6 +448,11 @@ config STM32F405_SOC
>      select STM32F4XX_SYSCFG
>      select STM32F4XX_EXTI
>
> +config STM32L4X5_SOC
> +    bool
> +    select ARM_V7M
> +    select OR_IRQ
> +
>  config XLNX_ZYNQMP_ARM
>      bool
>      default y if PIXMAN
> diff --git a/hw/arm/meson.build b/hw/arm/meson.build
> index 68245d3ad1..9766da10c4 100644
> --- a/hw/arm/meson.build
> +++ b/hw/arm/meson.build
> @@ -42,6 +42,7 @@ arm_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2836.c', 'raspi.c'))
>  arm_ss.add(when: 'CONFIG_STM32F100_SOC', if_true: files('stm32f100_soc.c'))
>  arm_ss.add(when: 'CONFIG_STM32F205_SOC', if_true: files('stm32f205_soc.c'))
>  arm_ss.add(when: 'CONFIG_STM32F405_SOC', if_true: files('stm32f405_soc.c'))
> +arm_ss.add(when: 'CONFIG_STM32L4X5_SOC', if_true: files('stm32l4x5_soc.c'))
>  arm_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp.c', 'xlnx-zcu102.c'))
>  arm_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal.c', 'xlnx-versal-virt.c'))
>  arm_ss.add(when: 'CONFIG_FSL_IMX25', if_true: files('fsl-imx25.c', 'imx25_pdk.c'))
> diff --git a/hw/arm/stm32l4x5_soc.c b/hw/arm/stm32l4x5_soc.c
> new file mode 100644
> index 0000000000..7513db0d6a
> --- /dev/null
> +++ b/hw/arm/stm32l4x5_soc.c
> @@ -0,0 +1,268 @@
> +/*
> + * STM32L4x5 SoC family
> + *
> + * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr>
> + * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr>
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + *
> + * This work is heavily inspired by the stm32f405_soc by Alistair Francis.
> + * Original code is licensed under the MIT License:
> + *
> + * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
> + */
> +
> +/*
> + * The reference used is the STMicroElectronics RM0351 Reference manual
> + * for STM32L4x5 and STM32L4x6 advanced Arm ® -based 32-bit MCUs.
> + * https://www.st.com/en/microcontrollers-microprocessors/stm32l4x5/documentation.html
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/units.h"
> +#include "qapi/error.h"
> +#include "exec/address-spaces.h"
> +#include "sysemu/sysemu.h"
> +#include "hw/arm/stm32l4x5_soc.h"
> +#include "hw/qdev-clock.h"
> +#include "hw/misc/unimp.h"
> +
> +#define FLASH_BASE_ADDRESS 0x08000000
> +#define SRAM1_BASE_ADDRESS 0x20000000
> +#define SRAM1_SIZE (96 * KiB)
> +#define SRAM2_BASE_ADDRESS 0x10000000
> +#define SRAM2_SIZE (32 * KiB)
> +
> +static void stm32l4x5_soc_initfn(Object *obj)
> +{
> +    Stm32l4x5SocState *s = STM32L4X5_SOC(obj);
> +
> +    s->sysclk = qdev_init_clock_in(DEVICE(s), "sysclk", NULL, NULL, 0);
> +    s->refclk = qdev_init_clock_in(DEVICE(s), "refclk", NULL, NULL, 0);
> +}
> +
> +static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp)
> +{
> +    ERRP_GUARD();
> +    Stm32l4x5SocState *s = STM32L4X5_SOC(dev_soc);
> +    const Stm32l4x5SocClass *sc = STM32L4X5_SOC_GET_CLASS(dev_soc);
> +    MemoryRegion *system_memory = get_system_memory();
> +    DeviceState *armv7m;
> +
> +    /*
> +     * We use s->refclk internally and only define it with qdev_init_clock_in()
> +     * so it is correctly parented and not leaked on an init/deinit; it is not
> +     * intended as an externally exposed clock.
> +     */
> +    if (clock_has_source(s->refclk)) {
> +        error_setg(errp, "refclk clock must not be wired up by the board code");
> +        return;
> +    }
> +
> +    if (!clock_has_source(s->sysclk)) {
> +        error_setg(errp, "sysclk clock must be wired up by the board code");
> +        return;
> +    }
> +
> +    /*
> +     * TODO: ideally we should model the SoC RCC and its ability to
> +     * change the sysclk frequency and define different sysclk sources.
> +     */
> +
> +    /* The refclk always runs at frequency HCLK / 8 */
> +    clock_set_mul_div(s->refclk, 8, 1);
> +    clock_set_source(s->refclk, s->sysclk);
> +
> +    memory_region_init_rom(&s->flash, OBJECT(dev_soc), "flash",
> +                           sc->flash_size, errp);
> +    if (*errp) {
> +        return;
> +    }
> +    memory_region_init_alias(&s->flash_alias, OBJECT(dev_soc),
> +                             "flash_boot_alias", &s->flash, 0,
> +                             sc->flash_size);
> +
> +    memory_region_add_subregion(system_memory, FLASH_BASE_ADDRESS, &s->flash);
> +    memory_region_add_subregion(system_memory, 0, &s->flash_alias);
> +
> +    memory_region_init_ram(&s->sram1, OBJECT(dev_soc), "SRAM1", SRAM1_SIZE,
> +                           errp);
> +    if (*errp) {
> +        return;
> +    }
> +    memory_region_add_subregion(system_memory, SRAM1_BASE_ADDRESS, &s->sram1);
> +
> +    memory_region_init_ram(&s->sram2, OBJECT(dev_soc), "SRAM2", SRAM2_SIZE,
> +                           errp);
> +    if (*errp) {
> +        return;
> +    }
> +    memory_region_add_subregion(system_memory, SRAM2_BASE_ADDRESS, &s->sram2);
> +
> +    object_initialize_child(OBJECT(dev_soc), "armv7m", &s->armv7m, TYPE_ARMV7M);
> +    armv7m = DEVICE(&s->armv7m);
> +    qdev_prop_set_uint32(armv7m, "num-irq", 96);
> +    qdev_prop_set_string(armv7m, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m4"));
> +    qdev_prop_set_bit(armv7m, "enable-bitband", true);
> +    qdev_connect_clock_in(armv7m, "cpuclk", s->sysclk);
> +    qdev_connect_clock_in(armv7m, "refclk", s->refclk);
> +    object_property_set_link(OBJECT(&s->armv7m), "memory",
> +                             OBJECT(system_memory), &error_abort);
> +    if (!sysbus_realize(SYS_BUS_DEVICE(&s->armv7m), errp)) {
> +        return;
> +    }
> +
> +    /* APB1 BUS */
> +    create_unimplemented_device("TIM2",      0x40000000, 0x400);
> +    create_unimplemented_device("TIM3",      0x40000400, 0x400);
> +    create_unimplemented_device("TIM4",      0x40000800, 0x400);
> +    create_unimplemented_device("TIM5",      0x40000C00, 0x400);
> +    create_unimplemented_device("TIM6",      0x40001000, 0x400);
> +    create_unimplemented_device("TIM7",      0x40001400, 0x400);
> +    /* RESERVED:    0x40001800, 0x1000 */
> +    create_unimplemented_device("RTC",       0x40002800, 0x400);
> +    create_unimplemented_device("WWDG",      0x40002C00, 0x400);
> +    create_unimplemented_device("IWDG",      0x40003000, 0x400);
> +    /* RESERVED:    0x40001800, 0x400 */
> +    create_unimplemented_device("SPI2",      0x40003800, 0x400);
> +    create_unimplemented_device("SPI3",      0x40003C00, 0x400);
> +    /* RESERVED:    0x40004000, 0x400 */
> +    create_unimplemented_device("USART2",    0x40004400, 0x400);
> +    create_unimplemented_device("USART3",    0x40004800, 0x400);
> +    create_unimplemented_device("UART4",     0x40004C00, 0x400);
> +    create_unimplemented_device("UART5",     0x40005000, 0x400);
> +    create_unimplemented_device("I2C1",      0x40005400, 0x400);
> +    create_unimplemented_device("I2C2",      0x40005800, 0x400);
> +    create_unimplemented_device("I2C3",      0x40005C00, 0x400);
> +    /* RESERVED:    0x40006000, 0x400 */
> +    create_unimplemented_device("CAN1",      0x40006400, 0x400);
> +    /* RESERVED:    0x40006800, 0x400 */
> +    create_unimplemented_device("PWR",       0x40007000, 0x400);
> +    create_unimplemented_device("DAC1",      0x40007400, 0x400);
> +    create_unimplemented_device("OPAMP",     0x40007800, 0x400);
> +    create_unimplemented_device("LPTIM1",    0x40007C00, 0x400);
> +    create_unimplemented_device("LPUART1",   0x40008000, 0x400);
> +    /* RESERVED:    0x40008400, 0x400 */
> +    create_unimplemented_device("SWPMI1",    0x40008800, 0x400);
> +    /* RESERVED:    0x40008C00, 0x800 */
> +    create_unimplemented_device("LPTIM2",    0x40009400, 0x400);
> +    /* RESERVED:    0x40009800, 0x6800 */
> +
> +    /* APB2 BUS */
> +    create_unimplemented_device("SYSCFG",    0x40010000, 0x30);
> +    create_unimplemented_device("VREFBUF",   0x40010030, 0x1D0);
> +    create_unimplemented_device("COMP",      0x40010200, 0x200);
> +    create_unimplemented_device("EXTI",      0x40010400, 0x400);
> +    /* RESERVED:    0x40010800, 0x1400 */
> +    create_unimplemented_device("FIREWALL",  0x40011C00, 0x400);
> +    /* RESERVED:    0x40012000, 0x800 */
> +    create_unimplemented_device("SDMMC1",    0x40012800, 0x400);
> +    create_unimplemented_device("TIM1",      0x40012C00, 0x400);
> +    create_unimplemented_device("SPI1",      0x40013000, 0x400);
> +    create_unimplemented_device("TIM8",      0x40013400, 0x400);
> +    create_unimplemented_device("USART1",    0x40013800, 0x400);
> +    /* RESERVED:    0x40013C00, 0x400 */
> +    create_unimplemented_device("TIM15",     0x40014000, 0x400);
> +    create_unimplemented_device("TIM16",     0x40014400, 0x400);
> +    create_unimplemented_device("TIM17",     0x40014800, 0x400);
> +    /* RESERVED:    0x40014C00, 0x800 */
> +    create_unimplemented_device("SAI1",      0x40015400, 0x400);
> +    create_unimplemented_device("SAI2",      0x40015800, 0x400);
> +    /* RESERVED:    0x40015C00, 0x400 */
> +    create_unimplemented_device("DFSDM1",    0x40016000, 0x400);
> +    /* RESERVED:    0x40016400, 0x9C00 */
> +
> +    /* AHB1 BUS */
> +    create_unimplemented_device("DMA1",      0x40020000, 0x400);
> +    create_unimplemented_device("DMA2",      0x40020400, 0x400);
> +    /* RESERVED:    0x40020800, 0x800 */
> +    create_unimplemented_device("RCC",       0x40021000, 0x400);
> +    /* RESERVED:    0x40021400, 0xC00 */
> +    create_unimplemented_device("FLASH",     0x40022000, 0x400);
> +    /* RESERVED:    0x40022400, 0xC00 */
> +    create_unimplemented_device("CRC",       0x40023000, 0x400);
> +    /* RESERVED:    0x40023400, 0x400 */
> +    create_unimplemented_device("TSC",       0x40024000, 0x400);
> +
> +    /* RESERVED:    0x40024400, 0x7FDBC00 */
> +
> +    /* AHB2 BUS */
> +    create_unimplemented_device("GPIOA",     0x48000000, 0x400);
> +    create_unimplemented_device("GPIOB",     0x48000400, 0x400);
> +    create_unimplemented_device("GPIOC",     0x48000800, 0x400);
> +    create_unimplemented_device("GPIOD",     0x48000C00, 0x400);
> +    create_unimplemented_device("GPIOE",     0x48001000, 0x400);
> +    create_unimplemented_device("GPIOF",     0x48001400, 0x400);
> +    create_unimplemented_device("GPIOG",     0x48001800, 0x400);
> +    create_unimplemented_device("GPIOH",     0x48001C00, 0x400);
> +    /* RESERVED:    0x48002000, 0x7FDBC00 */
> +    create_unimplemented_device("OTG_FS",    0x50000000, 0x40000);
> +    create_unimplemented_device("ADC",       0x50040000, 0x400);
> +    /* RESERVED:    0x50040400, 0x20400 */
> +    create_unimplemented_device("RNG",       0x50060800, 0x400);
> +
> +    /* AHB3 BUS */
> +    create_unimplemented_device("FMC",       0xA0000000, 0x1000);
> +    create_unimplemented_device("QUADSPI",   0xA0001000, 0x400);
> +}
> +
> +static void stm32l4x5_soc_class_init(ObjectClass *klass, void *data)
> +{
> +
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +
> +    dc->realize = stm32l4x5_soc_realize;
> +    /* Reason: Mapped at fixed location on the system bus */
> +    dc->user_creatable = false;
> +    /* No vmstate or reset required: device has no internal state */
> +}
> +
> +static void stm32l4x5xc_soc_class_init(ObjectClass *oc, void *data)
> +{
> +    Stm32l4x5SocClass *ssc = STM32L4X5_SOC_CLASS(oc);
> +
> +    ssc->flash_size = 256 * KiB;
> +}
> +
> +static void stm32l4x5xe_soc_class_init(ObjectClass *oc, void *data)
> +{
> +    Stm32l4x5SocClass *ssc = STM32L4X5_SOC_CLASS(oc);
> +
> +    ssc->flash_size = 512 * KiB;
> +}
> +
> +static void stm32l4x5xg_soc_class_init(ObjectClass *oc, void *data)
> +{
> +    Stm32l4x5SocClass *ssc = STM32L4X5_SOC_CLASS(oc);
> +
> +    ssc->flash_size = 1 * MiB;
> +}
> +
> +static const TypeInfo stm32l4x5_soc_types[] = {
> +    {
> +        .name           = TYPE_STM32L4X5XC_SOC,
> +        .parent         = TYPE_STM32L4X5_SOC,
> +        .class_init     = stm32l4x5xc_soc_class_init,
> +    }, {
> +        .name           = TYPE_STM32L4X5XE_SOC,
> +        .parent         = TYPE_STM32L4X5_SOC,
> +        .class_init     = stm32l4x5xe_soc_class_init,
> +    }, {
> +        .name           = TYPE_STM32L4X5XG_SOC,
> +        .parent         = TYPE_STM32L4X5_SOC,
> +        .class_init     = stm32l4x5xg_soc_class_init,
> +    }, {
> +        .name           = TYPE_STM32L4X5_SOC,
> +        .parent         = TYPE_SYS_BUS_DEVICE,
> +        .instance_size  = sizeof(Stm32l4x5SocState),
> +        .instance_init  = stm32l4x5_soc_initfn,
> +        .class_size     = sizeof(Stm32l4x5SocClass),
> +        .class_init     = stm32l4x5_soc_class_init,
> +        .abstract       = true,
> +    }
> +};
> +
> +DEFINE_TYPES(stm32l4x5_soc_types)
> diff --git a/include/hw/arm/stm32l4x5_soc.h b/include/hw/arm/stm32l4x5_soc.h
> new file mode 100644
> index 0000000000..dce13a023d
> --- /dev/null
> +++ b/include/hw/arm/stm32l4x5_soc.h
> @@ -0,0 +1,59 @@
> +/*
> + * STM32L4x5 SoC family
> + *
> + * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr>
> + * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr>
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + *
> + * This work is heavily inspired by the stm32f405_soc by Alistair Francis.
> + * Original code is licensed under the MIT License:
> + *
> + * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
> + */
> +
> +/*
> + * The reference used is the STMicroElectronics RM0351 Reference manual
> + * for STM32L4x5 and STM32L4x6 advanced Arm ® -based 32-bit MCUs.
> + * https://www.st.com/en/microcontrollers-microprocessors/stm32l4x5/documentation.html
> + */
> +
> +#ifndef HW_ARM_STM32L4x5_SOC_H
> +#define HW_ARM_STM32L4x5_SOC_H
> +
> +#include "exec/memory.h"
> +#include "qemu/units.h"
> +#include "hw/qdev-core.h"
> +#include "hw/arm/armv7m.h"
> +#include "qom/object.h"
> +
> +#define TYPE_STM32L4X5_SOC "stm32l4x5-soc"
> +#define TYPE_STM32L4X5XC_SOC "stm32l4x5xc-soc"
> +#define TYPE_STM32L4X5XE_SOC "stm32l4x5xe-soc"
> +#define TYPE_STM32L4X5XG_SOC "stm32l4x5xg-soc"
> +OBJECT_DECLARE_TYPE(Stm32l4x5SocState, Stm32l4x5SocClass, STM32L4X5_SOC)
> +
> +struct Stm32l4x5SocState {
> +    SysBusDevice parent_obj;
> +
> +    ARMv7MState armv7m;
> +
> +    MemoryRegion sram1;
> +    MemoryRegion sram2;
> +    MemoryRegion flash;
> +    MemoryRegion flash_alias;
> +
> +    Clock *sysclk;
> +    Clock *refclk;
> +};
> +
> +struct Stm32l4x5SocClass {
> +    SysBusDeviceClass parent_class;
> +
> +    size_t flash_size;
> +};
> +
> +#endif
> --
> 2.38.5
>
>


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

* Re: [PATCH qemu v3 2/2] hw/arm: Add minimal support for the B-L475E-IOT01A board
  2023-11-15  8:04 ` [PATCH qemu v3 2/2] hw/arm: Add minimal support for the B-L475E-IOT01A board ~inesvarhol
@ 2023-12-15  5:30   ` Alistair Francis
  0 siblings, 0 replies; 6+ messages in thread
From: Alistair Francis @ 2023-12-15  5:30 UTC (permalink / raw)
  To: ~inesvarhol
  Cc: qemu-devel, qemu-arm, alistair, philmd, peter.maydell,
	ines.varhol, arnaud.minier

On Fri, Dec 15, 2023 at 1:24 AM ~inesvarhol <inesvarhol@git.sr.ht> wrote:
>
> From: Inès Varhol <ines.varhol@telecom-paris.fr>
>
> This commit adds a new B-L475E-IOT01A board using the STM32L475VG SoC.
> The implementation is derived from the Netduino Plus 2 machine.
> There are no peripherals implemented yet, only memory regions.
>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
>
> Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
> Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>

Acked-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  MAINTAINERS                             |  7 +++
>  configs/devices/arm-softmmu/default.mak |  1 +
>  hw/arm/Kconfig                          |  6 +++
>  hw/arm/b-l475e-iot01a.c                 | 70 +++++++++++++++++++++++++
>  hw/arm/meson.build                      |  1 +
>  5 files changed, 85 insertions(+)
>  create mode 100644 hw/arm/b-l475e-iot01a.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index e5b28aee28..3f3831c92a 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1131,6 +1131,13 @@ S: Maintained
>  F: hw/arm/stm32l4x5_soc.c
>  F: include/hw/arm/stm32l4x5_soc.h
>
> +B-L475E-IOT01A IoT Node
> +M: Arnaud Minier <arnaud.minier@telecom-paris.fr>
> +M: Inès Varhol <ines.varhol@telecom-paris.fr>
> +L: qemu-arm@nongnu.org
> +S: Maintained
> +F: hw/arm/b-l475e-iot01a.c
> +
>  SmartFusion2
>  M: Subbaraya Sundeep <sundeep.lkml@gmail.com>
>  M: Peter Maydell <peter.maydell@linaro.org>
> diff --git a/configs/devices/arm-softmmu/default.mak b/configs/devices/arm-softmmu/default.mak
> index 980c48a7d9..023faa2f75 100644
> --- a/configs/devices/arm-softmmu/default.mak
> +++ b/configs/devices/arm-softmmu/default.mak
> @@ -19,6 +19,7 @@ CONFIG_ARM_VIRT=y
>  # CONFIG_NSERIES=n
>  # CONFIG_STELLARIS=n
>  # CONFIG_STM32VLDISCOVERY=n
> +# CONFIG_B_L475E_IOT01A=n
>  # CONFIG_REALVIEW=n
>  # CONFIG_VERSATILE=n
>  # CONFIG_VEXPRESS=n
> diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
> index d2b94d9a47..7520dc5cc0 100644
> --- a/hw/arm/Kconfig
> +++ b/hw/arm/Kconfig
> @@ -448,6 +448,12 @@ config STM32F405_SOC
>      select STM32F4XX_SYSCFG
>      select STM32F4XX_EXTI
>
> +config B_L475E_IOT01A
> +    bool
> +    default y
> +    depends on TCG && ARM
> +    select STM32L4X5_SOC
> +
>  config STM32L4X5_SOC
>      bool
>      select ARM_V7M
> diff --git a/hw/arm/b-l475e-iot01a.c b/hw/arm/b-l475e-iot01a.c
> new file mode 100644
> index 0000000000..c3790e3dc8
> --- /dev/null
> +++ b/hw/arm/b-l475e-iot01a.c
> @@ -0,0 +1,70 @@
> +/*
> + * B-L475E-IOT01A Discovery Kit machine
> + * (B-L475E-IOT01A IoT Node)
> + *
> + * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr>
> + * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr>
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + *
> + * This work is heavily inspired by the netduinoplus2 by Alistair Francis.
> + * Original code is licensed under the MIT License:
> + *
> + * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
> + */
> +
> +/*
> + * The reference used is the STMicroElectronics UM2153 User manual
> + * Discovery kit for IoT node, multi-channel communication with STM32L4.
> + * https://www.st.com/en/evaluation-tools/b-l475e-iot01a.html#documentation
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qapi/error.h"
> +#include "hw/boards.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/qdev-clock.h"
> +#include "qemu/error-report.h"
> +#include "hw/arm/stm32l4x5_soc.h"
> +#include "hw/arm/boot.h"
> +
> +/* Main SYSCLK frequency in Hz (80MHz) */
> +#define SYSCLK_FRQ 80000000ULL
> +
> +static void b_l475e_iot01a_init(MachineState *machine)
> +{
> +    const Stm32l4x5SocClass *sc;
> +    DeviceState *dev;
> +    Clock *sysclk;
> +
> +    /* This clock doesn't need migration because it is fixed-frequency */
> +    sysclk = clock_new(OBJECT(machine), "SYSCLK");
> +    clock_set_hz(sysclk, SYSCLK_FRQ);
> +
> +    dev = qdev_new(TYPE_STM32L4X5XG_SOC);
> +    sc = STM32L4X5_SOC_GET_CLASS(dev);
> +    qdev_connect_clock_in(dev, "sysclk", sysclk);
> +    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
> +
> +    armv7m_load_kernel(ARM_CPU(first_cpu),
> +                       machine->kernel_filename,
> +                       0, sc->flash_size);
> +}
> +
> +static void b_l475e_iot01a_machine_init(MachineClass *mc)
> +{
> +    static const char *machine_valid_cpu_types[] = {
> +        ARM_CPU_TYPE_NAME("cortex-m4"),
> +        NULL};
> +    mc->desc = "B-L475E-IOT01A Discovery Kit (Cortex-M4)";
> +    mc->init = b_l475e_iot01a_init;
> +    mc->valid_cpu_types = machine_valid_cpu_types;
> +
> +    /* SRAM pre-allocated as part of the SoC instantiation */
> +    mc->default_ram_size = 0;
> +}
> +
> +DEFINE_MACHINE("b-l475e-iot01a", b_l475e_iot01a_machine_init)
> diff --git a/hw/arm/meson.build b/hw/arm/meson.build
> index 9766da10c4..bb92b27db3 100644
> --- a/hw/arm/meson.build
> +++ b/hw/arm/meson.build
> @@ -42,6 +42,7 @@ arm_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2836.c', 'raspi.c'))
>  arm_ss.add(when: 'CONFIG_STM32F100_SOC', if_true: files('stm32f100_soc.c'))
>  arm_ss.add(when: 'CONFIG_STM32F205_SOC', if_true: files('stm32f205_soc.c'))
>  arm_ss.add(when: 'CONFIG_STM32F405_SOC', if_true: files('stm32f405_soc.c'))
> +arm_ss.add(when: 'CONFIG_B_L475E_IOT01A', if_true: files('b-l475e-iot01a.c'))
>  arm_ss.add(when: 'CONFIG_STM32L4X5_SOC', if_true: files('stm32l4x5_soc.c'))
>  arm_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp.c', 'xlnx-zcu102.c'))
>  arm_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal.c', 'xlnx-versal-virt.c'))
> --
> 2.38.5
>


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

* Re: [PATCH qemu v3 0/2] Add minimal support for the B-L475E-IOT01A board
  2023-12-14 15:23 [PATCH qemu v3 0/2] Add minimal support for the B-L475E-IOT01A board ~inesvarhol
  2023-11-15  7:59 ` [PATCH qemu v3 1/2] hw/arm: Add minimal support for the STM32L4x5 SoC ~inesvarhol
  2023-11-15  8:04 ` [PATCH qemu v3 2/2] hw/arm: Add minimal support for the B-L475E-IOT01A board ~inesvarhol
@ 2023-12-18 14:53 ` Peter Maydell
  2 siblings, 0 replies; 6+ messages in thread
From: Peter Maydell @ 2023-12-18 14:53 UTC (permalink / raw)
  To: ~inesvarhol
  Cc: qemu-devel, qemu-arm, alistair, philmd, ines.varhol,
	arnaud.minier

On Thu, 14 Dec 2023 at 15:23, ~inesvarhol <inesvarhol@git.sr.ht> wrote:
>
> This patch adds a new STM32L4x5 SoC, it is necessary to add support for
> the B-L475E-IOT01A board.
> The implementation is derived from the STM32F405 SoC and NetduinoPlus2
> board.
> The implementation contains no peripherals, only memory regions are
> implemented.
>
> Sorry about the inconsistency in licenses in v2, I changed them.
> Should I clarify anything further? Thank you.
>
> Changes from v1 to v3:
> Changing the MIT license to GPL.
>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
> Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
>
> Inès Varhol (2):
>   hw/arm: Add minimal support for the STM32L4x5 SoC
>   hw/arm: Add minimal support for the B-L475E-IOT01A board
>
>  MAINTAINERS                             |  15 ++
>  configs/devices/arm-softmmu/default.mak |   1 +
>  hw/arm/Kconfig                          |  11 +
>  hw/arm/b-l475e-iot01a.c                 |  70 +++++++
>  hw/arm/meson.build                      |   2 +
>  hw/arm/stm32l4x5_soc.c                  | 268 ++++++++++++++++++++++++
>  include/hw/arm/stm32l4x5_soc.h          |  59 ++++++

Can we have some documentation for the new board model, please?
That should be a new file under docs/system/arm/, that you
then list in docs/system/target-arm.rst (note the comment there
about what order the ToC should be in). The docs don't have to
be super comprehensive, but should at least:
 * describe what the board is
 * briefly list the supported devices
 * list any missing features or other limitations
 * describe any machine-specific options (you don't have any yet)
 * if there is an easy open source guest that will run on the board,
   some instructions for how to do that (this part isn't mandatory)

docs/system/arm/orangepi.rst is a good example of the format/structure.

(If you pass configure '--enable-docs' that will ensure that it
builds documentation and doesn't skip it because you're missing
a dependency.)

Then subsequent followon patchsets that update the model to
add new devices etc will likely also patch the docs to add
items to the "supported" list.

thanks
-- PMM


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

end of thread, other threads:[~2023-12-18 14:54 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-12-14 15:23 [PATCH qemu v3 0/2] Add minimal support for the B-L475E-IOT01A board ~inesvarhol
2023-11-15  7:59 ` [PATCH qemu v3 1/2] hw/arm: Add minimal support for the STM32L4x5 SoC ~inesvarhol
2023-12-15  5:29   ` Alistair Francis
2023-11-15  8:04 ` [PATCH qemu v3 2/2] hw/arm: Add minimal support for the B-L475E-IOT01A board ~inesvarhol
2023-12-15  5:30   ` Alistair Francis
2023-12-18 14:53 ` [PATCH qemu v3 0/2] " Peter Maydell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).