diff --git a/components/esp32/CMakeLists.txt b/components/esp32/CMakeLists.txt index 7798db0cc7..ecc765ba78 100644 --- a/components/esp32/CMakeLists.txt +++ b/components/esp32/CMakeLists.txt @@ -96,5 +96,19 @@ else() target_compile_options(${COMPONENT_LIB} PUBLIC -mfix-esp32-psram-cache-issue) # also, make sure we link with this option so correct toolchain libs are pulled in target_link_libraries(${COMPONENT_LIB} PUBLIC -mfix-esp32-psram-cache-issue) + # set strategy selected + # note that we don't need to set link options as the library linked is independent of this + if(CONFIG_SPIRAM_CACHE_WORKAROUND_STRATEGY_DUPLDST) + target_compile_options(${COMPONENT_LIB} PUBLIC -mfix-esp32-psram-cache-strategy=dupldst) + target_link_libraries(${COMPONENT_LIB} PUBLIC -mfix-esp32-psram-cache-strategy=dupldst) + endif() + if(CONFIG_SPIRAM_CACHE_WORKAROUND_STRATEGY_MEMW) + target_compile_options(${COMPONENT_LIB} PUBLIC -mfix-esp32-psram-cache-strategy=memw) + target_link_libraries(${COMPONENT_LIB} PUBLIC -mfix-esp32-psram-cache-strategy=memw) + endif() + if(CONFIG_SPIRAM_CACHE_WORKAROUND_STRATEGY_NOPS) + target_compile_options(${COMPONENT_LIB} PUBLIC -mfix-esp32-psram-cache-strategy=nops) + target_link_libraries(${COMPONENT_LIB} PUBLIC -mfix-esp32-psram-cache-strategy=nops) + endif() endif() endif() diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index eb898326d3..509fa3db7e 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -129,6 +129,40 @@ menu "ESP32-specific" The workaround is not required for ESP32 revision 3 and above. + menu "SPIRAM cache workaround debugging" + + choice SPIRAM_CACHE_WORKAROUND_STRATEGY + prompt "Workaround strategy" + depends on SPIRAM_CACHE_WORKAROUND + default SPIRAM_CACHE_WORKAROUND_STRATEGY_MEMW + help + Select the workaround strategy. Note that the strategy for precompiled + libraries (libgcc, newlib, bt, wifi) is not affected by this selection. + + Unless you know you need a different strategy, it's suggested you stay + with the default MEMW strategy. Note that DUPLDST can interfere with hardware + encryption and this will be automatically disabled if this workaround is selected. + 'Insert nops' is the workaround that was used in older esp-idf versions. This workaround + still can cause faulty data transfers from/to SPI RAM in some situation. + + config SPIRAM_CACHE_WORKAROUND_STRATEGY_MEMW + bool "Insert memw after vulnerable instructions (default)" + + config SPIRAM_CACHE_WORKAROUND_STRATEGY_DUPLDST + bool "Duplicate LD/ST for 32-bit, memw for 8/16 bit" + + config SPIRAM_CACHE_WORKAROUND_STRATEGY_NOPS + bool "Insert nops between vulnerable loads/stores (old strategy, obsolete)" + endchoice + + #This needs to be Y only for the dupldst workaround + config SPIRAM_WORKAROUND_NEED_VOLATILE_SPINLOCK + bool + default "y" if SPIRAM_CACHE_WORKAROUND_STRATEGY_DUPLDST + + + endmenu + config SPIRAM_BANKSWITCH_ENABLE bool "Enable bank switching for >4MiB external RAM" default y diff --git a/components/esp32/Makefile.projbuild b/components/esp32/Makefile.projbuild index d13dbe2d0b..476cead53e 100644 --- a/components/esp32/Makefile.projbuild +++ b/components/esp32/Makefile.projbuild @@ -1,9 +1,24 @@ # Enable psram cache bug workaround in compiler if selected + ifdef CONFIG_SPIRAM_CACHE_WORKAROUND -CFLAGS+=-mfix-esp32-psram-cache-issue -CXXFLAGS+=-mfix-esp32-psram-cache-issue -LDFLAGS+=-mfix-esp32-psram-cache-issue +SPIRAM_CACHE_WORKAROUND_FLAGS = -mfix-esp32-psram-cache-issue + +ifdef CONFIG_SPIRAM_CACHE_WORKAROUND_STRATEGY_DUPLDST +SPIRAM_CACHE_WORKAROUND_FLAGS += -mfix-esp32-psram-cache-strategy=dupldst endif +ifdef CONFIG_SPIRAM_CACHE_WORKAROUND_STRATEGY_MEMW +SPIRAM_CACHE_WORKAROUND_FLAGS += -mfix-esp32-psram-cache-strategy=memw +endif +ifdef CONFIG_SPIRAM_CACHE_WORKAROUND_STRATEGY_NOPS +SPIRAM_CACHE_WORKAROUND_FLAGS += -mfix-esp32-psram-cache-strategy=nops +endif + +CFLAGS+=$(SPIRAM_CACHE_WORKAROUND_FLAGS) +CXXFLAGS+=$(SPIRAM_CACHE_WORKAROUND_FLAGS) +LDFLAGS+=$(SPIRAM_CACHE_WORKAROUND_FLAGS) +endif + + # Enable dynamic esp_timer overflow value if building unit tests ifneq ("$(filter esp32,$(TEST_COMPONENTS_LIST))","") diff --git a/components/esp32/project_include.cmake b/components/esp32/project_include.cmake index aa0ac286fa..e53f240380 100644 --- a/components/esp32/project_include.cmake +++ b/components/esp32/project_include.cmake @@ -4,6 +4,16 @@ if(CONFIG_SPIRAM_CACHE_WORKAROUND) # non-IDF CMakeLists.txt file is imported into a component) don't depend # on the esp32 component so don't get the extra flag. This handles that case. idf_build_set_property(COMPILE_OPTIONS "-mfix-esp32-psram-cache-issue" APPEND) + # note that we don't need to set link options as the library linked is independent of this + if(CONFIG_SPIRAM_CACHE_WORKAROUND_STRATEGY_DUPLDST) + idf_build_set_property(COMPILE_OPTIONS "-mfix-esp32-psram-cache-strategy=dupldst" APPEND) + endif() + if(CONFIG_SPIRAM_CACHE_WORKAROUND_STRATEGY_MEMW) + idf_build_set_property(COMPILE_OPTIONS "-mfix-esp32-psram-cache-strategy=memw" APPEND) + endif() + if(CONFIG_SPIRAM_CACHE_WORKAROUND_STRATEGY_NOPS) + idf_build_set_property(COMPILE_OPTIONS "-mfix-esp32-psram-cache-strategy=nops" APPEND) + endif() endif() # Check toolchain is configured properly in cmake diff --git a/components/idf_test/include/idf_performance.h b/components/idf_test/include/idf_performance.h index b464862d64..9de9d9ceb4 100644 --- a/components/idf_test/include/idf_performance.h +++ b/components/idf_test/include/idf_performance.h @@ -72,10 +72,10 @@ #endif #ifndef IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_MBSEC_TOHOST_4BIT -#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_MBSEC_TOHOST_4BIT 12500 +#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_MBSEC_TOHOST_4BIT 12200 #endif #ifndef IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_MBSEC_FRHOST_4BIT -#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_MBSEC_FRHOST_4BIT 12500 +#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_MBSEC_FRHOST_4BIT 12200 #endif #ifndef IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_MBSEC_TOHOST_1BIT #define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_MBSEC_TOHOST_1BIT 4000 diff --git a/components/mbedtls/Kconfig b/components/mbedtls/Kconfig index 5d222f408b..737f8cdb2e 100644 --- a/components/mbedtls/Kconfig +++ b/components/mbedtls/Kconfig @@ -189,6 +189,7 @@ menu "mbedTLS" config MBEDTLS_HARDWARE_AES bool "Enable hardware AES acceleration" default y + depends on !SPIRAM_CACHE_WORKAROUND_STRATEGY_DUPLDST help Enable hardware accelerated AES encryption & decryption. @@ -220,6 +221,7 @@ menu "mbedTLS" config MBEDTLS_HARDWARE_MPI bool "Enable hardware MPI (bignum) acceleration" default y + depends on !SPIRAM_CACHE_WORKAROUND_STRATEGY_DUPLDST help Enable hardware accelerated multiple precision integer operations. @@ -231,6 +233,7 @@ menu "mbedTLS" config MBEDTLS_HARDWARE_SHA bool "Enable hardware SHA acceleration" default y + depends on !SPIRAM_CACHE_WORKAROUND_STRATEGY_DUPLDST help Enable hardware accelerated SHA1, SHA256, SHA384 & SHA512 in mbedTLS. diff --git a/components/soc/include/soc/spinlock.h b/components/soc/include/soc/spinlock.h index a19b41e25e..fd6ec4e339 100644 --- a/components/soc/include/soc/spinlock.h +++ b/components/soc/include/soc/spinlock.h @@ -22,6 +22,12 @@ #include "xtensa/xtruntime.h" +#ifdef CONFIG_SPIRAM_WORKAROUND_NEED_VOLATILE_SPINLOCK +#define NEED_VOLATILE_MUX volatile +#else +#define NEED_VOLATILE_MUX +#endif + #define SPINLOCK_FREE 0xB33FFFFF #define SPINLOCK_WAIT_FOREVER (-1) #define SPINLOCK_NO_WAIT 0 @@ -29,8 +35,8 @@ #define CORE_ID_REGVAL_XOR_SWAP (0xCDCD ^ 0xABAB) typedef struct { - uint32_t owner; - uint32_t count; + NEED_VOLATILE_MUX uint32_t owner; + NEED_VOLATILE_MUX uint32_t count; }spinlock_t; /** diff --git a/tools/ci/test_build_system_cmake.sh b/tools/ci/test_build_system_cmake.sh index e39521ada1..e4a277bd2b 100755 --- a/tools/ci/test_build_system_cmake.sh +++ b/tools/ci/test_build_system_cmake.sh @@ -459,6 +459,21 @@ function run_tests() grep -q '"command"' build/compile_commands.json || failure "compile_commands.json missing or has no no 'commands' in it" (grep '"command"' build/compile_commands.json | grep -v mfix-esp32-psram-cache-issue) && failure "All commands in compile_commands.json should use PSRAM cache workaround" rm -r build + #Test for various strategies + for strat in MEMW NOPS DUPLDST; do + rm -r build sdkconfig.defaults sdkconfig sdkconfig.defaults.esp32 + stratlc=`echo $strat | tr A-Z a-z` + mkdir build && touch build/sdkconfig + echo "CONFIG_ESP32_SPIRAM_SUPPORT=y" > sdkconfig.defaults + echo "CONFIG_SPIRAM_CACHE_WORKAROUND_STRATEGY_$strat=y" >> sdkconfig.defaults + echo "CONFIG_SPIRAM_CACHE_WORKAROUND=y" >> sdkconfig.defaults + # note: we do 'reconfigure' here, as we just need to run cmake + idf.py reconfigure + grep -q '"command"' build/compile_commands.json || failure "compile_commands.json missing or has no no 'commands' in it" + (grep '"command"' build/compile_commands.json | grep -v mfix-esp32-psram-cache-strategy=$stratlc) && failure "All commands in compile_commands.json should use PSRAM cache workaround strategy $strat when selected" + echo ${PWD} + rm -r sdkconfig.defaults build + done print_status "Displays partition table when executing target partition_table" idf.py partition_table | grep -E "# ESP-IDF .+ Partition Table" diff --git a/tools/unit-test-app/configs/psram b/tools/unit-test-app/configs/psram index 6dd17ebed8..21b3fd090b 100644 --- a/tools/unit-test-app/configs/psram +++ b/tools/unit-test-app/configs/psram @@ -1,4 +1,4 @@ -TEST_EXCLUDE_COMPONENTS=libsodium bt app_update driver esp32 esp_timer freertos mbedtls spi_flash test_utils +TEST_EXCLUDE_COMPONENTS=libsodium bt app_update driver esp32 esp_timer mbedtls spi_flash test_utils heap pthread soc CONFIG_ESP32_SPIRAM_SUPPORT=y CONFIG_ESP_INT_WDT_TIMEOUT_MS=800 CONFIG_SPIRAM_OCCUPY_NO_HOST=y diff --git a/tools/unit-test-app/configs/psram_2 b/tools/unit-test-app/configs/psram_2 index 450f8c8d15..379dc923be 100644 --- a/tools/unit-test-app/configs/psram_2 +++ b/tools/unit-test-app/configs/psram_2 @@ -1,4 +1,4 @@ -TEST_COMPONENTS=esp32 esp_timer freertos mbedtls spi_flash +TEST_COMPONENTS=esp32 esp_timer mbedtls spi_flash heap pthread soc CONFIG_ESP32_SPIRAM_SUPPORT=y CONFIG_ESP_INT_WDT_TIMEOUT_MS=800 CONFIG_SPIRAM_OCCUPY_NO_HOST=y