From 0fffb2d6db2eae033061da3dce0be30480627a9b Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Wed, 2 Aug 2023 16:57:22 +0200 Subject: [PATCH 01/15] drivers: flash: stm32 flash driver has a Kconfig STM32_MEMMAP This CONFIG_STM32_MEMMAP is for enabling the MemoryMapped mode on external octo or quad spi memory. In this case, the flash_stm32_read is done in mem map mode the flash_stm32_erase is not available. Signed-off-by: Francois Ramu --- drivers/flash/Kconfig.stm32 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/flash/Kconfig.stm32 b/drivers/flash/Kconfig.stm32 index a452ab8b98d0..d431b76cbe19 100644 --- a/drivers/flash/Kconfig.stm32 +++ b/drivers/flash/Kconfig.stm32 @@ -72,4 +72,11 @@ config FLASH_STM32_BLOCK_REGISTERS registers improves system security, because flash content (or protection settings) can't be changed even when exploit was found. +config STM32_MEMMAP + bool "NOR Flash in MemoryMapped for XiP" + depends on XIP + help + This option enables the XIP mode for the external NOR flash + mounted on STM32 boards. + endif # SOC_FLASH_STM32 From d03476fb6981e7c2c50b47bf67d0ef85435efe88 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Thu, 1 Jun 2023 15:39:02 +0200 Subject: [PATCH 02/15] drivers: flash: stm32 ospi drivers with Memorymapped mode Enable the MemoryMapped Mode for the stm32 octoFlash driver Configure the Flash in MemoryMapped to use in XiP mode. With this mode the erase and write are not supported. Address and size are given by the DTS register property. Signed-off-by: Francois Ramu --- drivers/flash/flash_stm32_ospi.c | 187 ++++++++++++++++++++++++++++++- 1 file changed, 183 insertions(+), 4 deletions(-) diff --git a/drivers/flash/flash_stm32_ospi.c b/drivers/flash/flash_stm32_ospi.c index 030dc8bd1563..dbc492d78f94 100644 --- a/drivers/flash/flash_stm32_ospi.c +++ b/drivers/flash/flash_stm32_ospi.c @@ -975,11 +975,136 @@ static int stm32_ospi_mem_reset(const struct device *dev) return 0; } +#ifdef CONFIG_STM32_MEMMAP +/* Function to configure the octoflash in MemoryMapped mode */ +static int stm32_ospi_set_memorymap(const struct device *dev) +{ + HAL_StatusTypeDef ret; + const struct flash_stm32_ospi_config *dev_cfg = dev->config; + struct flash_stm32_ospi_data *dev_data = dev->data; + OSPI_RegularCmdTypeDef s_command; + OSPI_MemoryMappedTypeDef s_MemMappedCfg = {0}; + + /* Configure octoflash in MemoryMapped mode */ + if ((dev_cfg->data_mode == OSPI_SPI_MODE) && + (stm32_ospi_hal_address_size(dev) == HAL_OSPI_ADDRESS_24_BITS)) { + /* OPI mode and 3-bytes address size not supported by memory */ + LOG_ERR("OSPI_SPI_MODE in 3Bytes addressing is not supported"); + return -EIO; + } + + /* Initialize the read command */ + s_command.OperationType = HAL_OSPI_OPTYPE_READ_CFG; + s_command.FlashId = HAL_OSPI_FLASH_ID_1; + s_command.InstructionMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER) + ? ((dev_cfg->data_mode == OSPI_SPI_MODE) + ? HAL_OSPI_INSTRUCTION_1_LINE + : HAL_OSPI_INSTRUCTION_8_LINES) + : HAL_OSPI_INSTRUCTION_8_LINES; + s_command.InstructionDtrMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER) + ? HAL_OSPI_INSTRUCTION_DTR_DISABLE + : HAL_OSPI_INSTRUCTION_DTR_ENABLE; + s_command.InstructionSize = (dev_cfg->data_rate == OSPI_STR_TRANSFER) + ? ((dev_cfg->data_mode == OSPI_SPI_MODE) + ? HAL_OSPI_INSTRUCTION_8_BITS + : HAL_OSPI_INSTRUCTION_16_BITS) + : HAL_OSPI_INSTRUCTION_16_BITS; + s_command.Instruction = (dev_cfg->data_rate == OSPI_STR_TRANSFER) + ? ((dev_cfg->data_mode == OSPI_SPI_MODE) + ? ((stm32_ospi_hal_address_size(dev) == + HAL_OSPI_ADDRESS_24_BITS) + ? SPI_NOR_CMD_READ_FAST + : SPI_NOR_CMD_READ_FAST_4B) + : SPI_NOR_OCMD_RD) + : SPI_NOR_OCMD_DTR_RD; + s_command.AddressMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER) + ? ((dev_cfg->data_mode == OSPI_SPI_MODE) + ? HAL_OSPI_ADDRESS_1_LINE + : HAL_OSPI_ADDRESS_8_LINES) + : HAL_OSPI_ADDRESS_8_LINES; + s_command.AddressDtrMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER) + ? HAL_OSPI_ADDRESS_DTR_DISABLE + : HAL_OSPI_ADDRESS_DTR_ENABLE; + s_command.AddressSize = (dev_cfg->data_rate == OSPI_STR_TRANSFER) + ? stm32_ospi_hal_address_size(dev) + : HAL_OSPI_ADDRESS_32_BITS; + s_command.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + s_command.DataMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER) + ? ((dev_cfg->data_mode == OSPI_SPI_MODE) + ? HAL_OSPI_DATA_1_LINE + : HAL_OSPI_DATA_8_LINES) + : HAL_OSPI_DATA_8_LINES; + s_command.DataDtrMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER) + ? HAL_OSPI_DATA_DTR_DISABLE + : HAL_OSPI_DATA_DTR_ENABLE; + s_command.DummyCycles = (dev_cfg->data_rate == OSPI_STR_TRANSFER) + ? ((dev_cfg->data_mode == OSPI_SPI_MODE) + ? SPI_NOR_DUMMY_RD + : SPI_NOR_DUMMY_RD_OCTAL) + : SPI_NOR_DUMMY_RD_OCTAL_DTR; + s_command.DQSMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER) + ? HAL_OSPI_DQS_DISABLE + : HAL_OSPI_DQS_ENABLE; + + s_command.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; + + ret = HAL_OSPI_Command(&dev_data->hospi, &s_command, HAL_OSPI_TIMEOUT_DEFAULT_VALUE); + if (ret != HAL_OK) { + LOG_ERR("%d: Failed to set memory map", ret); + return -EIO; + } + + /* Initialize the program command */ + s_command.OperationType = HAL_OSPI_OPTYPE_WRITE_CFG; + if (dev_cfg->data_rate == OSPI_STR_TRANSFER) { + s_command.Instruction = (dev_cfg->data_mode == OSPI_SPI_MODE) + ? ((stm32_ospi_hal_address_size(dev) == + HAL_OSPI_ADDRESS_24_BITS) + ? SPI_NOR_CMD_PP + : SPI_NOR_CMD_PP_4B) + : SPI_NOR_OCMD_PAGE_PRG; + } else { + s_command.Instruction = SPI_NOR_OCMD_PAGE_PRG; + } + s_command.DQSMode = HAL_OSPI_DQS_DISABLE; + s_command.DummyCycles = 0U; + + ret = HAL_OSPI_Command(&dev_data->hospi, &s_command, HAL_OSPI_TIMEOUT_DEFAULT_VALUE); + if (ret != HAL_OK) { + LOG_ERR("%d: Failed to set memory mapped", ret); + return -EIO; + } + + /* Enable the memory-mapping */ + s_MemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_DISABLE; + + ret = HAL_OSPI_MemoryMapped(&dev_data->hospi, &s_MemMappedCfg); + if (ret != HAL_OK) { + LOG_ERR("%d: Failed to set memory mapped", ret); + return -EIO; + } + + LOG_INF("MemoryMap mode enabled"); + return 0; +} + +/* Function to return true if the octoflash is in MemoryMapped else false */ +static bool stm32_ospi_is_memorymap(const struct device *dev) +{ + struct flash_stm32_ospi_data *dev_data = dev->data; + + return ((READ_BIT(dev_data->hospi.Instance->CR, + OCTOSPI_CR_FMODE) == OCTOSPI_CR_FMODE) ? + true : false); +} +#endif /* CONFIG_STM32_MEMMAP */ + /* * Function to erase the flash : chip or sector with possible OSPI/SPI and STR/DTR * to erase the complete chip (using dedicated command) : * set size >= flash size * set addr = 0 + * NOTE: cannot erase in MemoryMapped mode */ static int flash_stm32_ospi_erase(const struct device *dev, off_t addr, size_t size) @@ -1009,6 +1134,13 @@ static int flash_stm32_ospi_erase(const struct device *dev, off_t addr, return -ENOTSUP; } +#ifdef CONFIG_STM32_MEMMAP + if (stm32_ospi_is_memorymap(dev)) { + LOG_DBG("MemoryMap : cannot erase"); + return 0; + } +#endif /* CONFIG_STM32_MEMMAP */ + OSPI_RegularCmdTypeDef cmd_erase = { .OperationType = HAL_OSPI_OPTYPE_COMMON_CFG, .FlashId = HAL_OSPI_FLASH_ID_1, @@ -1023,9 +1155,9 @@ static int flash_stm32_ospi_erase(const struct device *dev, off_t addr, if (stm32_ospi_mem_ready(dev_data, dev_cfg->data_mode, dev_cfg->data_rate) != 0) { - ospi_unlock_thread(dev); LOG_ERR("Erase failed : flash busy"); - return -EBUSY; + ret = -EBUSY; + goto end_erase; } cmd_erase.InstructionMode = (dev_cfg->data_mode == OSPI_OPI_MODE) @@ -1134,6 +1266,7 @@ static int flash_stm32_ospi_erase(const struct device *dev, off_t addr, } +end_erase: ospi_unlock_thread(dev); return ret; @@ -1158,6 +1291,17 @@ static int flash_stm32_ospi_read(const struct device *dev, off_t addr, return 0; } +#ifdef CONFIG_STM32_MEMMAP + if (stm32_ospi_is_memorymap(dev)) { + LOG_DBG("MemoryMapped Read offset: 0x%lx, len: %zu", + (long)(STM32_OSPI_BASE_ADDRESS + addr), + size); + memcpy(data, (uint8_t *)STM32_OSPI_BASE_ADDRESS + addr, size); + + return 0; + } +#endif /* CONFIG_STM32_MEMMAP */ + OSPI_RegularCmdTypeDef cmd = ospi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate); if (dev_cfg->data_mode != OSPI_OPI_MODE) { @@ -1226,7 +1370,10 @@ static int flash_stm32_ospi_read(const struct device *dev, off_t addr, return ret; } -/* Function to write the flash (page program) : with possible OSPI/SPI and STR/DTR */ +/* + * Function to write the flash (page program) : with possible OSPI/SPI and STR/DTR + * NOTE: writing in MemoryMapped mode is not guaranted + */ static int flash_stm32_ospi_write(const struct device *dev, off_t addr, const void *data, size_t size) { @@ -1246,6 +1393,16 @@ static int flash_stm32_ospi_write(const struct device *dev, off_t addr, return 0; } +#ifdef CONFIG_STM32_MEMMAP + if (stm32_ospi_is_memorymap(dev)) { + LOG_DBG("MemoryMapped Write offset: 0x%lx, len: %zu", + (long)(STM32_OSPI_BASE_ADDRESS + addr), + size); + memcpy((uint8_t *)STM32_OSPI_BASE_ADDRESS + addr, data, size); + + return 0; + } +#endif /* CONFIG_STM32_MEMMAP */ /* page program for STR or DTR mode */ OSPI_RegularCmdTypeDef cmd_pp = ospi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate); @@ -1910,6 +2067,16 @@ static int flash_stm32_ospi_init(const struct device *dev) return -ENODEV; } +#ifdef CONFIG_STM32_MEMMAP + /* If MemoryMapped then configure skip init */ + if (stm32_ospi_is_memorymap(dev)) { + LOG_DBG("NOR init'd in MemMapped mode\n"); + /* Force HAL instance in correct state */ + dev_data->hospi.State = HAL_OSPI_STATE_BUSY_MEM_MAPPED; + return 0; + } +#endif /* CONFIG_STM32_MEMMAP */ + #if STM32_OSPI_USE_DMA /* * DMA configuration @@ -2289,9 +2456,21 @@ static int flash_stm32_ospi_init(const struct device *dev) } #endif /* CONFIG_FLASH_PAGE_LAYOUT */ - LOG_INF("NOR octo-flash at 0x%lx (0x%x bytes)", +#ifdef CONFIG_STM32_MEMMAP + /* Now configure the octo Flash in MemoryMapped (access by address) */ + ret = stm32_ospi_set_memorymap(dev); + if (ret != 0) { + LOG_ERR("Error (%d): setting NOR in MemoryMapped mode", ret); + return -EINVAL; + } + LOG_DBG("NOR octo-flash in MemoryMapped mode at 0x%lx (0x%x bytes)", + (long)(STM32_OSPI_BASE_ADDRESS), + dev_cfg->flash_size); +#else + LOG_DBG("NOR octo-flash at 0x%lx (0x%x bytes)", (long)(STM32_OSPI_BASE_ADDRESS), dev_cfg->flash_size); +#endif /* CONFIG_STM32_MEMMAP */ return 0; } From de2f839a05074663ca86764fb81b8d9d05e594c8 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Wed, 24 Jan 2024 12:55:47 +0100 Subject: [PATCH 03/15] drivers: flash: stm32 ospi driver aborts memmap before erase/write This change is aborting the memoryMapped mode of the octo-flash before erasing or writing the NOR. Operations are performed in command mode. Reading is always performed in MemoryMapped mode (memcopy) Signed-off-by: Francois Ramu --- drivers/flash/flash_stm32_ospi.c | 48 ++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/drivers/flash/flash_stm32_ospi.c b/drivers/flash/flash_stm32_ospi.c index dbc492d78f94..ba5e842c38a8 100644 --- a/drivers/flash/flash_stm32_ospi.c +++ b/drivers/flash/flash_stm32_ospi.c @@ -1015,7 +1015,7 @@ static int stm32_ospi_set_memorymap(const struct device *dev) HAL_OSPI_ADDRESS_24_BITS) ? SPI_NOR_CMD_READ_FAST : SPI_NOR_CMD_READ_FAST_4B) - : SPI_NOR_OCMD_RD) + : dev_data->read_opcode) : SPI_NOR_OCMD_DTR_RD; s_command.AddressMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER) ? ((dev_cfg->data_mode == OSPI_SPI_MODE) @@ -1080,11 +1080,11 @@ static int stm32_ospi_set_memorymap(const struct device *dev) ret = HAL_OSPI_MemoryMapped(&dev_data->hospi, &s_MemMappedCfg); if (ret != HAL_OK) { - LOG_ERR("%d: Failed to set memory mapped", ret); + LOG_ERR("%d: Failed to enable memory mapped", ret); return -EIO; } - LOG_INF("MemoryMap mode enabled"); + LOG_DBG("MemoryMap mode enabled"); return 0; } @@ -1097,6 +1097,20 @@ static bool stm32_ospi_is_memorymap(const struct device *dev) OCTOSPI_CR_FMODE) == OCTOSPI_CR_FMODE) ? true : false); } + +/* Abort the Memorymapped Mode so that erasing is possible */ +static int stm32_ospi_abort_memmap(const struct device *dev) +{ + struct flash_stm32_ospi_data *dev_data = dev->data; + + if (HAL_OSPI_Abort(&dev_data->hospi) != HAL_OK) { + LOG_ERR("MemoryMap abort failed"); + return -EIO; + } + LOG_DBG("MemoryMap mode disabled"); + + return 0; +} #endif /* CONFIG_STM32_MEMMAP */ /* @@ -1136,8 +1150,12 @@ static int flash_stm32_ospi_erase(const struct device *dev, off_t addr, #ifdef CONFIG_STM32_MEMMAP if (stm32_ospi_is_memorymap(dev)) { - LOG_DBG("MemoryMap : cannot erase"); - return 0; + /* If the Flash is in MemoryMapped mode, abort it and continue */ + LOG_DBG("MemoryMap : disable before erase"); + if (stm32_ospi_abort_memmap(dev) != 0) { + LOG_ERR("MemoryMap not aborted correctly"); + return -EIO; + } } #endif /* CONFIG_STM32_MEMMAP */ @@ -1292,6 +1310,14 @@ static int flash_stm32_ospi_read(const struct device *dev, off_t addr, } #ifdef CONFIG_STM32_MEMMAP + /* If not MemMapped then configure it */ + if (!stm32_ospi_is_memorymap(dev)) { + if (stm32_ospi_set_memorymap(dev) != 0) { + LOG_ERR("READ failed: cannot enable MemoryMap"); + return -EIO; + } + } + LOG_INF("MemoryMap : enable before read"); if (stm32_ospi_is_memorymap(dev)) { LOG_DBG("MemoryMapped Read offset: 0x%lx, len: %zu", (long)(STM32_OSPI_BASE_ADDRESS + addr), @@ -1395,6 +1421,18 @@ static int flash_stm32_ospi_write(const struct device *dev, off_t addr, #ifdef CONFIG_STM32_MEMMAP if (stm32_ospi_is_memorymap(dev)) { + /* If the Flash is in MemoryMapped mode, abort it and continue */ + LOG_INF("MemoryMap : disable before write"); + if (stm32_ospi_abort_memmap(dev) != 0) { + LOG_ERR("MemoryMap not aborted correctly"); + return -EIO; + } + } + if (stm32_ospi_is_memorymap(dev)) { + /* + * If the Flash is in MemoryMapped mode, write by memcopy + * should not due to previous operation + */ LOG_DBG("MemoryMapped Write offset: 0x%lx, len: %zu", (long)(STM32_OSPI_BASE_ADDRESS + addr), size); From de6f1d99309def20038a9fbbdbd134fbefdb3f7e Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Fri, 15 Sep 2023 14:59:43 +0200 Subject: [PATCH 04/15] drivers: clock control of the stm32h7 skips pll1 re-init Skip the PLL1 init if it is already running, this will avoid disabling the PLL when running after a jump from mcuboot. In case of XiP, the pll must not be reinit because it clocks the octo-quad SPI instance which accesses the external NOR flash. Signed-off-by: Francois Ramu --- drivers/clock_control/clock_stm32_ll_h7.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/clock_control/clock_stm32_ll_h7.c b/drivers/clock_control/clock_stm32_ll_h7.c index e4d78e5ce603..e15b291820bc 100644 --- a/drivers/clock_control/clock_stm32_ll_h7.c +++ b/drivers/clock_control/clock_stm32_ll_h7.c @@ -672,6 +672,16 @@ __unused static int set_up_plls(void) { #if defined(STM32_PLL_ENABLED) || defined(STM32_PLL2_ENABLED) || defined(STM32_PLL3_ENABLED) + + /* + * Skip if PLL1 is already configured by the McuBoot + * with ext NOR in MemMapped : application running in external NOR in XiP + * has not necessarily the CONFIG_STM32_MEMMAP + */ + if (LL_RCC_PLL1_IsReady()) { + return 0; + } + int r; uint32_t vco_input_range; uint32_t vco_output_range; From 2249b7e83e599448bd05ebfc8c6243d52ae268a9 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Wed, 31 Jan 2024 11:15:08 +0100 Subject: [PATCH 05/15] samples: code relocation in external memory of stm32 disco kit Define the configuration to run the code_relocation application on the external memory octo flash of the stm32u585 or stm32h7b3i disco kit in XIP Signed-off-by: Francois Ramu --- .../boards/b_u585i_iot02a.conf | 2 ++ .../boards/stm32h7b3i_dk.conf | 2 ++ .../code_relocation_nocopy/linker_arm_nocopy.ld | 14 ++++++++++++++ 3 files changed, 18 insertions(+) create mode 100644 samples/application_development/code_relocation_nocopy/boards/b_u585i_iot02a.conf create mode 100644 samples/application_development/code_relocation_nocopy/boards/stm32h7b3i_dk.conf diff --git a/samples/application_development/code_relocation_nocopy/boards/b_u585i_iot02a.conf b/samples/application_development/code_relocation_nocopy/boards/b_u585i_iot02a.conf new file mode 100644 index 000000000000..eac2504a7850 --- /dev/null +++ b/samples/application_development/code_relocation_nocopy/boards/b_u585i_iot02a.conf @@ -0,0 +1,2 @@ +CONFIG_FLASH=y +CONFIG_STM32_MEMMAP=y diff --git a/samples/application_development/code_relocation_nocopy/boards/stm32h7b3i_dk.conf b/samples/application_development/code_relocation_nocopy/boards/stm32h7b3i_dk.conf new file mode 100644 index 000000000000..eac2504a7850 --- /dev/null +++ b/samples/application_development/code_relocation_nocopy/boards/stm32h7b3i_dk.conf @@ -0,0 +1,2 @@ +CONFIG_FLASH=y +CONFIG_STM32_MEMMAP=y diff --git a/samples/application_development/code_relocation_nocopy/linker_arm_nocopy.ld b/samples/application_development/code_relocation_nocopy/linker_arm_nocopy.ld index 7ead7f6bae48..7d4e3a964fc3 100644 --- a/samples/application_development/code_relocation_nocopy/linker_arm_nocopy.ld +++ b/samples/application_development/code_relocation_nocopy/linker_arm_nocopy.ld @@ -26,6 +26,20 @@ #define EXTFLASH_SIZE DT_PROP_OR(EXTFLASH_NODE, size_in_bytes, \ DT_PROP(EXTFLASH_NODE, size) / 8) +#elif defined(CONFIG_STM32_MEMMAP) && DT_NODE_EXISTS(DT_INST(0, st_stm32_ospi_nor)) +/* On stm32 OSPI, external flash is mapped in XIP region at address given by the reg property. */ + +#define EXTFLASH_NODE DT_INST(0, st_stm32_ospi_nor) +#define EXTFLASH_ADDR DT_REG_ADDR(DT_INST(0, st_stm32_ospi_nor)) +#define EXTFLASH_SIZE DT_REG_ADDR_BY_IDX(DT_INST(0, st_stm32_ospi_nor), 1) + +#elif defined(CONFIG_STM32_MEMMAP) && DT_NODE_EXISTS(DT_INST(0, st_stm32_qspi_nor)) +/* On stm32 QSPI, external flash is mapped in XIP region at address given by the reg property. */ + +#define EXTFLASH_NODE DT_INST(0, st_stm32_qspi_nor) +#define EXTFLASH_ADDR DT_REG_ADDR(DT_INST(0, st_stm32_qspi_nor)) +#define EXTFLASH_SIZE DT_REG_ADDR_BY_IDX(DT_INST(0, st_stm32_qspi_nor), 1) + #else /* From 85e14b6f0630ef72af2a9bfb4c0f6f63cfde38c7 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Mon, 29 Jan 2024 16:54:10 +0100 Subject: [PATCH 06/15] drivers: flash: stm32 qspi driver set NOR flash in MemoryMapped Configures the external NOR Flash in MemoryMapped Mode, at the end of the NOR flash-controller initialization. Then reading/writing are performed in MemoryMapped mode with memcopy (and no more with command mode). In this mode: erasing is not supported anymore. The flash size and address are given by the DTS property. Signed-off-by: Francois Ramu --- drivers/flash/flash_stm32_qspi.c | 101 ++++++++++++++++++++++++++++++- drivers/flash/spi_nor.h | 4 ++ 2 files changed, 104 insertions(+), 1 deletion(-) diff --git a/drivers/flash/flash_stm32_qspi.c b/drivers/flash/flash_stm32_qspi.c index 326c1129a363..a60bab5502ad 100644 --- a/drivers/flash/flash_stm32_qspi.c +++ b/drivers/flash/flash_stm32_qspi.c @@ -385,6 +385,55 @@ static bool qspi_address_is_valid(const struct device *dev, off_t addr, return (addr >= 0) && ((uint64_t)addr + (uint64_t)size <= flash_size); } +#ifdef CONFIG_STM32_MEMMAP +/* Function to return true if the quad-NOR flash is in MemoryMapped else false */ +static bool qspi_is_memorymap(const struct device *dev) +{ + struct flash_stm32_qspi_data *dev_data = dev->data; + + return ((READ_BIT(dev_data->hqspi.Instance->CCR, + QUADSPI_CCR_FMODE) == QUADSPI_CCR_FMODE) ? + true : false); +} + + +/* Function to configure the memmapped mode */ +static int qspi_set_memorymap(const struct device *dev) +{ + HAL_StatusTypeDef ret; + struct flash_stm32_qspi_data *dev_data = dev->data; + QSPI_CommandTypeDef s_command = {0}; + QSPI_MemoryMappedTypeDef s_memmap_cfg; + + /* Reading sequence */ + s_command.Instruction = SPI_NOR_CMD_4READ; /* 0x6B also supported */ + s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; + s_command.AddressMode = QSPI_ADDRESS_4_LINES; + s_command.DataMode = QSPI_DATA_4_LINES; +#ifdef CONFIG_SOC_SERIES_STM32H7X + s_command.AddressSize = QSPI_ADDRESS_32_BITS; + s_command.DummyCycles = SPI_NOR_DUMMY_RD_QUAD; /* less than 10 is too short */ +#else + s_command.AddressSize = QSPI_ADDRESS_24_BITS; + s_command.DummyCycles = 6;/* other value than 6 is too short */ +#endif /* CONFIG_SOC_SERIES_STM32H7X */ + s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + s_command.AlternateBytesSize = QSPI_ALTERNATE_BYTES_8_BITS; + + /* Enable the memory-mapping */ + s_memmap_cfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE; + s_memmap_cfg.TimeOutPeriod = 0; + + ret = HAL_QSPI_MemoryMapped(&dev_data->hqspi, &s_command, &s_memmap_cfg); + if (ret != HAL_OK) { + LOG_ERR("%d: Failed to set memory map", ret); + return -EIO; + } + + return 0; +} +#endif /* CONFIG_STM32_MEMMAP */ + static int flash_stm32_qspi_read(const struct device *dev, off_t addr, void *data, size_t size) { @@ -401,6 +450,15 @@ static int flash_stm32_qspi_read(const struct device *dev, off_t addr, return 0; } +#ifdef CONFIG_STM32_MEMMAP + if (qspi_is_memorymap(dev)) { + LOG_DBG("MemoryMapped Read offset: 0x%lx, len: %zu", + (long)(STM32_QSPI_BASE_ADDRESS + addr), size); + memcpy(data, (uint8_t *)STM32_QSPI_BASE_ADDRESS + addr, size); + + return 0; + } +#endif /* CONFIG_STM32_MEMMAP */ QSPI_CommandTypeDef cmd = { .Instruction = SPI_NOR_CMD_READ, .Address = addr, @@ -460,6 +518,16 @@ static int flash_stm32_qspi_write(const struct device *dev, off_t addr, return 0; } +#ifdef CONFIG_STM32_MEMMAP + if (qspi_is_memorymap(dev)) { + LOG_DBG("MemoryMapped Write offset: 0x%lx, len: %zu", + (long)(STM32_QSPI_BASE_ADDRESS + addr), size); + memcpy((uint8_t *)STM32_QSPI_BASE_ADDRESS + addr, data, size); + + return 0; + } +#endif /* CONFIG_STM32_MEMMAP */ + QSPI_CommandTypeDef cmd_write_en = { .Instruction = SPI_NOR_CMD_WREN, .InstructionMode = QSPI_INSTRUCTION_1_LINE, @@ -541,6 +609,13 @@ static int flash_stm32_qspi_erase(const struct device *dev, off_t addr, return 0; } +#ifdef CONFIG_STM32_MEMMAP + if (qspi_is_memorymap(dev)) { + LOG_INF("MemoryMapped : cannot erase"); + return 0; + } +#endif /* CONFIG_STM32_MEMMAP */ + QSPI_CommandTypeDef cmd_write_en = { .Instruction = SPI_NOR_CMD_WREN, .InstructionMode = QSPI_INSTRUCTION_1_LINE, @@ -913,6 +988,7 @@ static int qspi_write_status_register(const struct device *dev, uint8_t reg_num, return qspi_write_access(dev, &cmd, regs_p, size); } +/* Function send a Write Enable and wait it is effective. */ static int qspi_write_enable(const struct device *dev) { uint8_t reg; @@ -1188,6 +1264,17 @@ static int flash_stm32_qspi_init(const struct device *dev) return ret; } + +#ifdef CONFIG_STM32_MEMMAP + /* If MemoryMapped then configure skip init */ + if (qspi_is_memorymap(dev)) { + LOG_INF("NOR init'd in MemMapped mode\n"); + /* Force HAL instance in correct state */ + dev_data->hqspi.State = HAL_QSPI_STATE_BUSY_MEM_MAPPED; + return 0; + } +#endif /* CONFIG_STM32_MEMMAP */ + #if STM32_QSPI_RESET_GPIO flash_stm32_qspi_gpio_reset(dev); #endif @@ -1367,9 +1454,21 @@ static int flash_stm32_qspi_init(const struct device *dev) } #endif /* CONFIG_FLASH_PAGE_LAYOUT */ - LOG_INF("NOR quad-flash at 0x%lx (0x%x bytes)", +#ifdef CONFIG_STM32_MEMMAP + ret = qspi_set_memorymap(dev); + + if (ret != 0) { + LOG_ERR("Error (%d): setting NOR in MemoryMapped mode", ret); + return -EINVAL; + } + LOG_DBG("NOR quad-flash in MemoryMapped mode at 0x%lx (0x%x bytes)", + (long)(STM32_QSPI_BASE_ADDRESS), + dev_cfg->flash_size); +#else + LOG_DBG("NOR quad-flash at 0x%lx (0x%x bytes)", (long)(STM32_QSPI_BASE_ADDRESS), dev_cfg->flash_size); +#endif /* CONFIG_STM32_MEMMAP */ return 0; } diff --git a/drivers/flash/spi_nor.h b/drivers/flash/spi_nor.h index 5f38c98289f8..23f6124eb288 100644 --- a/drivers/flash/spi_nor.h +++ b/drivers/flash/spi_nor.h @@ -60,6 +60,9 @@ #define SPI_NOR_CMD_PP_1_1_4_4B 0x34 /* Quad Page program (1-1-4) 4 Byte Address */ #define SPI_NOR_CMD_PP_1_4_4_4B 0x3e /* Quad Page program (1-4-4) 4 Byte Address */ +#define SPI_NOR_CMD_RD_VOL_CFG 0x85 /* Read Volatile configuration register */ +#define SPI_NOR_CMD_WR_VOL_CFG 0x81 /* Write Volatile configuration register */ + /* Flash octal opcodes */ #define SPI_NOR_OCMD_SE 0x21DE /* Octal Sector erase */ #define SPI_NOR_OCMD_CE 0xC738 /* Octal Chip erase */ @@ -94,6 +97,7 @@ /* Flash Dummy Cycles values */ #define SPI_NOR_DUMMY_RD 8U +#define SPI_NOR_DUMMY_RD_QUAD 10U #define SPI_NOR_DUMMY_RD_OCTAL 6U #define SPI_NOR_DUMMY_RD_OCTAL_DTR 6U #define SPI_NOR_DUMMY_REG_OCTAL 4U From c956fe7f53158bf1a3028d0f1e59e7ee4410f820 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Thu, 1 Feb 2024 10:16:10 +0100 Subject: [PATCH 07/15] drivers: flash: stm32 qspi driver in Dual Flash Mode when MemoryMapped Configure the quad-spi in DualFlash Mode when enabling the MemoryMapped then reading is possible with memcopy. DUAL flash mode is possible on stm32 series with QUADSPI_CR_DFM Signed-off-by: Francois Ramu --- drivers/flash/flash_stm32_qspi.c | 42 ++++++++++++++++++++++++---- dts/bindings/qspi/st,stm32-qspi.yaml | 2 ++ 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/drivers/flash/flash_stm32_qspi.c b/drivers/flash/flash_stm32_qspi.c index a60bab5502ad..b4c0c40b144e 100644 --- a/drivers/flash/flash_stm32_qspi.c +++ b/drivers/flash/flash_stm32_qspi.c @@ -408,17 +408,20 @@ static int qspi_set_memorymap(const struct device *dev) /* Reading sequence */ s_command.Instruction = SPI_NOR_CMD_4READ; /* 0x6B also supported */ s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; + s_command.AddressMode = QSPI_ADDRESS_1_LINE; s_command.AddressMode = QSPI_ADDRESS_4_LINES; s_command.DataMode = QSPI_DATA_4_LINES; #ifdef CONFIG_SOC_SERIES_STM32H7X s_command.AddressSize = QSPI_ADDRESS_32_BITS; s_command.DummyCycles = SPI_NOR_DUMMY_RD_QUAD; /* less than 10 is too short */ +#elif CONFIG_SOC_SERIES_STM32F7X + s_command.AddressSize = QSPI_ADDRESS_24_BITS; + s_command.DummyCycles = 10;/* other value than 10 is too short */ #else s_command.AddressSize = QSPI_ADDRESS_24_BITS; s_command.DummyCycles = 6;/* other value than 6 is too short */ #endif /* CONFIG_SOC_SERIES_STM32H7X */ s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; - s_command.AlternateBytesSize = QSPI_ALTERNATE_BYTES_8_BITS; /* Enable the memory-mapping */ s_memmap_cfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE; @@ -1368,14 +1371,29 @@ static int flash_stm32_qspi_init(const struct device *dev) /* Give a bit position from 0 to 31 to the HAL init minus 1 for the DCR1 reg */ dev_data->hqspi.Init.FlashSize = find_lsb_set(dev_cfg->flash_size) - 2; +#if !DT_NODE_HAS_PROP(DT_NODELABEL(quadspi), flash_id) && defined(QUADSPI_CR_DFM) + /* + * When the DTS has NO FlashID, it means Dual Flash + * Even in DUAL flash config, the SDFP is read from one single quad-NOR + * else the magic nb is wrong (0x46465353) + * That means that the Dual Flash config is set after the SFDP sequence + */ + dev_data->hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE; + dev_data->hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_3_CYCLE; + dev_data->hqspi.Init.DualFlash = QSPI_DUALFLASH_DISABLE; + /* Set Dual Flash Mode only on MemoryMapped */ + dev_data->hqspi.Init.FlashID = QSPI_FLASH_ID_1; +#endif /* ! flash_id */ + HAL_QSPI_Init(&dev_data->hqspi); -#if DT_NODE_HAS_PROP(DT_NODELABEL(quadspi), flash_id) +#if DT_NODE_HAS_PROP(DT_NODELABEL(quadspi), flash_id) && defined(QUADSPI_CR_DFM) uint8_t qspi_flash_id = DT_PROP(DT_NODELABEL(quadspi), flash_id); HAL_QSPI_SetFlashID(&dev_data->hqspi, (qspi_flash_id - 1) << QUADSPI_CR_FSEL_Pos); -#endif +#endif /* flash_id */ + /* Initialize semaphores */ k_sem_init(&dev_data->sem, 1, 1); k_sem_init(&dev_data->sync, 0, 1); @@ -1455,8 +1473,22 @@ static int flash_stm32_qspi_init(const struct device *dev) #endif /* CONFIG_FLASH_PAGE_LAYOUT */ #ifdef CONFIG_STM32_MEMMAP - ret = qspi_set_memorymap(dev); +#if !DT_NODE_HAS_PROP(DT_NODELABEL(quadspi), flash_id) && defined(QUADSPI_CR_DFM) + /* + * When the DTS has NO FlashID, it means Dual Flash + * Force Dual Flash mode now, after the SFDP sequence which is reading + * one quad-NOR only + */ + MODIFY_REG(dev_data->hqspi.Instance->CR, (QUADSPI_CR_DFM), QSPI_DUALFLASH_ENABLE); + LOG_DBG("Dual Flash Mode"); +#endif /* !flash_id */ + + +#endif /* CONFIG_STM32_MEMMAP */ + +#ifdef CONFIG_STM32_MEMMAP + ret = qspi_set_memorymap(dev); if (ret != 0) { LOG_ERR("Error (%d): setting NOR in MemoryMapped mode", ret); return -EINVAL; @@ -1564,4 +1596,4 @@ static void flash_stm32_qspi_irq_config_func(const struct device *dev) irq_enable(DT_IRQN(STM32_QSPI_NODE)); } -#endif +#endif /* compat st_stm32_qspi_nor */ diff --git a/dts/bindings/qspi/st,stm32-qspi.yaml b/dts/bindings/qspi/st,stm32-qspi.yaml index 04aa6e4d0208..cea2f66a70eb 100644 --- a/dts/bindings/qspi/st,stm32-qspi.yaml +++ b/dts/bindings/qspi/st,stm32-qspi.yaml @@ -66,5 +66,7 @@ properties: QSPI GPIO banks (defined as 'quadspi_bk[12]' in pinctrl property) to communicate with flash memory. + When NOT set, it means Dual Flash Mode. + For example flash-id = <2>; From 3eb716be8560e7a445b63bae4e44d3ad266d4623 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Fri, 26 Jan 2024 16:44:34 +0100 Subject: [PATCH 08/15] dts: arm: stm32h7 MPU attribute for the external Memory Define the MPU attribute to be ATTR_MPU_EXTMEM for the external region (qspi- or octo-spi NOR flash) starting at 0x90000000 of the stm32h7 serie. Another region should be Included inside with attribute ATTR_MPU_IO, to access the external memory in XIP. Signed-off-by: Francois Ramu --- dts/arm/st/h7/stm32h7.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dts/arm/st/h7/stm32h7.dtsi b/dts/arm/st/h7/stm32h7.dtsi index 95c5590a8716..37136b50b453 100644 --- a/dts/arm/st/h7/stm32h7.dtsi +++ b/dts/arm/st/h7/stm32h7.dtsi @@ -47,7 +47,7 @@ ext_memory: memory@90000000 { compatible = "zephyr,memory-region"; - reg = <0x90000000 DT_SIZE_M(256)>; /* max addressable area */ + reg = <0x90000000 DT_SIZE_M(64)>; /* 512 Mbits */ zephyr,memory-region = "EXTMEM"; zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_EXTMEM) )>; }; From ce5cf8d8d26a7a8ce3a3d4bcf020d72e86680c1b Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Fri, 19 Apr 2024 15:07:41 +0200 Subject: [PATCH 09/15] dts: arm: stm32f7 MPU attribute for the external Memory efine the MPU attribute to be ATTR_MPU_EXTMEM for the external region (qspi-spi NOR flash) starting at 0x90000000 of the stm32f7 serie. Another region should be Included inside with attribute ATTR_MPU_IO, to access the external memory in XIP. Signed-off-by: Francois Ramu --- dts/arm/st/f7/stm32f7.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dts/arm/st/f7/stm32f7.dtsi b/dts/arm/st/f7/stm32f7.dtsi index 600f959b4fd8..f6535c844427 100644 --- a/dts/arm/st/f7/stm32f7.dtsi +++ b/dts/arm/st/f7/stm32f7.dtsi @@ -46,9 +46,9 @@ quadspi_memory: memory@90000000 { compatible = "zephyr,memory-region", "mmio-sram"; - reg = <0x90000000 DT_SIZE_M(256)>; + reg = <0x90000000 DT_SIZE_M(16)>; zephyr,memory-region = "QSPI"; - zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_EXTMEM) )>; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO) )>; }; clocks { From ce19c8769c0b5adc193a39a2c71c5795f294dc0c Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Mon, 5 Feb 2024 14:45:49 +0100 Subject: [PATCH 10/15] boards: arm: stm32h750 disco kit has dual Flash Enable the Dual Flash Mode on the stm32h750b_dk to access both quad flash in parallel as mounted on the hardware. Signed-off-by: Francois Ramu --- boards/st/stm32h750b_dk/stm32h750b_dk.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/st/stm32h750b_dk/stm32h750b_dk.dts b/boards/st/stm32h750b_dk/stm32h750b_dk.dts index 7cd328e90dbd..d6a19d572269 100644 --- a/boards/st/stm32h750b_dk/stm32h750b_dk.dts +++ b/boards/st/stm32h750b_dk/stm32h750b_dk.dts @@ -99,7 +99,7 @@ &quadspi_bk1_io2_pf7 &quadspi_bk1_io3_pf6 &quadspi_bk2_io0_ph2 &quadspi_bk2_io1_ph3 &quadspi_bk2_io2_pg9 &quadspi_bk2_io3_pg14>; - flash-id = <1>; + status = "okay"; mt25ql512ab1: qspi-nor-flash-1@90000000 { From 71e77df540b28758f4ab9c866fd85fb63ee79a61 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Fri, 1 Mar 2024 16:01:20 +0100 Subject: [PATCH 11/15] boards: arm: stm32h7 with external memory region for XiP Declare a sub-region of the whole ext_memory with attributes ATTR_MPU_IO so that XiP becomes possible on this external quad- octo- NOR flash Signed-off-by: Francois Ramu --- .../stm32h747i_disco_stm32h747xx_m7.dts | 8 +++++ boards/st/stm32h750b_dk/stm32h750b_dk.dts | 36 ++++++++++++++++++- boards/st/stm32h7b3i_dk/stm32h7b3i_dk.dts | 8 +++++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/boards/st/stm32h747i_disco/stm32h747i_disco_stm32h747xx_m7.dts b/boards/st/stm32h747i_disco/stm32h747i_disco_stm32h747xx_m7.dts index 8f27eb0f8365..098dafd4a6bc 100644 --- a/boards/st/stm32h747i_disco/stm32h747i_disco_stm32h747xx_m7.dts +++ b/boards/st/stm32h747i_disco/stm32h747i_disco_stm32h747xx_m7.dts @@ -31,6 +31,14 @@ zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; + quad_nor: memory@90000000 { + compatible = "zephyr,memory-region"; + reg = <0x90000000 DT_SIZE_K(800)>; /* size of the slot partition */ + zephyr,memory-region = "EXTMEM"; + /* The ATTR_MPU_EXTMEM attribut causing a MPU FAULT */ + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO) )>; + }; + leds { green_led_1:led_1 { status = "okay"; diff --git a/boards/st/stm32h750b_dk/stm32h750b_dk.dts b/boards/st/stm32h750b_dk/stm32h750b_dk.dts index d6a19d572269..3d8bf439815e 100644 --- a/boards/st/stm32h750b_dk/stm32h750b_dk.dts +++ b/boards/st/stm32h750b_dk/stm32h750b_dk.dts @@ -18,7 +18,6 @@ zephyr,shell-uart = &usart3; zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,flash-controller = &mt25ql512ab1; }; sdram2: sdram@d0000000 { @@ -29,6 +28,14 @@ zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; + quad_nor: memory@90000000 { + compatible = "zephyr,memory-region"; + reg = <0x90000000 DT_SIZE_K(800)>; /* size of the slot partition */ + zephyr,memory-region = "EXTMEM"; + /* The ATTR_MPU_EXTMEM attribut causing a MPU FAULT */ + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO) )>; + }; + leds { compatible = "gpio-leds"; red_led: led_1 { @@ -92,6 +99,33 @@ status = "okay"; }; +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(64)>; + }; + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x00010000 DT_SIZE_K(60)>; + }; + + scratch_partition: partition@1f000 { + label = "image-scratch"; + reg = <0x0001f000 DT_SIZE_K(2)>; + }; + storage_partition: partition@1f800 { + label = "storage"; + reg = <0x0001f800 DT_SIZE_K(2)>; + }; + + }; +}; + &quadspi { pinctrl-names = "default"; pinctrl-0 = <&quadspi_clk_pf10 &quadspi_bk1_ncs_pg6 diff --git a/boards/st/stm32h7b3i_dk/stm32h7b3i_dk.dts b/boards/st/stm32h7b3i_dk/stm32h7b3i_dk.dts index 1567585b2fd5..879c09d5c93f 100644 --- a/boards/st/stm32h7b3i_dk/stm32h7b3i_dk.dts +++ b/boards/st/stm32h7b3i_dk/stm32h7b3i_dk.dts @@ -59,6 +59,14 @@ zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) )>; }; + octo_nor: memory@90000000 { + compatible = "zephyr,memory-region"; + reg = <0x90000000 DT_SIZE_K(800)>; /* size of the slot partition */ + zephyr,memory-region = "EXTMEM"; + /* The ATTR_MPU_EXTMEM attribut causing a MPU FAULT */ + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO) )>; + }; + transceiver0: can-phy0 { compatible = "microchip,mcp2562fd", "can-transceiver-gpio"; standby-gpios = <&gpioh 8 GPIO_ACTIVE_HIGH>; From 84485b696a19a410cf3a7325ad658a04ee6e0e28 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Wed, 7 Feb 2024 13:32:43 +0100 Subject: [PATCH 12/15] boards: arm: stm32l496 disco kit has external Flash Define a partition to the stm32l496g_dk board Signed-off-by: Francois Ramu --- boards/st/stm32l496g_disco/stm32l496g_disco.dts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/boards/st/stm32l496g_disco/stm32l496g_disco.dts b/boards/st/stm32l496g_disco/stm32l496g_disco.dts index e2a70f6163d5..b16e74ab9910 100644 --- a/boards/st/stm32l496g_disco/stm32l496g_disco.dts +++ b/boards/st/stm32l496g_disco/stm32l496g_disco.dts @@ -208,5 +208,15 @@ zephyr_udc0: &usbotg_fs { status = "okay"; spi-bus-width = <4>; writeoc = "PP_1_4_4"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + reg = <0x00000000 DT_SIZE_M(8)>; + }; + }; }; }; From 08e37fe2e35670a493d40f13df53cf5b656e7bd8 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Fri, 19 Apr 2024 15:06:16 +0200 Subject: [PATCH 13/15] boards: arm: stm32f746g_disco kit has external Flash Consider the quad-NOR is single flash mode enabled That will avoid configuring the dual flash on this target Signed-off-by: Francois Ramu --- boards/st/stm32f746g_disco/stm32f746g_disco.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/st/stm32f746g_disco/stm32f746g_disco.dts b/boards/st/stm32f746g_disco/stm32f746g_disco.dts index 6250c4e8e80d..c48d7258eab9 100644 --- a/boards/st/stm32f746g_disco/stm32f746g_disco.dts +++ b/boards/st/stm32f746g_disco/stm32f746g_disco.dts @@ -185,6 +185,7 @@ zephyr_udc0: &usbotg_fs { &quadspi_bk1_io0_pd11 &quadspi_bk1_io1_pd12 &quadspi_bk1_io2_pe2 &quadspi_bk1_io3_pd13>; pinctrl-names = "default"; + flash-id = <1>; /* One quad NOR : single flash mode */ status = "okay"; n25q128a1: qspi-nor-flash@90000000 { From 9bfae1cd2444b6c863a9ec18e05d4ef15f376df5 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Fri, 19 Apr 2024 11:24:41 +0200 Subject: [PATCH 14/15] boards: arm: stm32h747i_disco kit has external Flash Define a partition to the stm32h747_disco board Signed-off-by: Francois Ramu --- .../stm32h747i_disco_stm32h747xx_m7.dts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/boards/st/stm32h747i_disco/stm32h747i_disco_stm32h747xx_m7.dts b/boards/st/stm32h747i_disco/stm32h747i_disco_stm32h747xx_m7.dts index 098dafd4a6bc..528a8ed04b06 100644 --- a/boards/st/stm32h747i_disco/stm32h747i_disco_stm32h747xx_m7.dts +++ b/boards/st/stm32h747i_disco/stm32h747i_disco_stm32h747xx_m7.dts @@ -20,7 +20,6 @@ zephyr,shell-uart = &usart1; zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,flash-controller = &mt25ql512ab1; }; sdram2: sdram@d0000000 { @@ -119,6 +118,19 @@ #address-cells = <1>; #size-cells = <1>; + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(64)>; + }; + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x00010000 DT_SIZE_K(60)>; + }; + + scratch_partition: partition@1f000 { + label = "image-scratch"; + reg = <0x0001f000 DT_SIZE_K(2)>; + }; /* Set 2KB of storage at the end of first 1MB flash */ storage_partition: partition@ff800 { label = "storage"; From 0f2c15f731439e9d491e5a4135d704da5f15bd11 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Tue, 6 Feb 2024 10:29:08 +0100 Subject: [PATCH 15/15] samples: code relocation in external memory of stm32 disco kit Define the configuration to run the code_relocation application on the external memory quad flash of the stm32h7 or stm32f7 or stm32l496g disco kit in XIP Signed-off-by: Francois Ramu --- .../code_relocation_nocopy/boards/stm32f746g_disco.conf | 5 +++++ .../code_relocation_nocopy/boards/stm32h747i_disco.conf | 5 +++++ .../code_relocation_nocopy/boards/stm32h750b_dk.conf | 2 ++ .../code_relocation_nocopy/boards/stm32l496g_disco.conf | 2 ++ 4 files changed, 14 insertions(+) create mode 100644 samples/application_development/code_relocation_nocopy/boards/stm32f746g_disco.conf create mode 100644 samples/application_development/code_relocation_nocopy/boards/stm32h747i_disco.conf create mode 100644 samples/application_development/code_relocation_nocopy/boards/stm32h750b_dk.conf create mode 100644 samples/application_development/code_relocation_nocopy/boards/stm32l496g_disco.conf diff --git a/samples/application_development/code_relocation_nocopy/boards/stm32f746g_disco.conf b/samples/application_development/code_relocation_nocopy/boards/stm32f746g_disco.conf new file mode 100644 index 000000000000..abbcc320bb35 --- /dev/null +++ b/samples/application_development/code_relocation_nocopy/boards/stm32f746g_disco.conf @@ -0,0 +1,5 @@ +CONFIG_FLASH=y +CONFIG_STM32_MEMMAP=y + +CONFIG_LOG=y +CONFIG_FLASH_LOG_LEVEL_DBG=y diff --git a/samples/application_development/code_relocation_nocopy/boards/stm32h747i_disco.conf b/samples/application_development/code_relocation_nocopy/boards/stm32h747i_disco.conf new file mode 100644 index 000000000000..abbcc320bb35 --- /dev/null +++ b/samples/application_development/code_relocation_nocopy/boards/stm32h747i_disco.conf @@ -0,0 +1,5 @@ +CONFIG_FLASH=y +CONFIG_STM32_MEMMAP=y + +CONFIG_LOG=y +CONFIG_FLASH_LOG_LEVEL_DBG=y diff --git a/samples/application_development/code_relocation_nocopy/boards/stm32h750b_dk.conf b/samples/application_development/code_relocation_nocopy/boards/stm32h750b_dk.conf new file mode 100644 index 000000000000..eac2504a7850 --- /dev/null +++ b/samples/application_development/code_relocation_nocopy/boards/stm32h750b_dk.conf @@ -0,0 +1,2 @@ +CONFIG_FLASH=y +CONFIG_STM32_MEMMAP=y diff --git a/samples/application_development/code_relocation_nocopy/boards/stm32l496g_disco.conf b/samples/application_development/code_relocation_nocopy/boards/stm32l496g_disco.conf new file mode 100644 index 000000000000..eac2504a7850 --- /dev/null +++ b/samples/application_development/code_relocation_nocopy/boards/stm32l496g_disco.conf @@ -0,0 +1,2 @@ +CONFIG_FLASH=y +CONFIG_STM32_MEMMAP=y