Re: [PATCH] STM32F100: add support for external memory via FSMC
On Thu, Jun 22, 2023 at 10:37 PM Alistair Francis wrote: > On Wed, Jun 21, 2023 at 5:44 AM Lucas Villa Real wrote: > > > > Add support for FSMC on high-density STM32F100 devices and enable > > mapping of additional memory via the `-m SIZE` command-line option. > > FSMC Bank1 can address up to 4x64MB of PSRAM memory at 0x6000. > > Thanks for the patches! > You're welcome! > > > > RCC is needed to enable peripheral clock for FSMC; this commit > > implements support for RCC through the MMIO interface. > > This should be a separate commit. The idea is to break commits up as > small as possible and send a patch series, this makes review much > easier. Each new feature should be its own commit. > Thanks, I'll submit a new patchset as recommended. > > > > Last, high-density devices support up to 32KB of static SRAM, so > > adjust SRAM_SIZE accordingly. > > Also, can you include a link to the documentation in the commit message? > Absolutely. > > +static const MemoryRegionOps stm32f100_rcc_ops = { > > +.read = stm32f100_rcc_read, > > +.write = stm32f100_rcc_write, > > +.endianness = DEVICE_NATIVE_ENDIAN, > > +}; > > This should be its own file and device that is included > Sounds good, thanks for the guidance. I'll work on this next week. Best regards, Lucas
Re: [PATCH] STM32F100: add support for external memory via FSMC
On Wed, Jun 21, 2023 at 5:44 AM Lucas Villa Real wrote: > > Add support for FSMC on high-density STM32F100 devices and enable > mapping of additional memory via the `-m SIZE` command-line option. > FSMC Bank1 can address up to 4x64MB of PSRAM memory at 0x6000. Thanks for the patches! > > RCC is needed to enable peripheral clock for FSMC; this commit > implements support for RCC through the MMIO interface. This should be a separate commit. The idea is to break commits up as small as possible and send a patch series, this makes review much easier. Each new feature should be its own commit. > > Last, high-density devices support up to 32KB of static SRAM, so > adjust SRAM_SIZE accordingly. Also, can you include a link to the documentation in the commit message? > > Signed-off-by: Lucas C. Villa Real > --- > docs/system/arm/stm32.rst| 12 ++- > hw/arm/Kconfig | 1 + > hw/arm/stm32f100_soc.c | 102 +++- > hw/arm/stm32f1_generic.c | 12 +++ > hw/misc/Kconfig | 3 + > hw/misc/meson.build | 1 + > hw/misc/stm32f1xx_fsmc.c | 155 +++ > include/hw/arm/stm32f100_soc.h | 24 - > include/hw/misc/stm32f1xx_fsmc.h | 62 + > 9 files changed, 368 insertions(+), 4 deletions(-) > create mode 100644 hw/misc/stm32f1xx_fsmc.c > create mode 100644 include/hw/misc/stm32f1xx_fsmc.h > > diff --git a/docs/system/arm/stm32.rst b/docs/system/arm/stm32.rst > index d0a3b1a7eb..40de58ed04 100644 > --- a/docs/system/arm/stm32.rst > +++ b/docs/system/arm/stm32.rst > @@ -40,6 +40,8 @@ Supported devices > * SPI controller > * System configuration (SYSCFG) > * Timer controller (TIMER) > + * Reset and Clock Controller (RCC) > + * Flexible static memory controller (FSMC) > > Missing devices > --- > @@ -57,7 +59,6 @@ Missing devices > * Power supply configuration (PWR) > * Random Number Generator (RNG) > * Real-Time Clock (RTC) controller > - * Reset and Clock Controller (RCC) > * Secure Digital Input/Output (SDIO) interface > * USB OTG > * Watchdog controller (IWDG, WWDG) > @@ -78,4 +79,11 @@ to select the device density line. The following values > are supported: > > .. code-block:: bash > > - $ qemu-system-arm -M stm32f1-generic -global stm32f100-soc.density=medium > ... > \ No newline at end of file > + $ qemu-system-arm -M stm32f1-generic -global stm32f100-soc.density=medium > ... > + > +High-density devices can also enable up to 256 MB of external memory using > +the `-m SIZE` option. The memory is mapped at address 0x6000. Example: > + > +.. code-block:: bash > + > + $ qemu-system-arm -M stm32f1-generic -m 64M ... > \ No newline at end of file > diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig > index 822441945c..dd48068108 100644 > --- a/hw/arm/Kconfig > +++ b/hw/arm/Kconfig > @@ -433,6 +433,7 @@ config RASPI > config STM32F100_SOC > bool > select ARM_V7M > +select STM32F1XX_FSMC > select STM32F2XX_USART > select STM32F2XX_SPI > > diff --git a/hw/arm/stm32f100_soc.c b/hw/arm/stm32f100_soc.c > index c157ffd644..a2b863d309 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 "qemu/log.h" > #include "hw/arm/boot.h" > #include "exec/address-spaces.h" > #include "hw/arm/stm32f100_soc.h" > @@ -40,9 +41,85 @@ static const uint32_t usart_addr[STM_NUM_USARTS] = { > 0x40013800, 0x40004400, > 0x40004800 }; > static const uint32_t spi_addr[STM_NUM_SPIS] = { 0x40013000, 0x40003800, > 0x40003C00 }; > +static const uint32_t fsmc_addr = 0xA000; > > static const int usart_irq[STM_NUM_USARTS] = {37, 38, 39}; > static const int spi_irq[STM_NUM_SPIS] = {35, 36, 51}; > +static const int fsmc_irq = 48; > + > +static uint64_t stm32f100_rcc_read(void *h, hwaddr offset, unsigned size) > +{ > +STM32F100State *s = (STM32F100State *) h; > +switch (offset) { > +case 0x00: > +return s->rcc.cr; > +case 0x04: > +return s->rcc.cfgr; > +case 0x08: > +return s->rcc.cir; > +case 0x0C: > +return s->rcc.apb2rstr; > +case 0x10: > +return s->rcc.apb1rstr; > +case 0x14: > +return s->rcc.ahbenr; > +case 0x18: > +return s->rcc.apb2enr; > +case 0x1C: > +return s->rcc.apb1enr; > +case 0x20: > +return s->rcc.bdcr; > +case 0x24: > +return s->rcc.csr; > +case 0x2C: > +return s->rcc.cfgr2; > +default: > +qemu_log_mask(LOG_GUEST_ERROR, > + "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, offset); > +} > +return 0; > +} > + > +static void stm32f100_rcc_write(void *h, hwaddr offset, uint64_t value64, > +unsigned size) > +{ > +STM32F100State *s = (STM32F100State *) h; > +uint32_t value = value64
[PATCH] STM32F100: add support for external memory via FSMC
Add support for FSMC on high-density STM32F100 devices and enable mapping of additional memory via the `-m SIZE` command-line option. FSMC Bank1 can address up to 4x64MB of PSRAM memory at 0x6000. RCC is needed to enable peripheral clock for FSMC; this commit implements support for RCC through the MMIO interface. Last, high-density devices support up to 32KB of static SRAM, so adjust SRAM_SIZE accordingly. Signed-off-by: Lucas C. Villa Real --- docs/system/arm/stm32.rst| 12 ++- hw/arm/Kconfig | 1 + hw/arm/stm32f100_soc.c | 102 +++- hw/arm/stm32f1_generic.c | 12 +++ hw/misc/Kconfig | 3 + hw/misc/meson.build | 1 + hw/misc/stm32f1xx_fsmc.c | 155 +++ include/hw/arm/stm32f100_soc.h | 24 - include/hw/misc/stm32f1xx_fsmc.h | 62 + 9 files changed, 368 insertions(+), 4 deletions(-) create mode 100644 hw/misc/stm32f1xx_fsmc.c create mode 100644 include/hw/misc/stm32f1xx_fsmc.h diff --git a/docs/system/arm/stm32.rst b/docs/system/arm/stm32.rst index d0a3b1a7eb..40de58ed04 100644 --- a/docs/system/arm/stm32.rst +++ b/docs/system/arm/stm32.rst @@ -40,6 +40,8 @@ Supported devices * SPI controller * System configuration (SYSCFG) * Timer controller (TIMER) + * Reset and Clock Controller (RCC) + * Flexible static memory controller (FSMC) Missing devices --- @@ -57,7 +59,6 @@ Missing devices * Power supply configuration (PWR) * Random Number Generator (RNG) * Real-Time Clock (RTC) controller - * Reset and Clock Controller (RCC) * Secure Digital Input/Output (SDIO) interface * USB OTG * Watchdog controller (IWDG, WWDG) @@ -78,4 +79,11 @@ to select the device density line. The following values are supported: .. code-block:: bash - $ qemu-system-arm -M stm32f1-generic -global stm32f100-soc.density=medium ... \ No newline at end of file + $ qemu-system-arm -M stm32f1-generic -global stm32f100-soc.density=medium ... + +High-density devices can also enable up to 256 MB of external memory using +the `-m SIZE` option. The memory is mapped at address 0x6000. Example: + +.. code-block:: bash + + $ qemu-system-arm -M stm32f1-generic -m 64M ... \ No newline at end of file diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index 822441945c..dd48068108 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -433,6 +433,7 @@ config RASPI config STM32F100_SOC bool select ARM_V7M +select STM32F1XX_FSMC select STM32F2XX_USART select STM32F2XX_SPI diff --git a/hw/arm/stm32f100_soc.c b/hw/arm/stm32f100_soc.c index c157ffd644..a2b863d309 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 "qemu/log.h" #include "hw/arm/boot.h" #include "exec/address-spaces.h" #include "hw/arm/stm32f100_soc.h" @@ -40,9 +41,85 @@ static const uint32_t usart_addr[STM_NUM_USARTS] = { 0x40013800, 0x40004400, 0x40004800 }; static const uint32_t spi_addr[STM_NUM_SPIS] = { 0x40013000, 0x40003800, 0x40003C00 }; +static const uint32_t fsmc_addr = 0xA000; static const int usart_irq[STM_NUM_USARTS] = {37, 38, 39}; static const int spi_irq[STM_NUM_SPIS] = {35, 36, 51}; +static const int fsmc_irq = 48; + +static uint64_t stm32f100_rcc_read(void *h, hwaddr offset, unsigned size) +{ +STM32F100State *s = (STM32F100State *) h; +switch (offset) { +case 0x00: +return s->rcc.cr; +case 0x04: +return s->rcc.cfgr; +case 0x08: +return s->rcc.cir; +case 0x0C: +return s->rcc.apb2rstr; +case 0x10: +return s->rcc.apb1rstr; +case 0x14: +return s->rcc.ahbenr; +case 0x18: +return s->rcc.apb2enr; +case 0x1C: +return s->rcc.apb1enr; +case 0x20: +return s->rcc.bdcr; +case 0x24: +return s->rcc.csr; +case 0x2C: +return s->rcc.cfgr2; +default: +qemu_log_mask(LOG_GUEST_ERROR, + "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, offset); +} +return 0; +} + +static void stm32f100_rcc_write(void *h, hwaddr offset, uint64_t value64, +unsigned size) +{ +STM32F100State *s = (STM32F100State *) h; +uint32_t value = value64 & 0x; + +switch (offset) { +case 0x00: +s->rcc.cr = value; +case 0x04: +s->rcc.cfgr = value; +case 0x08: +s->rcc.cir = value; +case 0x0C: +s->rcc.apb2rstr = value; +case 0x10: +s->rcc.apb1rstr = value; +case 0x14: +s->rcc.ahbenr = value; +case 0x18: +s->rcc.apb2enr = value; +case 0x1C: +s->rcc.apb1enr = value; +case 0x20: +s->rcc.bdcr = value; +case 0x24: +s->rcc.csr = value; +case 0x2C: +s->rcc.cfgr2 = value; +default: +
[PATCH] STM32F100: add support for external memory via FSMC
Add support for FSMC on high-density STM32F100 devices and enable mapping of additional memory via the `-m SIZE` command-line option. FSMC Bank1 can address up to 4x64MB of PSRAM memory at 0x6000. RCC is needed to enable peripheral clock for FSMC; this commit implements support for RCC through the MMIO interface. Last, high-density devices support up to 32KB of static SRAM, so adjust SRAM_SIZE accordingly. Signed-off-by: Lucas C. Villa Real --- docs/system/arm/stm32.rst| 12 ++- hw/arm/Kconfig | 1 + hw/arm/stm32f100_soc.c | 102 +++- hw/arm/stm32f1_generic.c | 12 +++ hw/misc/Kconfig | 3 + hw/misc/meson.build | 1 + hw/misc/stm32f1xx_fsmc.c | 155 +++ include/hw/arm/stm32f100_soc.h | 24 - include/hw/misc/stm32f1xx_fsmc.h | 62 + 9 files changed, 368 insertions(+), 4 deletions(-) create mode 100644 hw/misc/stm32f1xx_fsmc.c create mode 100644 include/hw/misc/stm32f1xx_fsmc.h diff --git a/docs/system/arm/stm32.rst b/docs/system/arm/stm32.rst index d0a3b1a7eb..40de58ed04 100644 --- a/docs/system/arm/stm32.rst +++ b/docs/system/arm/stm32.rst @@ -40,6 +40,8 @@ Supported devices * SPI controller * System configuration (SYSCFG) * Timer controller (TIMER) + * Reset and Clock Controller (RCC) + * Flexible static memory controller (FSMC) Missing devices --- @@ -57,7 +59,6 @@ Missing devices * Power supply configuration (PWR) * Random Number Generator (RNG) * Real-Time Clock (RTC) controller - * Reset and Clock Controller (RCC) * Secure Digital Input/Output (SDIO) interface * USB OTG * Watchdog controller (IWDG, WWDG) @@ -78,4 +79,11 @@ to select the device density line. The following values are supported: .. code-block:: bash - $ qemu-system-arm -M stm32f1-generic -global stm32f100-soc.density=medium ... \ No newline at end of file + $ qemu-system-arm -M stm32f1-generic -global stm32f100-soc.density=medium ... + +High-density devices can also enable up to 256 MB of external memory using +the `-m SIZE` option. The memory is mapped at address 0x6000. Example: + +.. code-block:: bash + + $ qemu-system-arm -M stm32f1-generic -m 64M ... \ No newline at end of file diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index 822441945c..dd48068108 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -433,6 +433,7 @@ config RASPI config STM32F100_SOC bool select ARM_V7M +select STM32F1XX_FSMC select STM32F2XX_USART select STM32F2XX_SPI diff --git a/hw/arm/stm32f100_soc.c b/hw/arm/stm32f100_soc.c index c157ffd644..a2b863d309 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 "qemu/log.h" #include "hw/arm/boot.h" #include "exec/address-spaces.h" #include "hw/arm/stm32f100_soc.h" @@ -40,9 +41,85 @@ static const uint32_t usart_addr[STM_NUM_USARTS] = { 0x40013800, 0x40004400, 0x40004800 }; static const uint32_t spi_addr[STM_NUM_SPIS] = { 0x40013000, 0x40003800, 0x40003C00 }; +static const uint32_t fsmc_addr = 0xA000; static const int usart_irq[STM_NUM_USARTS] = {37, 38, 39}; static const int spi_irq[STM_NUM_SPIS] = {35, 36, 51}; +static const int fsmc_irq = 48; + +static uint64_t stm32f100_rcc_read(void *h, hwaddr offset, unsigned size) +{ +STM32F100State *s = (STM32F100State *) h; +switch (offset) { +case 0x00: +return s->rcc.cr; +case 0x04: +return s->rcc.cfgr; +case 0x08: +return s->rcc.cir; +case 0x0C: +return s->rcc.apb2rstr; +case 0x10: +return s->rcc.apb1rstr; +case 0x14: +return s->rcc.ahbenr; +case 0x18: +return s->rcc.apb2enr; +case 0x1C: +return s->rcc.apb1enr; +case 0x20: +return s->rcc.bdcr; +case 0x24: +return s->rcc.csr; +case 0x2C: +return s->rcc.cfgr2; +default: +qemu_log_mask(LOG_GUEST_ERROR, + "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, offset); +} +return 0; +} + +static void stm32f100_rcc_write(void *h, hwaddr offset, uint64_t value64, +unsigned size) +{ +STM32F100State *s = (STM32F100State *) h; +uint32_t value = value64 & 0x; + +switch (offset) { +case 0x00: +s->rcc.cr = value; +case 0x04: +s->rcc.cfgr = value; +case 0x08: +s->rcc.cir = value; +case 0x0C: +s->rcc.apb2rstr = value; +case 0x10: +s->rcc.apb1rstr = value; +case 0x14: +s->rcc.ahbenr = value; +case 0x18: +s->rcc.apb2enr = value; +case 0x1C: +s->rcc.apb1enr = value; +case 0x20: +s->rcc.bdcr = value; +case 0x24: +s->rcc.csr = value; +case 0x2C: +s->rcc.cfgr2 = value; +default: +