Re: [PATCH] STM32F100: add support for external memory via FSMC

2023-06-24 Thread Lucas C. Villa Real
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

2023-06-22 Thread Alistair Francis
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

2023-06-20 Thread Lucas Villa Real
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

2023-06-20 Thread Lucas Villa Real
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:
+