From nobody Sat Nov 15 09:31:56 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=rt-thread.org ARC-Seal: i=1; a=rsa-sha256; t=1753129323; cv=none; d=zohomail.com; s=zohoarc; b=R861aqc3aEGwdIxL+PzuUpX5R76wF8sU++GF2R/r9uzHrHKyN8TzLo4p6xddROCW7DEQJRZqtZjFxa0WZsaJIDGIrL2RB0Z83h7FYy4XO9y/MzeU5bPY0NKdCiZ9ZMvl0ObJujRtXLuMDPrebfd7E1u9rjZfjPoEGZBq1LcfueI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1753129323; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=mmOs2IbJ1iobGCcYuwGC/cVhsR6OQTKNHle8PCJkcX4=; b=b5kRxs5BufOJA+bG8O/r8DEsDM26bk6/NUPfBtsiKc3k5URysWGvBVc4LyA8VpV8TrgqVWylo21WgNzHwxC/FpdQUh0YgbNcFY6wlom70d6Rb5TVzV6tLGt4a2H1X/YW8ttxh5tmPxiH9iag7BziQRDM+cinocHvvuUlvj/HEmo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1753129323931497.12548378755946; Mon, 21 Jul 2025 13:22:03 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1udx1G-0006HI-C0; Mon, 21 Jul 2025 16:21:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1udwyO-00038U-AM for qemu-devel@nongnu.org; Mon, 21 Jul 2025 16:19:02 -0400 Received: from mail-m8288.xmail.ntesmail.com ([156.224.82.88]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1udwyK-0000Xw-Pm for qemu-devel@nongnu.org; Mon, 21 Jul 2025 16:18:56 -0400 Received: from DESKTOP-FHFCVTH.localdomain (unknown [IPV6:240e:360:9379:c800:30:bacc:21c0:5559]) by smtp.qiye.163.com (Hmail) with ESMTP id 1cc453b66; Tue, 22 Jul 2025 04:11:37 +0800 (GMT+08:00) From: fanyihao@rt-thread.org To: qemu-devel@nongnu.org Cc: Peter Maydell , Yihao Fan Subject: [PATCH v2 1/3] Add-the-stm32f407-SoC Date: Tue, 22 Jul 2025 04:11:32 +0800 Message-ID: <20250721201134.13270-2-fanyihao@rt-thread.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250721201134.13270-1-fanyihao@rt-thread.org> References: <20250721201134.13270-1-fanyihao@rt-thread.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-HM-Spam-Status: e1kfGhgUHx5ZQUpXWQgPGg8OCBgUHx5ZQUlOS1dZFg8aDwILHllBWSg2Ly tZV1koWUFITzdXWS1ZQUlXWQ8JGhUIEh9ZQVkZSUlDVk9IQ0gaTx8ZTh9CTlYVFAkWGhdVEwETFh oSFyQUDg9ZV1kYEgtZQVlJT0seQUhNS0FCSExCQRhDS0tBSEtBGRoYGEFJShhLQU5OTkJZV1kWGg 8SFR0UWUFZT0tIVUpLSUJDQ0lVSktLVUtZBg++ X-HM-Tid: 0a982e9cfe6703a4kunm518c726929260c6 X-HM-MType: 1 X-HM-Sender-Digest: e1kMHhlZQR0aFwgeV1kSHx4VD1lBWUc6PjI6Axw4GDEiCDo3Nw8CFTZK DjJPCQxVSlVKTE5ISklDTUJDSUpCVTMWGhIXVR0aFQISExoUOwkPVg8TCR4aH1UUCRxFWVdZEgtZ QVlJT0seQUhNS0FCSExCQRhDS0tBSEtBGRoYGEFJShhLQU5OTkJZV1kIAVlBQ09CQzcG DKIM-Signature: a=rsa-sha256; b=KzyHIYTB+QDCc9sYUliuyDOnkwAFpQNah8T4hEWDSBFnc+rGi6O1osxYR4dJQQ30QxMvzVpa2vaYvB37lzV/hePxP/mFjRrUpUihFhb9jZ4BpY41XeXB59iTQH868p5zdLeZGtIv6T1V3OQXkmzgPKa3XFHW+VXxvRgy3zy7uAIuthB6bsju494kJuivO00DZGE/WsR4paMFBdy55VhRlrHJq61Oa1UI9Ym8fxbN7AWKMiS30IHod3L/znD2IVYbHEgKpDKsFhJO9sGFom4RmCHWy9M4riJMDoqNXr5zCCfMfetuCyGR17Ws1QM+XvT1M02XJ03oV8i0ZmZSajI4Zg==; c=relaxed/relaxed; s=default; d=rt-thread.org; v=1; bh=mmOs2IbJ1iobGCcYuwGC/cVhsR6OQTKNHle8PCJkcX4=; h=date:mime-version:subject:message-id:from; Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=156.224.82.88; envelope-from=fanyihao@rt-thread.org; helo=mail-m8288.xmail.ntesmail.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @rt-thread.org) X-ZM-MESSAGEID: 1753129325821116600 Content-Type: text/plain; charset="utf-8" From: Yihao Fan This patch introduces a new QEMU machine type for the STM32F407 SoC featuri= ng a Cortex-M4 core. This will be used by the RT-Spark to create a machine. Signed-off-by: Yihao Fan --- MAINTAINERS | 7 ++ hw/arm/Kconfig | 6 ++ hw/arm/meson.build | 1 + hw/arm/stm32f407_soc.c | 130 +++++++++++++++++++++++++++++++++ include/hw/arm/stm32f407_soc.h | 39 ++++++++++ 5 files changed, 183 insertions(+) create mode 100644 hw/arm/stm32f407_soc.c create mode 100644 include/hw/arm/stm32f407_soc.h diff --git a/MAINTAINERS b/MAINTAINERS index d1672fda8d..2744639a8b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1137,6 +1137,13 @@ F: hw/misc/stm32f4xx_exti.c F: hw/misc/stm32_rcc.c F: include/hw/misc/stm32_rcc.h =20 +STM32F407 +M: yanl1229 +M: Yihao Fan +L: qemu-arm@nongnu.org +S: Maintained +F: hw/arm/stm32f407_soc.c + Netduino 2 M: Alistair Francis M: Peter Maydell diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index f543d944c3..4b2f71e6e1 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -392,6 +392,12 @@ config STM32F405_SOC select STM32F4XX_SYSCFG select STM32F4XX_EXTI =20 +config STM32F407_SOC + bool + select ARM_V7M + select STM32F4XX_SYSCFG + select STM32F4XX_EXTI + config B_L475E_IOT01A bool default y diff --git a/hw/arm/meson.build b/hw/arm/meson.build index d90be8f4c9..31621060ba 100644 --- a/hw/arm/meson.build +++ b/hw/arm/meson.build @@ -32,6 +32,7 @@ arm_common_ss.add(when: ['CONFIG_RASPI', 'TARGET_AARCH64'= ], if_true: files('bcm2 arm_common_ss.add(when: 'CONFIG_STM32F100_SOC', if_true: files('stm32f100_= soc.c')) arm_common_ss.add(when: 'CONFIG_STM32F205_SOC', if_true: files('stm32f205_= soc.c')) arm_common_ss.add(when: 'CONFIG_STM32F405_SOC', if_true: files('stm32f405_= soc.c')) +arm_common_ss.add(when: 'CONFIG_STM32F407_SOC', if_true: files('stm32f407_= soc.c')) arm_common_ss.add(when: 'CONFIG_B_L475E_IOT01A', if_true: files('b-l475e-i= ot01a.c')) arm_common_ss.add(when: 'CONFIG_STM32L4X5_SOC', if_true: files('stm32l4x5_= soc.c')) arm_common_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zyn= qmp.c', 'xlnx-zcu102.c')) diff --git a/hw/arm/stm32f407_soc.c b/hw/arm/stm32f407_soc.c new file mode 100644 index 0000000000..0a91d4bb10 --- /dev/null +++ b/hw/arm/stm32f407_soc.c @@ -0,0 +1,130 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "system/address-spaces.h" +#include "system/system.h" +#include "hw/arm/stm32f407_soc.h" +#include "hw/qdev-clock.h" +#include "hw/sd/sd.h" +#include "hw/boards.h" +#include "qom/object.h" +#include "hw/block/flash.h" +#include "hw/misc/unimp.h" + + +static const uint32_t syscfg_addr =3D 0x40013800; +static const uint32_t exti_addr =3D 0x40013C00; +static const int syscfg_irq =3D 71; +static const int exti_irq[] =3D { + 6, 7, 8, 9, 10, 23, 23, 23, 23, 23, 40, + 40, 40, 40, 40, 40 +}; + + +static void stm32f407_soc_initfn(Object *obj) +{ + int i; + + STM32F407State *s =3D STM32F407_SOC(obj); + + object_initialize_child(obj, "armv7m", &s->armv7m, TYPE_ARMV7M); + + object_initialize_child(obj, "syscfg", &s->syscfg, TYPE_STM32F4XX_SYSC= FG); + object_initialize_child(obj, "exti", &s->exti, TYPE_STM32F4XX_EXTI); + + s->sysclk =3D qdev_init_clock_in(DEVICE(s), "sysclk", NULL, NULL, 0); + s->refclk =3D qdev_init_clock_in(DEVICE(s), "refclk", NULL, NULL, 0); +} + +static void stm32f407_soc_realize(DeviceState *dev_soc, Error **errp) +{ + STM32F407State *s =3D STM32F407_SOC(dev_soc); + DeviceState *dev, *armv7m; + SysBusDevice *busdev; + DriveInfo *dinfo; + int i, j; + + MemoryRegion *system_memory =3D get_system_memory(); + + /* + * 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 c= ode"); + 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); + + + armv7m =3D DEVICE(&s->armv7m); + qdev_prop_set_uint32(armv7m, "num-irq", 98); + 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; + } + /* System configuration controller */ + dev =3D DEVICE(&s->syscfg); + if (!sysbus_realize(SYS_BUS_DEVICE(&s->syscfg), errp)) { + return; + } + busdev =3D SYS_BUS_DEVICE(dev); + sysbus_mmio_map(busdev, 0, syscfg_addr); + sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(armv7m, syscfg_irq)); + + /* EXTI device */ + dev =3D DEVICE(&s->exti); + if (!sysbus_realize(SYS_BUS_DEVICE(&s->exti), errp)) { + return; + } + busdev =3D SYS_BUS_DEVICE(dev); + sysbus_mmio_map(busdev, 0, exti_addr); + for (i =3D 0; i < 16; i) { + sysbus_connect_irq(busdev, i, qdev_get_gpio_in(armv7m, exti_irq[i]= )); + } + for (i =3D 0; i < 16; i) { + qdev_connect_gpio_out(DEVICE(&s->syscfg), i, qdev_get_gpio_in(dev,= i)); + } + +} + +static void stm32f407_soc_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + + dc->realize =3D stm32f407_soc_realize; +} + +static const TypeInfo stm32f407_soc_info =3D { + .name =3D TYPE_STM32F407_SOC, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(STM32F407State), + .instance_init =3D stm32f407_soc_initfn, + .class_init =3D stm32f407_soc_class_init, +}; + +static void stm32f407_soc_types(void) +{ + type_register_static(&stm32f407_soc_info); +} + +type_init(stm32f407_soc_types) diff --git a/include/hw/arm/stm32f407_soc.h b/include/hw/arm/stm32f407_soc.h new file mode 100644 index 0000000000..19191dc44e --- /dev/null +++ b/include/hw/arm/stm32f407_soc.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef STM32F407_SOC_H +#define STM32F407_SOC_H + +#include "hw/or-irq.h" +#include "hw/arm/armv7m.h" +#include "hw/misc/stm32f4xx_syscfg.h" +#include "hw/misc/stm32f4xx_exti.h" + +#include "qom/object.h" + +#define TYPE_STM32F407_SOC "stm32f407-soc" +OBJECT_DECLARE_SIMPLE_TYPE(STM32F407State, STM32F407_SOC) + +#define SYSCFG_BASE_ADDRESS 0x40013800 +#define SYSCFG_IRQ 71 +#define EXIT_BASE_ADDRESS 0x40013C00 +#define FLASH_BASE_ADDRESS 0x8000000 +#define FLASH_SIZE 0x100000 +#define SRAM_BASE_ADDRESS 0x20000000 +#define SRAM_SIZE (192 * 1024) + + +struct STM32F407State { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + char *kernel_filename; + ARMv7MState armv7m; + + STM32F4xxSyscfgState syscfg; + STM32F4xxExtiState exti; + + Clock *sysclk; + Clock *refclk; +}; + +#endif --=20 2.43.0 From nobody Sat Nov 15 09:31:56 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=rt-thread.org ARC-Seal: i=1; a=rsa-sha256; t=1753129323; cv=none; d=zohomail.com; s=zohoarc; b=XSV5GoQqQLwsyKjklDJblIzeokeNOMcHCAR9HK+bhUXuovL5C3HMLVkb/Ih85ElRnSZhPo4ner+frZloaGXS5U7MOGldNDnxshSoRaTgnpUhYoL6TiW901PUGT8gSwNSPXkRgc9mN9XdbHP1j1KJ9BKNAv/VCdy+BmEYEFAXxhA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1753129323; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=DhtHw8BoO83emuq5svR1hPIfwohhpo4OSgYOi+4ii5Y=; b=GwK4YLsEIdvq03JIO2iLHlq/u+u2EJ6lhJJ+O2n1rF52Pbq1+BUyvKyjzJemIZgVIW9LYJQ5Q4zpcw/iS/eJC1o++vq3285o8xXR1OLvvNhKb2j/Bs/suzn+ehMBpngasMNMkHO+a0vqjrIv35aEegBgA3rUUx0AZwi4BrvcMak= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1753129323624446.60836369436663; Mon, 21 Jul 2025 13:22:03 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1udx0x-0005gl-1V; Mon, 21 Jul 2025 16:21:40 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1udwyQ-0003AF-Jz for qemu-devel@nongnu.org; Mon, 21 Jul 2025 16:19:02 -0400 Received: from mail-m93118.xmail.ntesmail.com ([103.126.93.118]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1udwyM-0000YU-7Y for qemu-devel@nongnu.org; Mon, 21 Jul 2025 16:18:58 -0400 Received: from DESKTOP-FHFCVTH.localdomain (unknown [IPV6:240e:360:9379:c800:30:bacc:21c0:5559]) by smtp.qiye.163.com (Hmail) with ESMTP id 1cc453b67; Tue, 22 Jul 2025 04:11:38 +0800 (GMT+08:00) From: fanyihao@rt-thread.org To: qemu-devel@nongnu.org Cc: Peter Maydell , Yihao Fan Subject: [PATCH v2 2/3] Add the STM32F4spark Machine Date: Tue, 22 Jul 2025 04:11:33 +0800 Message-ID: <20250721201134.13270-3-fanyihao@rt-thread.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250721201134.13270-1-fanyihao@rt-thread.org> References: <20250721201134.13270-1-fanyihao@rt-thread.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-HM-Spam-Status: e1kfGhgUHx5ZQUpXWQgPGg8OCBgUHx5ZQUlOS1dZFg8aDwILHllBWSg2Ly tZV1koWUFITzdXWS1ZQUlXWQ8JGhUIEh9ZQVkZH0oYVk5JTRofQx0ZTElCHlYVFAkWGhdVEwETFh oSFyQUDg9ZV1kYEgtZQVlJT0seQUhNS0FCSExCQRhDS0tBSEtBGRoYGEFJShhLQU5OTkJZV1kWGg 8SFR0UWUFZT0tIVUpLSUJDQ0lVSktLVUtZBg++ X-HM-Tid: 0a982e9d038203a4kunm518c726929260df X-HM-MType: 1 X-HM-Sender-Digest: e1kMHhlZQR0aFwgeV1kSHx4VD1lBWUc6NC46Gjo5CjEiTToWCQhOFTcj DAkwCjpVSlVKTE5ISklDTUJCT09MVTMWGhIXVR0aFQISExoUOwkPVg8TCR4aH1UUCRxFWVdZEgtZ QVlJT0seQUhNS0FCSExCQRhDS0tBSEtBGRoYGEFJShhLQU5OTkJZV1kIAVlBT0lJSjcG DKIM-Signature: a=rsa-sha256; b=LLxpfIlqLaNCMMadtDCbA4wUfR06QfnmLAhD6nrPxvu+24Qt4uZk4RmlC1PK/NeSjhKqjbv5CU9jDsqCYnGhrhUU+x+U5B9f6Die3YcD2LLuGwd+XYrm1x00zs8wWxhfk/IWjU1HidieekfmU0LH5btgI9a2lxlXB5VdvHnWOOhBlsUhRerfYBDwGWpWHbxjwQ+2vicutCHiXY3dcDPTQmv5F7leVrgq+afXi0JnmrpA8FejsOo+hDHEku5AGdsO1ya8UCMR6Y1ckdyZQ0SrLzQpoL3c7fbr/8BcXjMx/yJ3FYw9IXnBvXrvmx11mvDT0x681EsNB/j66/S/k2SCuw==; c=relaxed/relaxed; s=default; d=rt-thread.org; v=1; bh=DhtHw8BoO83emuq5svR1hPIfwohhpo4OSgYOi+4ii5Y=; h=date:mime-version:subject:message-id:from; Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=103.126.93.118; envelope-from=fanyihao@rt-thread.org; helo=mail-m93118.xmail.ntesmail.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @rt-thread.org) X-ZM-MESSAGEID: 1753129325723116600 Content-Type: text/plain; charset="utf-8" From: Yihao Fan Add the STM32F4spark machine model using the STM32F407 SoC. Signed-off-by: Yihao Fan --- MAINTAINERS | 7 +++++++ hw/arm/Kconfig | 6 ++++++ hw/arm/meson.build | 1 + hw/arm/stm32f4spark.c | 48 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 62 insertions(+) create mode 100644 hw/arm/stm32f4spark.c diff --git a/MAINTAINERS b/MAINTAINERS index 2744639a8b..0dc7c7bf60 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1030,6 +1030,13 @@ S: Maintained F: hw/arm/stm32vldiscovery.c F: docs/system/arm/stm32.rst =20 +STM32F4SPARK +M: yanl1229 +M: Yihao Fan +L: qemu-arm@nongnu.org +S: Maintained +F: hw/arm/stm32f4spark.c + Versatile Express M: Peter Maydell L: qemu-arm@nongnu.org diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index 4b2f71e6e1..3706a65286 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -234,6 +234,12 @@ config STM32VLDISCOVERY depends on TCG && ARM select STM32F100_SOC =20 +config STM32F4SPARK + bool + default y + depends on TCG && ARM + select STM32F407_SOC + config STRONGARM bool select PXA2XX_TIMER diff --git a/hw/arm/meson.build b/hw/arm/meson.build index 31621060ba..ec63ed7373 100644 --- a/hw/arm/meson.build +++ b/hw/arm/meson.build @@ -17,6 +17,7 @@ arm_common_ss.add(when: 'CONFIG_REALVIEW', if_true: files= ('realview.c')) arm_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('sbsa-ref.c')) arm_common_ss.add(when: 'CONFIG_STELLARIS', if_true: files('stellaris.c')) arm_common_ss.add(when: 'CONFIG_STM32VLDISCOVERY', if_true: files('stm32vl= discovery.c')) +arm_common_ss.add(when: 'CONFIG_STM32F4SPARK', if_true: files('stm32f4spar= k.c')) arm_common_ss.add(when: 'CONFIG_ZYNQ', if_true: files('xilinx_zynq.c')) arm_common_ss.add(when: 'CONFIG_SABRELITE', if_true: files('sabrelite.c')) =20 diff --git a/hw/arm/stm32f4spark.c b/hw/arm/stm32f4spark.c new file mode 100644 index 0000000000..e1d656a3f9 --- /dev/null +++ b/hw/arm/stm32f4spark.c @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#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/stm32f407_soc.h" +#include "hw/arm/boot.h" + +/* stm32f4spark implementation is derived from netduinoplus2 */ + +/* Main SYSCLK frequency in Hz (72MHz) */ +#define SYSCLK_FRQ 72000000ULL + + +static void stm32f4spark_init(MachineState *machine) +{ + DeviceState *dev; + Clock *sysclk; + + /* This clock doesn't need migration because it is fixed-frequency */ + sysclk =3D clock_new(OBJECT(machine), "SYSCLK"); + clock_set_hz(sysclk, SYSCLK_FRQ); + + dev =3D qdev_new(TYPE_STM32F407_SOC); + object_property_add_child(OBJECT(machine), "soc", OBJECT(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, FLASH_SIZE); +} + +static void stm32f4spark_machine_init(MachineClass *mc) +{ + static const char * const valid_cpu_types[] =3D { + ARM_CPU_TYPE_NAME("cortex-m4"), + NULL + }; + + mc->desc =3D "ST RT-spark (Cortex-M4)"; + mc->init =3D stm32f4spark_init; + mc->valid_cpu_types =3D valid_cpu_types; +} + +DEFINE_MACHINE("rt-spark", stm32f4spark_machine_init) --=20 2.43.0 From nobody Sat Nov 15 09:31:56 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=rt-thread.org ARC-Seal: i=1; a=rsa-sha256; t=1753129248; cv=none; d=zohomail.com; s=zohoarc; b=Dt8nhxyl4k/TC6DLIrsBc4ibHUFzYpQaaBJrGvEhhYGPlQcC7gcgnKRmKGckOhby3uImryyYIZG9//lapfKwzJ/36nzIqegNGKCEGGMjO//6/AzQi53Ejd9IBkTyNFHjNm9Gzw79/kXCJ9BdKq1VO4aXfPIXFbFvuuuCdano9kM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1753129248; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=TYZjORxpLCC8uEWGuup+3RHrlZ5+JlH9+aCu7j/4njA=; b=CLtzIYXME+M65db1HvVC9XWIL0bV3VuOnP9G1cFCjbM5hV3PhIp6y77AHVGsn/wzdpwvqMJaV6rQcOHwR10jDjPS3sunBGgvdACZCOeVz+gFo85A7L1rdITKinSmd908afleJCcSsP8Yxx49IyZWBwyAcgVJ0IYO7cAxink+CNo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1753129247350340.3441207395663; Mon, 21 Jul 2025 13:20:47 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1udwzy-0004sk-5g; Mon, 21 Jul 2025 16:20:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1udwyQ-0003AE-JZ for qemu-devel@nongnu.org; Mon, 21 Jul 2025 16:19:02 -0400 Received: from mail-m81138.xmail.ntesmail.com ([156.224.81.138]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1udwyL-0000YP-Rv for qemu-devel@nongnu.org; Mon, 21 Jul 2025 16:18:56 -0400 Received: from DESKTOP-FHFCVTH.localdomain (unknown [IPV6:240e:360:9379:c800:30:bacc:21c0:5559]) by smtp.qiye.163.com (Hmail) with ESMTP id 1cc453b69; Tue, 22 Jul 2025 04:11:39 +0800 (GMT+08:00) From: fanyihao@rt-thread.org To: qemu-devel@nongnu.org Cc: Peter Maydell , Yihao Fan Subject: [PATCH v2 3/3] Add STM32F4xx USART device model Date: Tue, 22 Jul 2025 04:11:34 +0800 Message-ID: <20250721201134.13270-4-fanyihao@rt-thread.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250721201134.13270-1-fanyihao@rt-thread.org> References: <20250721201134.13270-1-fanyihao@rt-thread.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-HM-Spam-Status: e1kfGhgUHx5ZQUpXWQgPGg8OCBgUHx5ZQUlOS1dZFg8aDwILHllBWSg2Ly tZV1koWUFITzdXWS1ZQUlXWQ8JGhUIEh9ZQVkaTk0eVkJDQx5IQkIeSR9MSVYVFAkWGhdVEwETFh oSFyQUDg9ZV1kYEgtZQVlJT0seQUhNS0FCSExCQRhDS0tBSEtBGRoYGEFJShhLQU5OTkJZV1kWGg 8SFR0UWUFZT0tIVUpLSUJDQ0lVSktLVUtZBg++ X-HM-Tid: 0a982e9d085b03a4kunm518c726929260ee X-HM-MType: 1 X-HM-Sender-Digest: e1kMHhlZQR0aFwgeV1kSHx4VD1lBWUc6Pgg6LTo*KjEaSTo9GQgPFTIR UTMKClZVSlVKTE5ISklDTEtLTENKVTMWGhIXVR0aFQISExoUOwkPVg8TCR4aH1UUCRxFWVdZEgtZ QVlJT0seQUhNS0FCSExCQRhDS0tBSEtBGRoYGEFJShhLQU5OTkJZV1kIAVlBSk9NSkg3Bg++ DKIM-Signature: a=rsa-sha256; b=Sn98J4Huq/s8rG4aCtWUMLDwrp8LwyHWkvsJc3LHme0dkRAt7/Da2GN1wvK2yZBZ9X3uRbtQvUQCbqHIzGxR3A+90VXZgvCCu/WhAku86LSTS8jm4kbDC37bvU61D0tF8Ao5Rv7M+g8GWg36SHMseG37jJOX3BfC4eMoYIetem4ULAibKSZPP90SEqXJisZpKVIa82JYFyNGip9+nl7X3UMSmdFyIHbBLQDkhjBMZg1lhLzPvHh7EK34TRpVNhMf5dEIDUEfwUAZUXVWgcsecWje9/P0vHUB9rECTUoi8ns/X8x+9ByNSIDRKuQIb+3oZaWucRShc5kKo1DBhh+/Sw==; c=relaxed/relaxed; s=default; d=rt-thread.org; v=1; bh=TYZjORxpLCC8uEWGuup+3RHrlZ5+JlH9+aCu7j/4njA=; h=date:mime-version:subject:message-id:from; Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=156.224.81.138; envelope-from=fanyihao@rt-thread.org; helo=mail-m81138.xmail.ntesmail.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @rt-thread.org) X-ZM-MESSAGEID: 1753129251244116600 Content-Type: text/plain; charset="utf-8" From: Yihao Fan This patch adds support for the STM32F407 USART controllers device model. Signed-off-by: Yihao Fan --- MAINTAINERS | 2 + hw/arm/Kconfig | 1 + hw/arm/stm32f407_soc.c | 25 +++ hw/char/Kconfig | 3 + hw/char/meson.build | 1 + hw/char/stm32f4xx_usart.c | 236 ++++++++++++++++++++++++++++++ include/hw/arm/stm32f407_soc.h | 8 + include/hw/char/stm32f4xx_usart.h | 60 ++++++++ 8 files changed, 335 insertions(+) create mode 100644 hw/char/stm32f4xx_usart.c create mode 100644 include/hw/char/stm32f4xx_usart.h diff --git a/MAINTAINERS b/MAINTAINERS index 0dc7c7bf60..2054aba27e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1150,6 +1150,8 @@ M: Yihao Fan L: qemu-arm@nongnu.org S: Maintained F: hw/arm/stm32f407_soc.c +F: hw/char/stm32f4xx_usart.c +F: include/hw/char/stm32f4xx_usart.h =20 Netduino 2 M: Alistair Francis diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index 3706a65286..c6a4919266 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -403,6 +403,7 @@ config STM32F407_SOC select ARM_V7M select STM32F4XX_SYSCFG select STM32F4XX_EXTI + select STM32F4XX_USART =20 config B_L475E_IOT01A bool diff --git a/hw/arm/stm32f407_soc.c b/hw/arm/stm32f407_soc.c index 0a91d4bb10..8a929674af 100644 --- a/hw/arm/stm32f407_soc.c +++ b/hw/arm/stm32f407_soc.c @@ -20,6 +20,13 @@ static const int exti_irq[] =3D { 40, 40, 40, 40, 40 }; =20 +static const uint32_t usart_addr[STM_NUM_USARTS] =3D { + STM32F407_USART1, STM32F407_USART2, STM32F407_USART3, + STM32F407_USART6 +}; +static const int usart_irq[STM_NUM_USARTS] =3D { + 37, 38, 39, 71 +}; =20 static void stm32f407_soc_initfn(Object *obj) { @@ -32,6 +40,12 @@ static void stm32f407_soc_initfn(Object *obj) object_initialize_child(obj, "syscfg", &s->syscfg, TYPE_STM32F4XX_SYSC= FG); object_initialize_child(obj, "exti", &s->exti, TYPE_STM32F4XX_EXTI); =20 + for (i =3D 0; i < STM_NUM_USARTS; i++) { + object_initialize_child(obj, "usart[*]", &s->usart[i], + TYPE_STM32F4XX_USART); + } + + s->sysclk =3D qdev_init_clock_in(DEVICE(s), "sysclk", NULL, NULL, 0); s->refclk =3D qdev_init_clock_in(DEVICE(s), "refclk", NULL, NULL, 0); } @@ -105,6 +117,18 @@ static void stm32f407_soc_realize(DeviceState *dev_soc= , Error **errp) qdev_connect_gpio_out(DEVICE(&s->syscfg), i, qdev_get_gpio_in(dev,= i)); } =20 + /* USART controllers */ + for (i =3D 0; i < STM_NUM_USARTS; i) { + dev =3D DEVICE(&(s->usart[i])); + qdev_prop_set_chr(dev, "chardev", serial_hd(i)); + if (!sysbus_realize(SYS_BUS_DEVICE(&s->usart[i]), errp)) { + return; + } + busdev =3D SYS_BUS_DEVICE(dev); + sysbus_mmio_map(busdev, 0, usart_addr[i]); + sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(armv7m, usart_irq[i= ])); + } + } =20 static void stm32f407_soc_class_init(ObjectClass *klass, void *data) diff --git a/hw/char/Kconfig b/hw/char/Kconfig index 9d517f3e28..25a0483fb3 100644 --- a/hw/char/Kconfig +++ b/hw/char/Kconfig @@ -51,6 +51,9 @@ config VIRTIO_SERIAL config STM32F2XX_USART bool =20 +config STM32F4XX_USART + bool + config STM32L4X5_USART bool =20 diff --git a/hw/char/meson.build b/hw/char/meson.build index 4e439da8b9..3372e77bbc 100644 --- a/hw/char/meson.build +++ b/hw/char/meson.build @@ -32,6 +32,7 @@ system_ss.add(when: 'CONFIG_RENESAS_SCI', if_true: files(= 'renesas_sci.c')) system_ss.add(when: 'CONFIG_SIFIVE_UART', if_true: files('sifive_uart.c')) system_ss.add(when: 'CONFIG_SH_SCI', if_true: files('sh_serial.c')) system_ss.add(when: 'CONFIG_STM32F2XX_USART', if_true: files('stm32f2xx_us= art.c')) +system_ss.add(when: 'CONFIG_STM32F4XX_USART', if_true: files('stm32f4xx_us= art.c')) system_ss.add(when: 'CONFIG_STM32L4X5_USART', if_true: files('stm32l4x5_us= art.c')) system_ss.add(when: 'CONFIG_MCHP_PFSOC_MMUART', if_true: files('mchp_pfsoc= _mmuart.c')) system_ss.add(when: 'CONFIG_HTIF', if_true: files('riscv_htif.c')) diff --git a/hw/char/stm32f4xx_usart.c b/hw/char/stm32f4xx_usart.c new file mode 100644 index 0000000000..c3d2690275 --- /dev/null +++ b/hw/char/stm32f4xx_usart.c @@ -0,0 +1,236 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#include "qemu/osdep.h" +#include "hw/char/stm32f4xx_usart.h" +#include "qemu/log.h" +#include "hw/irq.h" +#include "hw/qdev-properties.h" +#include "hw/qdev-properties-system.h" +#include "qemu/module.h" + +#ifndef STM_USART_ERR_DEBUG +#define STM_USART_ERR_DEBUG 0 +#endif + +#define DB_PRINT_L(lvl, fmt, args...) do { \ + if (STM_USART_ERR_DEBUG >=3D lvl) { \ + qemu_log("%s: " fmt, __func__, ## args); \ + } \ +} while (0) + +#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args) + +static int stm32f4xx_usart_can_receive(void *opaque) +{ + STM32F4XXUsartState *s =3D opaque; + + if (!(s->usart_sr & USART_SR_RXNE)) { + return 1; + } + + return 0; +} + +static void stm32f4xx_usart_receive(void *opaque, const uint8_t *buf, int = size) +{ + STM32F4XXUsartState *s =3D opaque; + + s->usart_dr =3D *buf; + + if (!(s->usart_cr1 & USART_CR1_UE && s->usart_cr1 & USART_CR1_RE)) { + /* USART not enabled - drop the chars */ + DB_PRINT("Dropping the chars\n"); + return; + } + + s->usart_sr |=3D USART_SR_RXNE; + + if (s->usart_cr1 & USART_CR1_RXNEIE) { + qemu_set_irq(s->irq, 1); + } + + DB_PRINT("Receiving: %c\n", s->usart_dr); +} + +static void stm32f4xx_usart_reset(DeviceState *dev) +{ + STM32F4XXUsartState *s =3D STM32F4XX_USART(dev); + + s->usart_sr =3D USART_SR_RESET; + s->usart_dr =3D 0x00000000; + s->usart_brr =3D 0x00000000; + s->usart_cr1 =3D 0x00000000; + s->usart_cr2 =3D 0x00000000; + s->usart_cr3 =3D 0x00000000; + s->usart_gtpr =3D 0x00000000; + + qemu_set_irq(s->irq, 0); +} + +static uint64_t stm32f4xx_usart_read(void *opaque, hwaddr addr, + unsigned int size) +{ + STM32F4XXUsartState *s =3D opaque; + uint64_t retvalue; + + DB_PRINT("Read 0x%"HWADDR_PRIx"\n", addr); + + switch (addr) { + case USART_SR: + retvalue =3D s->usart_sr; + qemu_chr_fe_accept_input(&s->chr); + return retvalue; + case USART_DR: + DB_PRINT("Value: 0x%" PRIx32 ", %c\n", s->usart_dr, (char) s->usar= t_dr); + s->usart_sr |=3D USART_SR_TXE; + s->usart_sr &=3D ~USART_SR_RXNE; + qemu_chr_fe_accept_input(&s->chr); + qemu_set_irq(s->irq, 0); + if (s->usart_cr1 & USART_CR1_M) { + return s->usart_dr & 0x1FF; + } else { + return s->usart_dr & 0xFF; + } + case USART_BRR: + return s->usart_brr; + case USART_CR1: + return s->usart_cr1; + case USART_CR2: + return s->usart_cr2; + case USART_CR3: + return s->usart_cr3; + case USART_GTPR: + return s->usart_gtpr; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr); + return 0; + } + + return 0; +} + +static void stm32f4xx_usart_write(void *opaque, hwaddr addr, + uint64_t val64, unsigned int size) +{ + STM32F4XXUsartState *s =3D opaque; + uint32_t value =3D val64; + unsigned char ch; + + DB_PRINT("Write 0x%" PRIx32 ", 0x%"HWADDR_PRIx"\n", value, addr); + + switch (addr) { + case USART_SR: + if (value <=3D 0x3FF) { + s->usart_sr |=3D value; + } else { + s->usart_sr &=3D value; + } + if (!(s->usart_sr & USART_SR_RXNE)) { + qemu_set_irq(s->irq, 0); + } + return; + case USART_DR: + if (s->usart_cr1 & USART_CR1_M) { + ch =3D value & 0x1FF; + } else { + ch =3D value & 0xFF; + } + if (!(s->usart_cr1 & USART_CR1_TE)) { + return; + } + if ((s->usart_sr & USART_SR_TC)) { + s->usart_sr &=3D ~USART_SR_TC; + } + ch =3D value; + qemu_chr_fe_write_all(&s->chr, &ch, 1); + s->usart_sr |=3D USART_SR_TXE; + if (s->usart_cr1 & USART_CR1_TXEIE) { + qemu_set_irq(s->irq, 0); + } + s->usart_sr |=3D USART_SR_TC; + if (s->usart_cr1 & USART_CR1_TCIE) { + qemu_set_irq(s->irq, 0); + } + break; + case USART_BRR: + s->usart_brr |=3D value & 0xFFFF; + break; + case USART_CR1: + if (!(s->usart_cr1 & USART_CR1_TE) && (value & USART_CR1_TE)) { + s->usart_dr =3D 0xFF; + } + s->usart_cr1 |=3D value & 0xFFFF; + if (s->usart_cr1 & USART_CR1_RXNEIE && + s->usart_sr & USART_SR_RXNE) { + qemu_set_irq(s->irq, 0); + } + break; + case USART_CR2: + s->usart_cr2 |=3D value & 0xFFFF; + break; + case USART_CR3: + s->usart_cr3 |=3D value; + break; + case USART_GTPR: + s->usart_gtpr |=3D value & 0xFFFF; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr); + break; + } +} + +static const MemoryRegionOps stm32f4xx_usart_ops =3D { + .read =3D stm32f4xx_usart_read, + .write =3D stm32f4xx_usart_write, + .endianness =3D DEVICE_NATIVE_ENDIAN, +}; + +static Property stm32f4xx_usart_properties[] =3D { + DEFINE_PROP_CHR("chardev", STM32F4XXUsartState, chr), +}; + +static void stm32f4xx_usart_init(Object *obj) +{ + STM32F4XXUsartState *s =3D STM32F4XX_USART(obj); + + sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq); + + memory_region_init_io(&s->mmio, obj, &stm32f4xx_usart_ops, s, + TYPE_STM32F4XX_USART, 0x400); + sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio); +} + +static void stm32f4xx_usart_realize(DeviceState *dev, Error **errp) +{ + STM32F4XXUsartState *s =3D STM32F4XX_USART(dev); + + qemu_chr_fe_set_handlers(&s->chr, stm32f4xx_usart_can_receive, + stm32f4xx_usart_receive, NULL, NULL, + s, NULL, true); +} + +static void stm32f4xx_usart_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + + device_class_set_legacy_reset(dc, stm32f4xx_usart_reset); + device_class_set_props(dc, stm32f4xx_usart_properties); + dc->realize =3D stm32f4xx_usart_realize; +} + +static const TypeInfo stm32f4xx_usart_info =3D { + .name =3D TYPE_STM32F4XX_USART, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(STM32F4XXUsartState), + .instance_init =3D stm32f4xx_usart_init, + .class_init =3D stm32f4xx_usart_class_init, +}; + +static void stm32f4xx_usart_register_types(void) +{ + type_register_static(&stm32f4xx_usart_info); +} + +type_init(stm32f4xx_usart_register_types) diff --git a/include/hw/arm/stm32f407_soc.h b/include/hw/arm/stm32f407_soc.h index 19191dc44e..6599e8aa48 100644 --- a/include/hw/arm/stm32f407_soc.h +++ b/include/hw/arm/stm32f407_soc.h @@ -6,6 +6,7 @@ #include "hw/arm/armv7m.h" #include "hw/misc/stm32f4xx_syscfg.h" #include "hw/misc/stm32f4xx_exti.h" +#include "hw/char/stm32f4xx_usart.h" =20 #include "qom/object.h" =20 @@ -20,6 +21,12 @@ OBJECT_DECLARE_SIMPLE_TYPE(STM32F407State, STM32F407_SOC) #define SRAM_BASE_ADDRESS 0x20000000 #define SRAM_SIZE (192 * 1024) =20 +#define STM_NUM_USARTS 4 +#define STM32F407_USART1 0x40011000 +#define STM32F407_USART2 0x40004400 +#define STM32F407_USART3 0x40004800 +#define STM32F407_USART6 0x40011400 + =20 struct STM32F407State { /*< private >*/ @@ -31,6 +38,7 @@ struct STM32F407State { =20 STM32F4xxSyscfgState syscfg; STM32F4xxExtiState exti; + STM32F4XXUsartState usart[STM_NUM_USARTS]; =20 Clock *sysclk; Clock *refclk; diff --git a/include/hw/char/stm32f4xx_usart.h b/include/hw/char/stm32f4xx_= usart.h new file mode 100644 index 0000000000..611906bd83 --- /dev/null +++ b/include/hw/char/stm32f4xx_usart.h @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef HW_STM32F4XX_USART_H +#define HW_STM32F4XX_USART_H + +#include "hw/sysbus.h" +#include "chardev/char-fe.h" + +#define USART_SR 0x00 +#define USART_DR 0x04 +#define USART_BRR 0x08 +#define USART_CR1 0x0C +#define USART_CR2 0x10 +#define USART_CR3 0x14 +#define USART_GTPR 0x18 + +#define USART_SR_RESET 0x00C0 + +#define USART_SR_TXE (1 << 7) +#define USART_SR_TC (1 << 6) +#define USART_SR_RXNE (1 << 5) + +#define USART_CR1_UE (1 << 13) +#define USART_CR1_RXNEIE (1 << 5) +#define USART_CR1_TE (1 << 3) +#define USART_CR1_RE (1 << 2) +#define USART_CR1_M (1 << 12) +#define USART_CR1_TXEIE (1 << 7) +#define USART_CR1_TCIE (1 << 6) + +#define USART_CR2_CLKEN (1 << 11) +#define USART_CR2_LINEN (1 << 14) + +#define USART_CR3_SCEN (1 << 5) +#define USART_CR3_HDSEL (1 << 3) +#define USART_CR3_IREN (1 << 1) + +#define TYPE_STM32F4XX_USART "stm32f4xx-usart" +#define STM32F4XX_USART(obj) \ + OBJECT_CHECK(STM32F4XXUsartState, (obj), TYPE_STM32F4XX_USART) + +typedef struct { + /* */ + SysBusDevice parent_obj; + + /* */ + MemoryRegion mmio; + + uint32_t usart_sr; + uint32_t usart_dr; + uint32_t usart_brr; + uint32_t usart_cr1; + uint32_t usart_cr2; + uint32_t usart_cr3; + uint32_t usart_gtpr; + + CharBackend chr; + qemu_irq irq; +} STM32F4XXUsartState; + +#endif --=20 2.43.0