Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stm32 OSPI flash driver enables XiP on external NOR flash #68597

Merged
merged 5 commits into from
May 31, 2024

Conversation

FRASTM
Copy link
Collaborator

@FRASTM FRASTM commented Feb 6, 2024

With this PR the stm32u5 and stm32h7 target board with octo-NOR flash can configure this external flash to eXecute In Place
a sample code application stored on this external memory.
The ospi flash driver is configuring the external NOR in MemoryMapped mode at init so that code is XiP at the external NOR flash address.
This is demonstrated by the samples/application_development/code_relocation_nocopy/ running on the stm32u585 or stm32h7b3 disco kits.

For stm32h7 serie, this PR requires the #68593
and include a sub-region of the EXTMEM where code is executed in XiP where
zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO) )>;

For stm32u5 serie this PR requires the #68590

Requires the PR #68377 to flash correclty the code to the external flash with west command.

This PR is replacing the #61082

@FRASTM
Copy link
Collaborator Author

FRASTM commented Feb 6, 2024

Running the sample to relocate code on the external NOR flash of the b_u585i_iot02a disco kit (also valid with stm32h7b3i_dk) :
west build -p always -b b_u585i_iot02a samples/application_development/code_relocation_nocopy/
gives

*** Booting Zephyr OS build zephyr-v3.5.0-5280-g36d125514e1f ***
Address of main function 0x8000599
Address of function_in_ext_flash 0x70000001
Address of var_ext_sram_data 0x20000080 (10)
Address of function_in_sram 0x20000001                           
Address of var_sram_data 0x20000084 (10)                         
Hello World! b_u585i_iot02a         

@GeorgeCGV
Copy link
Collaborator

GeorgeCGV commented Mar 1, 2024

@FRASTM started to experience application freezing when it was started by the bootloader (BL).

The H7 application freezes in the SCB_DisableDCache when CONFIG_NO_OPTIMIZATIONS=y. That happens within z_arm_reset in z_arm_init_arch_hw_at_boot when it tries to reset the D-CACHE due to it being enabled in BL.

A solution is to set CONFIG_CACHE_MANAGEMENT=n in the app, but leave it on in the bootloader or vice versa.

Everything worked fine before the introduction of CONFIG_CACHE_MANAGEMENT.

Did you experience something like that on H7 while working on the XIP support?

Note: what is interesting is that it works with CONFIG_NO_OPTIMIZATIONS=n

@FRASTM
Copy link
Collaborator Author

FRASTM commented Mar 1, 2024

@FRASTM started to experience application freezing when it was started by the bootloader (BL).

The H7 application freezes in the SCB_DisableDCache when CONFIG_NO_OPTIMIZATIONS=y. That happens within z_arm_reset in z_arm_init_arch_hw_at_boot when it tries to reset the D-CACHE due to it being enabled in BL.

A solution is to set CONFIG_CACHE_MANAGEMENT=n in the app, but leave it on in the bootloader or vice versa.

Everything worked fine before the introduction of CONFIG_CACHE_MANAGEMENT.

Did you experience something like that on H7 while working on the XIP support?

Note: what is interesting is that it works with CONFIG_NO_OPTIMIZATIONS=n

Yes, I had some pb with the stm32h7 cache, on my side, for that, I changed the memory-attribute of the ext memory section

diff --git a/dts/arm/st/h7/stm32h7.dtsi b/dts/arm/st/h7/stm32h7.dtsi
index 64ccfbf724..2351eb0e49 100644
--- a/dts/arm/st/h7/stm32h7.dtsi
+++ b/dts/arm/st/h7/stm32h7.dtsi
@@ -45,11 +45,12 @@
 		};
 	};
 
