[PATCH RFC v2 3/5] hw/arm/stm32f100: instantiate and map GPIO ports
Jack Wang <[email protected]>
| Newsgroups | org.nongnu.qemu-arm,org.nongnu.qemu-devel,org.nongnu.qemu-rust |
|---|---|
| Message-ID | <[email protected]> |
Instantiate the Rust STM32F1xx GPIO device for GPIOA through GPIOE on the STM32F100RBT6 used by the stm32vldiscovery machine. Use a fixed-size address table tied to STM32F100_NUM_GPIOS. When the Rust type is unavailable, retain the existing unimplemented-device regions so a --disable-rust build does not leave the GPIO windows unbacked. Do not connect the GPIO ports directly to the NVIC because external interrupts are routed through the currently unmodelled EXTI. Signed-off-by: Jack Wang <[email protected]> --- hw/arm/Kconfig | 1 + hw/arm/stm32f100_soc.c | 35 ++++++++++++++++++++++++++++++----- include/hw/arm/stm32f100_soc.h | 2 ++ 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index 260d2f0751..6333c0ca09 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -373,6 +373,7 @@ config STM32F100_SOC select ARM_V7M select STM32F2XX_USART select STM32F2XX_SPI + select STM32F1XX_GPIO if HAVE_RUST config STM32F205_SOC bool diff --git a/hw/arm/stm32f100_soc.c b/hw/arm/stm32f100_soc.c index 2358368dba..769f8e5ff0 100644 --- a/hw/arm/stm32f100_soc.c +++ b/hw/arm/stm32f100_soc.c @@ -26,6 +26,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qemu/module.h" +#include "qom/object.h" #include "hw/arm/boot.h" #include "system/address-spaces.h" #include "hw/arm/stm32f100_soc.h" @@ -36,10 +37,20 @@ /* stm32f100_soc implementation is derived from stm32f205_soc */ +#define TYPE_STM32F1XX_GPIO_RUST "stm32f1xx-gpio-rust" + static const uint32_t usart_addr[STM_NUM_USARTS] = { 0x40013800, 0x40004400, 0x40004800 }; static const uint32_t spi_addr[STM_NUM_SPIS] = { 0x40013000, 0x40003800 }; +static const uint32_t gpio_addr[STM32F100_NUM_GPIOS] = { + 0x40010800, 0x40010c00, 0x40011000, 0x40011400, 0x40011800, +}; + +static const char *const gpio_name[STM32F100_NUM_GPIOS] = { + "GPIOA", "GPIOB", "GPIOC", "GPIOD", "GPIOE", +}; + static const int usart_irq[STM_NUM_USARTS] = {37, 38, 39}; static const int spi_irq[STM_NUM_SPIS] = {35, 36}; @@ -149,6 +160,25 @@ static void stm32f100_soc_realize(DeviceState *dev_soc, Error **errp) sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(armv7m, spi_irq[i])); } + /* GPIO interrupts are routed through the currently unmodelled EXTI. */ + if (object_class_by_name(TYPE_STM32F1XX_GPIO_RUST)) { + for (i = 0; i < STM32F100_NUM_GPIOS; i++) { + g_autofree char *name = g_strdup_printf("gpio%c", 'a' + i); + + s->gpio[i] = qdev_new(TYPE_STM32F1XX_GPIO_RUST); + object_property_add_child(OBJECT(s), name, OBJECT(s->gpio[i])); + busdev = SYS_BUS_DEVICE(s->gpio[i]); + if (!sysbus_realize_and_unref(busdev, errp)) { + return; + } + sysbus_mmio_map(busdev, 0, gpio_addr[i]); + } + } else { + for (i = 0; i < STM32F100_NUM_GPIOS; i++) { + create_unimplemented_device(gpio_name[i], gpio_addr[i], 0x400); + } + } + create_unimplemented_device("timer[2]", 0x40000000, 0x400); create_unimplemented_device("timer[3]", 0x40000400, 0x400); create_unimplemented_device("timer[4]", 0x40000800, 0x400); @@ -165,11 +195,6 @@ static void stm32f100_soc_realize(DeviceState *dev_soc, Error **errp) create_unimplemented_device("CEC", 0x40007800, 0x400); create_unimplemented_device("AFIO", 0x40010000, 0x400); create_unimplemented_device("EXTI", 0x40010400, 0x400); - create_unimplemented_device("GPIOA", 0x40010800, 0x400); - create_unimplemented_device("GPIOB", 0x40010C00, 0x400); - create_unimplemented_device("GPIOC", 0x40011000, 0x400); - create_unimplemented_device("GPIOD", 0x40011400, 0x400); - create_unimplemented_device("GPIOE", 0x40011800, 0x400); create_unimplemented_device("ADC1", 0x40012400, 0x400); create_unimplemented_device("timer[1]", 0x40012C00, 0x400); create_unimplemented_device("timer[15]", 0x40014000, 0x400); diff --git a/include/hw/arm/stm32f100_soc.h b/include/hw/arm/stm32f100_soc.h index 4c113d6774..401794242d 100644 --- a/include/hw/arm/stm32f100_soc.h +++ b/include/hw/arm/stm32f100_soc.h @@ -36,6 +36,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(STM32F100State, STM32F100_SOC) #define STM_NUM_USARTS 3 #define STM_NUM_SPIS 2 +#define STM32F100_NUM_GPIOS 5 #define FLASH_BASE_ADDRESS 0x08000000 #define FLASH_SIZE (128 * 1024) @@ -49,6 +50,7 @@ struct STM32F100State { STM32F2XXUsartState usart[STM_NUM_USARTS]; STM32F2XXSPIState spi[STM_NUM_SPIS]; + DeviceState *gpio[STM32F100_NUM_GPIOS]; MemoryRegion sram; MemoryRegion flash; -- 2.53.0