-	quadspi_memory: memory@90000000 {
-		compatible = "zephyr,memory-region", "mmio-sram";
-		reg = <0x90000000 DT_SIZE_M(256)>;
-		zephyr,memory-region = "QSPI";
-		zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_EXTMEM) )>;
+	ext_memory: memory@90000000 {
+		compatible = "zephyr,memory-region";
+		reg = <0x90000000 DT_SIZE_M(64)>; /* 512 Mbits */
+		zephyr,memory-region = "EXTMEM";
+		/* The ATTR_MPU_EXTMEM attribut causing a MPU FAULT */
+		zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO) )>;
 	};
 
 	clocks {

@GeorgeCGV
Copy link
Collaborator

GeorgeCGV commented Mar 1, 2024

@FRASTM started to experience application freezing when it was started by the bootloader (BL).
The H7 application freezes in the SCB_DisableDCache when CONFIG_NO_OPTIMIZATIONS=y. That happens within z_arm_reset in z_arm_init_arch_hw_at_boot when it tries to reset the D-CACHE due to it being enabled in BL.
A solution is to set CONFIG_CACHE_MANAGEMENT=n in the app, but leave it on in the bootloader or vice versa.
Everything worked fine before the introduction of CONFIG_CACHE_MANAGEMENT.
Did you experience something like that on H7 while working on the XIP support?
Note: what is interesting is that it works with CONFIG_NO_OPTIMIZATIONS=n

Yes, I had some pb with the stm32h7 cache, on my side, for that, I changed the memory-attribute of the ext memory section

diff --git a/dts/arm/st/h7/stm32h7.dtsi b/dts/arm/st/h7/stm32h7.dtsi
index 64ccfbf724..2351eb0e49 100644
--- a/dts/arm/st/h7/stm32h7.dtsi
+++ b/dts/arm/st/h7/stm32h7.dtsi
@@ -45,11 +45,12 @@
 		};
 	};
 
-	quadspi_memory: memory@90000000 {
-		compatible = "zephyr,memory-region", "mmio-sram";
-		reg = <0x90000000 DT_SIZE_M(256)>;
-		zephyr,memory-region = "QSPI";
-		zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_EXTMEM) )>;
+	ext_memory: memory@90000000 {
+		compatible = "zephyr,memory-region";
+		reg = <0x90000000 DT_SIZE_M(64)>; /* 512 Mbits */
+		zephyr,memory-region = "EXTMEM";
+		/* The ATTR_MPU_EXTMEM attribut causing a MPU FAULT */
+		zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO) )>;
 	};
 
 	clocks {

The issue in my case is not related to MPU. It can easily be observed with any region attribute.

When

  • bootloader is built it enables the D-Cache and I-Cache as long as CONFIG_CACHE_MANAGEMENT=y.
  • application is built with CONFIG_CACHE_MANAGEMENT=y in addition to
CONFIG_DEBUG=y
CONFIG_NO_OPTIMIZATIONS=y

Eventually, when Bl jumps to the application and Zephyr calls z_arm_init_arch_hw_at_boot it detects that the D-Cache is enabled and tries to disable it. The disabling SCB_DisableDCache loops forever. I am not sure why it is only observable when CONFIG_NO_OPTIMIZATIONS=y (toolchain specific issue? Tested with zephyr-sdk-0.16.5/arm-zephyr-eabi and gnu arm-none-eabi)

@benediktibk shouldn't

#if defined(CONFIG_ARCH_CACHE)
#if defined(CONFIG_DCACHE)
/* Reset D-Cache settings. If the D-Cache was enabled,
* SCB_DisableDCache() takes care of cleaning and invalidating it.
* If it was already disabled, just call SCB_InvalidateDCache() to
* reset it to a known clean state.
*/
if (SCB->CCR & SCB_CCR_DC_Msk) {
/*
* Do not use sys_cache_data_disable at this point, but instead
* the architecture specific function. This ensures that the
* cache is disabled although CONFIG_CACHE_MANAGEMENT might be
* disabled.
*/
SCB_DisableDCache();
} else {
SCB_InvalidateDCache();
}
#endif /* CONFIG_DCACHE */
#if defined(CONFIG_ICACHE)
/*
* Reset I-Cache settings.
* Do not use sys_cache_data_disable at this point, but instead
* the architecture specific function. This ensures that the
* cache is disabled although CONFIG_CACHE_MANAGEMENT might be
* disabled.
*/
SCB_DisableICache();
#endif /* CONFIG_ICACHE */
#endif /* CONFIG_ARCH_CACHE */

be skipped if we are "chain loading"/booting Zephyr from a bootloader that enables d/i-caches?

Just found ARM-software/CMSIS_5#620 and that is exactly what seems to happen.

@benediktibk
Copy link
Collaborator

@benediktibk shouldn't

#if defined(CONFIG_ARCH_CACHE)
#if defined(CONFIG_DCACHE)
/* Reset D-Cache settings. If the D-Cache was enabled,
* SCB_DisableDCache() takes care of cleaning and invalidating it.
* If it was already disabled, just call SCB_InvalidateDCache() to
* reset it to a known clean state.
*/
if (SCB->CCR & SCB_CCR_DC_Msk) {
/*
* Do not use sys_cache_data_disable at this point, but instead
* the architecture specific function. This ensures that the
* cache is disabled although CONFIG_CACHE_MANAGEMENT might be
* disabled.
*/
SCB_DisableDCache();
} else {
SCB_InvalidateDCache();
}
#endif /* CONFIG_DCACHE */
#if defined(CONFIG_ICACHE)
/*
* Reset I-Cache settings.
* Do not use sys_cache_data_disable at this point, but instead
* the architecture specific function. This ensures that the
* cache is disabled although CONFIG_CACHE_MANAGEMENT might be
* disabled.
*/
SCB_DisableICache();
#endif /* CONFIG_ICACHE */
#endif /* CONFIG_ARCH_CACHE */

I don't think so, because the whole idea behind z_arm_init_arch_hw_at_boot is to get the system after after a bootloader into the same state as it is after a full reset. Starting from this then the caches are activated if they are enabled in the config of the actual application.

The big question for me is why SCB_DisableDCache seems to get stuck, because it should be safe to call it at this point? From the documentation it is not completely clear if it is required to call SCB_CleanDCache beforehand, but it might be worth a try?

@GeorgeCGV
Copy link
Collaborator

GeorgeCGV commented Mar 5, 2024

@benediktibk the issues seems to come from ARM-software/CMSIS_5#620. Created #69789.

@FRASTM
Copy link
Collaborator Author

FRASTM commented May 13, 2024

rebase on db1a4a6
This version is the stm32 ospi flash driver configuration (like the ##72339) to run the samples/application_development/code_relocation_nocopy/ on b_u585i_iot02a and stm32h7b3i_dk disco boards

For flashing (west flash) the stm32h7b3i_dk disco kit, the #68377 is required, with boards/st/stm32h7b3i_dk/board.cmake configured to flash the external memory, with the external loader of the STM32CubeProgrammer, as runner.

*** Booting Zephyr OS build v3.6.0-3798-gce5ed69f86bd ***
Address of main function 0x8000685
Address of function_in_ext_flash 0x90000001
Address of var_ext_sram_data 0x240000e0 (10)
Address of function_in_sram 0x24000001
Address of var_sram_data 0x240000e4 (10)
Hello World! stm32h7b3i_dk

Write and Erase operations are aborting the memorymap mode before executing in command mode. This is demonstrated with the samples/drivers/spi_flash executed on the b_u5885i_iot02a board when CONFIG_STM32_MEMMAP=y

@FRASTM FRASTM marked this pull request as ready for review May 13, 2024 11:48
@FRASTM FRASTM requested review from erwango and ABOSTM as code owners May 13, 2024 11:48
@FRASTM
Copy link
Collaborator Author

FRASTM commented May 28, 2024

@FRASTM You should rebase on top of d490616 instead of adding the commits of #68377 on top of this PR's branch.

done

@FRASTM
Copy link
Collaborator Author

FRASTM commented May 29, 2024

  • Rebase on c140053
  • Add a commit to remove the stm32h5 serie (which now is using the flash_stm32_xspi_ driver) from the flash_stm32_ospi driver code
  • samples/application_development/code_relocation_nocopy/ can executes code (XiP) from the external flash. STM32CubeProgrammer with external loader is used to flash to the disco board

ajarmouni-st
ajarmouni-st previously approved these changes May 29, 2024
@erwango erwango requested review from erwango and gautierg-st May 29, 2024 11:47
Copy link
Member

@erwango erwango left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise LGTM

drivers/flash/flash_stm32_ospi.c Outdated Show resolved Hide resolved
erwango
erwango previously approved these changes May 30, 2024
ajarmouni-st
ajarmouni-st previously approved these changes May 30, 2024
FRASTM added 4 commits May 30, 2024 18:23
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 <[email protected]>
Declare a sub-region of the whole ext_memory with attributes
ATTR_MPU_IO so that XiP becomes possible on this external
octo- NOR flash. Use the STM32CubeProgrammer runner
with the external loader for flashing.

Signed-off-by: Francois Ramu <[email protected]>
Declare a sub-region of the whole ext_memory with attributes
ATTR_MPU_IO so that XiP becomes possible on this external
octo- NOR flash.  Use the STM32CubeProgrammer runner
with the external loader for flashing.

Signed-off-by: Francois Ramu <[email protected]>
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 <[email protected]>
@FRASTM FRASTM dismissed stale reviews from ajarmouni-st and erwango via b6eb548 May 30, 2024 16:25
@FRASTM
Copy link
Collaborator Author

FRASTM commented May 30, 2024

fixing CI error

@erwango
Copy link
Member

erwango commented May 31, 2024

@de-nordic Ready for you review

@dleach02 dleach02 merged commit 4101948 into zephyrproject-rtos:main May 31, 2024
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.