From 85f79ecb075fc81e4eb18801a4bfd5d276d514bf Mon Sep 17 00:00:00 2001 From: wanglei Date: Wed, 20 May 2026 17:44:15 +0800 Subject: [PATCH 1/2] fix(esp_rom): implement cache writeback related apis in iram avoid critical issues caused by manual cache writeback and conflicting writes. The issue exist on chips after esp32p4 --- components/esp_rom/CMakeLists.txt | 8 ++ .../esp_rom/esp32c5/Kconfig.soc_caps.in | 4 + components/esp_rom/esp32c5/esp_rom_caps.h | 1 + components/esp_rom/esp32c5/ld/esp32c5.rom.ld | 10 +- .../esp_rom/esp32c61/Kconfig.soc_caps.in | 4 + components/esp_rom/esp32c61/esp_rom_caps.h | 1 + .../esp32c61/include/esp32c61/rom/cache.h | 2 + .../esp_rom/esp32c61/ld/esp32c61.rom.ld | 10 +- .../esp_rom/esp32h4/Kconfig.soc_caps.in | 4 + components/esp_rom/esp32h4/esp_rom_caps.h | 1 + components/esp_rom/esp32h4/ld/esp32h4.rom.ld | 10 +- .../esp_rom/esp32p4/Kconfig.soc_caps.in | 4 + components/esp_rom/esp32p4/esp_rom_caps.h | 1 + .../esp32p4/include/esp32p4/rom/cache.h | 1 + .../esp_rom/esp32p4/ld/esp32p4.rom.eco5.ld | 10 +- components/esp_rom/esp32p4/ld/esp32p4.rom.ld | 10 +- components/esp_rom/linker.lf | 4 + ...cache_writeback_esp32c5_esp32c61_esp32h4.c | 78 ++++++++++ .../patches/esp_rom_cache_writeback_esp32p4.c | 135 ++++++++++++++++++ 19 files changed, 273 insertions(+), 25 deletions(-) create mode 100644 components/esp_rom/patches/esp_rom_cache_writeback_esp32c5_esp32c61_esp32h4.c create mode 100644 components/esp_rom/patches/esp_rom_cache_writeback_esp32p4.c diff --git a/components/esp_rom/CMakeLists.txt b/components/esp_rom/CMakeLists.txt index ccf89f1df41..6cf7e3c2475 100644 --- a/components/esp_rom/CMakeLists.txt +++ b/components/esp_rom/CMakeLists.txt @@ -79,6 +79,14 @@ if(CONFIG_SECURE_ENABLE_TEE AND CONFIG_IDF_TARGET_ESP32C5 AND NOT ESP_TEE_BUILD) list(APPEND sources "patches/esp_rom_cache_esp32c5.c") endif() +if(CONFIG_ESP_ROM_CACHE_WRITEBACK_NEEDS_SYNC_TWICE_MAP) + list(APPEND sources "patches/esp_rom_cache_writeback_esp32p4.c") +endif() + +if(CONFIG_ESP_ROM_CACHE_WRITEBACK_NEEDS_SYNC_TWICE_NO_MAP) + list(APPEND sources "patches/esp_rom_cache_writeback_esp32c5_esp32c61_esp32h4.c") +endif() + idf_component_register(SRCS ${sources} INCLUDE_DIRS ${include_dirs} PRIV_REQUIRES ${private_required_comp} diff --git a/components/esp_rom/esp32c5/Kconfig.soc_caps.in b/components/esp_rom/esp32c5/Kconfig.soc_caps.in index f475909a2a7..b1bfef8e632 100644 --- a/components/esp_rom/esp32c5/Kconfig.soc_caps.in +++ b/components/esp_rom/esp32c5/Kconfig.soc_caps.in @@ -126,3 +126,7 @@ config ESP_ROM_DELAY_US_PATCH config ESP_ROM_SUPPORT_SECURE_BOOT_FAST_WAKEUP bool default y + +config ESP_ROM_CACHE_WRITEBACK_NEEDS_SYNC_TWICE_NO_MAP + bool + default y diff --git a/components/esp_rom/esp32c5/esp_rom_caps.h b/components/esp_rom/esp32c5/esp_rom_caps.h index 1812656eb29..ca7e093340f 100644 --- a/components/esp_rom/esp32c5/esp_rom_caps.h +++ b/components/esp_rom/esp32c5/esp_rom_caps.h @@ -37,3 +37,4 @@ #define ESP_ROM_HAS_SUBOPTIMAL_NEWLIB_ON_MISALIGNED_MEMORY (1) // ROM mem/str functions are not optimized well for misaligned memory access. #define ESP_ROM_DELAY_US_PATCH (1) // ROM ets_delay_us needs patch for U-mode operation #define ESP_ROM_SUPPORT_SECURE_BOOT_FAST_WAKEUP (1) // ROM supports the secure boot fast wakeup feature +#define ESP_ROM_CACHE_WRITEBACK_NEEDS_SYNC_TWICE_NO_MAP (1) // ROM cache writeback related needs patch to avoid sync loss, no map parameter diff --git a/components/esp_rom/esp32c5/ld/esp32c5.rom.ld b/components/esp_rom/esp32c5/ld/esp32c5.rom.ld index a4bb7e2ddf9..be4954a8a1b 100644 --- a/components/esp_rom/esp32c5/ld/esp32c5.rom.ld +++ b/components/esp_rom/esp32c5/ld/esp32c5.rom.ld @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -192,12 +192,12 @@ Cache_Sync_Items = 0x40000648; Cache_Op_Addr = 0x4000064c; Cache_Invalidate_Addr = 0x40000650; Cache_Clean_Addr = 0x40000654; -Cache_WriteBack_Addr = 0x40000658; -Cache_WriteBack_Invalidate_Addr = 0x4000065c; +PROVIDE( Cache_WriteBack_Addr = 0x40000658 ); +PROVIDE( Cache_WriteBack_Invalidate_Addr = 0x4000065c ); Cache_Invalidate_All = 0x40000660; Cache_Clean_All = 0x40000664; -Cache_WriteBack_All = 0x40000668; -Cache_WriteBack_Invalidate_All = 0x4000066c; +PROVIDE( Cache_WriteBack_All = 0x40000668 ); +PROVIDE( Cache_WriteBack_Invalidate_All = 0x4000066c ); Cache_Mask_All = 0x40000670; Cache_UnMask_Dram0 = 0x40000674; Cache_Suspend_Autoload = 0x40000678; diff --git a/components/esp_rom/esp32c61/Kconfig.soc_caps.in b/components/esp_rom/esp32c61/Kconfig.soc_caps.in index 348875b787c..781350c662f 100644 --- a/components/esp_rom/esp32c61/Kconfig.soc_caps.in +++ b/components/esp_rom/esp32c61/Kconfig.soc_caps.in @@ -118,3 +118,7 @@ config ESP_ROM_HAS_SUBOPTIMAL_NEWLIB_ON_MISALIGNED_MEMORY config ESP_ROM_DELAY_US_PATCH bool default y + +config ESP_ROM_CACHE_WRITEBACK_NEEDS_SYNC_TWICE_NO_MAP + bool + default y diff --git a/components/esp_rom/esp32c61/esp_rom_caps.h b/components/esp_rom/esp32c61/esp_rom_caps.h index f0870cbaab5..3e87dd3aaa9 100644 --- a/components/esp_rom/esp32c61/esp_rom_caps.h +++ b/components/esp_rom/esp32c61/esp_rom_caps.h @@ -35,3 +35,4 @@ #define ESP_ROM_HAS_OUTPUT_PUTC_FUNC (1) // ROM has esp_rom_output_putc (or ets_write_char_uart) #define ESP_ROM_HAS_SUBOPTIMAL_NEWLIB_ON_MISALIGNED_MEMORY (1) // ROM mem/str functions are not optimized well for misaligned memory access. #define ESP_ROM_DELAY_US_PATCH (1) // ROM ets_delay_us needs patch for U-mode operation +#define ESP_ROM_CACHE_WRITEBACK_NEEDS_SYNC_TWICE_NO_MAP (1) // ROM cache writeback related needs patch to avoid sync loss, no map parameter diff --git a/components/esp_rom/esp32c61/include/esp32c61/rom/cache.h b/components/esp_rom/esp32c61/include/esp32c61/rom/cache.h index 1e0f1baa0e9..2ba42350934 100644 --- a/components/esp_rom/esp32c61/include/esp32c61/rom/cache.h +++ b/components/esp_rom/esp32c61/include/esp32c61/rom/cache.h @@ -49,6 +49,8 @@ typedef enum { CACHE_SYNC_WRITEBACK_INVALIDATE = BIT(3), } cache_sync_t; +#define CACHE_MAP_FLASH_CACHE BIT(4) + typedef enum { CACHE_SIZE_HALF = 0, /*!< 8KB for icache and dcache */ CACHE_SIZE_FULL = 1, /*!< 16KB for icache and dcache */ diff --git a/components/esp_rom/esp32c61/ld/esp32c61.rom.ld b/components/esp_rom/esp32c61/ld/esp32c61.rom.ld index d68ff6d40b8..54eb55fc3d1 100644 --- a/components/esp_rom/esp32c61/ld/esp32c61.rom.ld +++ b/components/esp_rom/esp32c61/ld/esp32c61.rom.ld @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -188,12 +188,12 @@ Cache_Sync_Items = 0x4000062c; Cache_Op_Addr = 0x40000630; Cache_Invalidate_Addr = 0x40000634; Cache_Clean_Addr = 0x40000638; -Cache_WriteBack_Addr = 0x4000063c; -Cache_WriteBack_Invalidate_Addr = 0x40000640; +PROVIDE( Cache_WriteBack_Addr = 0x4000063c ); +PROVIDE( Cache_WriteBack_Invalidate_Addr = 0x40000640 ); Cache_Invalidate_All = 0x40000644; Cache_Clean_All = 0x40000648; -Cache_WriteBack_All = 0x4000064c; -Cache_WriteBack_Invalidate_All = 0x40000650; +PROVIDE( Cache_WriteBack_All = 0x4000064c ); +PROVIDE( Cache_WriteBack_Invalidate_All = 0x40000650 ); Cache_Mask_All = 0x40000654; Cache_UnMask_Dram0 = 0x40000658; Cache_Suspend_Autoload = 0x4000065c; diff --git a/components/esp_rom/esp32h4/Kconfig.soc_caps.in b/components/esp_rom/esp32h4/Kconfig.soc_caps.in index 168f73e1b7a..2646938ef40 100644 --- a/components/esp_rom/esp32h4/Kconfig.soc_caps.in +++ b/components/esp_rom/esp32h4/Kconfig.soc_caps.in @@ -78,3 +78,7 @@ config ESP_ROM_WDT_INIT_PATCH config ESP_ROM_RAM_APP_NEEDS_MMU_INIT bool default y + +config ESP_ROM_CACHE_WRITEBACK_NEEDS_SYNC_TWICE_NO_MAP + bool + default y diff --git a/components/esp_rom/esp32h4/esp_rom_caps.h b/components/esp_rom/esp32h4/esp_rom_caps.h index fc1e51202ad..f3414632742 100644 --- a/components/esp_rom/esp32h4/esp_rom_caps.h +++ b/components/esp_rom/esp32h4/esp_rom_caps.h @@ -25,3 +25,4 @@ #define ESP_ROM_USB_OTG_NUM (-1) // No USB_OTG CDC in the ROM, set -1 for Kconfig usage. #define ESP_ROM_WDT_INIT_PATCH (1) // ROM version does not configure the clock #define ESP_ROM_RAM_APP_NEEDS_MMU_INIT (1) // ROM doesn't init cache MMU when it's a RAM APP, needs MMU hal to init +#define ESP_ROM_CACHE_WRITEBACK_NEEDS_SYNC_TWICE_NO_MAP (1) // ROM cache writeback related needs patch to avoid sync loss, no map parameter diff --git a/components/esp_rom/esp32h4/ld/esp32h4.rom.ld b/components/esp_rom/esp32h4/ld/esp32h4.rom.ld index 227ed25f67d..62b604d0af6 100644 --- a/components/esp_rom/esp32h4/ld/esp32h4.rom.ld +++ b/components/esp_rom/esp32h4/ld/esp32h4.rom.ld @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -182,12 +182,12 @@ Cache_Sync_Items = 0x400005e8; Cache_Op_Addr = 0x400005ec; Cache_Invalidate_Addr = 0x400005f0; Cache_Clean_Addr = 0x400005f4; -Cache_WriteBack_Addr = 0x400005f8; -Cache_WriteBack_Invalidate_Addr = 0x400005fc; +PROVIDE( Cache_WriteBack_Addr = 0x400005f8 ); +PROVIDE( Cache_WriteBack_Invalidate_Addr = 0x400005fc ); Cache_Invalidate_All = 0x40000600; Cache_Clean_All = 0x40000604; -Cache_WriteBack_All = 0x40000608; -Cache_WriteBack_Invalidate_All = 0x4000060c; +PROVIDE( Cache_WriteBack_All = 0x40000608 ); +PROVIDE( Cache_WriteBack_Invalidate_All = 0x4000060c ); Cache_Mask_All = 0x40000610; Cache_UnMask_Dram0 = 0x40000614; Cache_Suspend_Autoload = 0x40000618; diff --git a/components/esp_rom/esp32p4/Kconfig.soc_caps.in b/components/esp_rom/esp32p4/Kconfig.soc_caps.in index 84c2a0f9bd0..75a2f1421b3 100644 --- a/components/esp_rom/esp32p4/Kconfig.soc_caps.in +++ b/components/esp_rom/esp32p4/Kconfig.soc_caps.in @@ -94,3 +94,7 @@ config ESP_ROM_HAS_SUBOPTIMAL_NEWLIB_ON_MISALIGNED_MEMORY config ESP_ROM_BOOTLOADER_OFFSET_FLASH hex default 0x2000 + +config ESP_ROM_CACHE_WRITEBACK_NEEDS_SYNC_TWICE_MAP + bool + default y diff --git a/components/esp_rom/esp32p4/esp_rom_caps.h b/components/esp_rom/esp32p4/esp_rom_caps.h index 8092c48704b..c1ee928beda 100644 --- a/components/esp_rom/esp32p4/esp_rom_caps.h +++ b/components/esp_rom/esp32p4/esp_rom_caps.h @@ -29,3 +29,4 @@ #define ESP_ROM_HAS_OUTPUT_PUTC_FUNC (1) // ROM has esp_rom_output_putc (or ets_write_char_uart) #define ESP_ROM_HAS_SUBOPTIMAL_NEWLIB_ON_MISALIGNED_MEMORY (1) // ROM mem/str functions are not optimized well for misaligned memory access. #define ESP_ROM_BOOTLOADER_OFFSET_FLASH (0x2000) // Bootloader offset in flash determined by the ROM bootloader +#define ESP_ROM_CACHE_WRITEBACK_NEEDS_SYNC_TWICE_MAP (1) // ROM cache writeback related needs patch to avoid sync loss, need map parameter diff --git a/components/esp_rom/esp32p4/include/esp32p4/rom/cache.h b/components/esp_rom/esp32p4/include/esp32p4/rom/cache.h index 0c5ba82533b..8fbc22de785 100644 --- a/components/esp_rom/esp32p4/include/esp32p4/rom/cache.h +++ b/components/esp_rom/esp32p4/include/esp32p4/rom/cache.h @@ -233,6 +233,7 @@ typedef enum { #define CACHE_MAP_L1_ICACHE_MASK (CACHE_MAP_L1_ICACHE_0 | CACHE_MAP_L1_ICACHE_1) #define CACHE_MAP_L1_CACHE_MASK (CACHE_MAP_L1_ICACHE_MASK | CACHE_MAP_L1_DCACHE) #define CACHE_MAP_MASK (CACHE_MAP_L1_ICACHE_MASK | CACHE_MAP_L1_DCACHE | CACHE_MAP_L2_CACHE) +#define CACHE_MAP_DCACHE_MASK (CACHE_MAP_L1_DCACHE | CACHE_MAP_L2_CACHE) struct cache_internal_stub_table { uint32_t (*l1_icache_line_size)(void); diff --git a/components/esp_rom/esp32p4/ld/esp32p4.rom.eco5.ld b/components/esp_rom/esp32p4/ld/esp32p4.rom.eco5.ld index 0df2f533eb2..6c2a6748eb4 100644 --- a/components/esp_rom/esp32p4/ld/esp32p4.rom.eco5.ld +++ b/components/esp_rom/esp32p4/ld/esp32p4.rom.eco5.ld @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -187,17 +187,17 @@ Cache_Invalidate_Addr = 0x4fc003e4; Cache_Invalidate_Addr_Gid = 0x4fc003e8; Cache_Clean_Addr = 0x4fc003ec; Cache_Clean_Addr_Gid = 0x4fc003f0; -Cache_WriteBack_Addr = 0x4fc003f4; +PROVIDE( Cache_WriteBack_Addr = 0x4fc003f4 ); Cache_WriteBack_Addr_Gid = 0x4fc003f8; -Cache_WriteBack_Invalidate_Addr = 0x4fc003fc; +PROVIDE( Cache_WriteBack_Invalidate_Addr = 0x4fc003fc ); Cache_WriteBack_Invalidate_Addr_Gid = 0x4fc00400; Cache_Invalidate_All = 0x4fc00404; Cache_Invalidate_All_Gid = 0x4fc00408; Cache_Clean_All = 0x4fc0040c; Cache_Clean_All_Gid = 0x4fc00410; -Cache_WriteBack_All = 0x4fc00414; +PROVIDE( Cache_WriteBack_All = 0x4fc00414 ); Cache_WriteBack_All_Gid = 0x4fc00418; -Cache_WriteBack_Invalidate_All = 0x4fc0041c; +PROVIDE( Cache_WriteBack_Invalidate_All = 0x4fc0041c ); Cache_WriteBack_Invalidate_All_Gid = 0x4fc00420; Cache_Mask_All = 0x4fc00424; Cache_Suspend_L1_CORE0_ICache_Autoload = 0x4fc00428; diff --git a/components/esp_rom/esp32p4/ld/esp32p4.rom.ld b/components/esp_rom/esp32p4/ld/esp32p4.rom.ld index b9950412e06..0a35cde1b5e 100644 --- a/components/esp_rom/esp32p4/ld/esp32p4.rom.ld +++ b/components/esp_rom/esp32p4/ld/esp32p4.rom.ld @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -187,17 +187,17 @@ Cache_Invalidate_Addr = 0x4fc003e4; Cache_Invalidate_Addr_Gid = 0x4fc003e8; Cache_Clean_Addr = 0x4fc003ec; Cache_Clean_Addr_Gid = 0x4fc003f0; -Cache_WriteBack_Addr = 0x4fc003f4; +PROVIDE( Cache_WriteBack_Addr = 0x4fc003f4 ); Cache_WriteBack_Addr_Gid = 0x4fc003f8; -Cache_WriteBack_Invalidate_Addr = 0x4fc003fc; +PROVIDE( Cache_WriteBack_Invalidate_Addr = 0x4fc003fc ); Cache_WriteBack_Invalidate_Addr_Gid = 0x4fc00400; Cache_Invalidate_All = 0x4fc00404; Cache_Invalidate_All_Gid = 0x4fc00408; Cache_Clean_All = 0x4fc0040c; Cache_Clean_All_Gid = 0x4fc00410; -Cache_WriteBack_All = 0x4fc00414; +PROVIDE( Cache_WriteBack_All = 0x4fc00414 ); Cache_WriteBack_All_Gid = 0x4fc00418; -Cache_WriteBack_Invalidate_All = 0x4fc0041c; +PROVIDE( Cache_WriteBack_Invalidate_All = 0x4fc0041c ); Cache_WriteBack_Invalidate_All_Gid = 0x4fc00420; Cache_Mask_All = 0x4fc00424; Cache_Suspend_L1_CORE0_ICache_Autoload = 0x4fc00428; diff --git a/components/esp_rom/linker.lf b/components/esp_rom/linker.lf index 944abe90a87..3b56a33caf1 100644 --- a/components/esp_rom/linker.lf +++ b/components/esp_rom/linker.lf @@ -15,3 +15,7 @@ entries: esp_rom_systimer (noflash) if HAL_WDT_USE_ROM_IMPL = y: esp_rom_wdt (noflash) + if ESP_ROM_CACHE_WRITEBACK_NEEDS_SYNC_TWICE_MAP = y: + esp_rom_cache_writeback_esp32p4 (noflash) + if ESP_ROM_CACHE_WRITEBACK_NEEDS_SYNC_TWICE_NO_MAP = y: + esp_rom_cache_writeback_esp32c5_esp32c61_esp32h4 (noflash) diff --git a/components/esp_rom/patches/esp_rom_cache_writeback_esp32c5_esp32c61_esp32h4.c b/components/esp_rom/patches/esp_rom_cache_writeback_esp32c5_esp32c61_esp32h4.c new file mode 100644 index 00000000000..7c87535edb3 --- /dev/null +++ b/components/esp_rom/patches/esp_rom_cache_writeback_esp32c5_esp32c61_esp32h4.c @@ -0,0 +1,78 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "soc/cache_reg.h" +#include "rom/cache.h" + +// esp32c5, esp32c61 and esp32h4 do not need msp parameters in apis. +int Cache_WriteBack_Addr(uint32_t addr, uint32_t size) +{ + uint32_t plus; + uint32_t cache_line_size = MIN_CACHE_LINE_SIZE; + + plus = addr & (cache_line_size - 1); + addr -= plus; + size += plus; + size = (size + cache_line_size - 1) & ~(cache_line_size - 1); + + REG_WRITE(CACHE_SYNC_MAP_REG, CACHE_MAP_FLASH_CACHE); + REG_WRITE(CACHE_SYNC_ADDR_REG, addr); + REG_WRITE(CACHE_SYNC_SIZE_REG, size); + REG_WRITE(CACHE_SYNC_CTRL_REG, CACHE_WRITEBACK_ENA); + while (!REG_GET_BIT(CACHE_SYNC_CTRL_REG, CACHE_SYNC_DONE)); + + REG_WRITE(CACHE_SYNC_CTRL_REG, CACHE_WRITEBACK_ENA); + while (!REG_GET_BIT(CACHE_SYNC_CTRL_REG, CACHE_SYNC_DONE)); + + return 0; +} + +void Cache_WriteBack_All(void) +{ + REG_WRITE(CACHE_SYNC_MAP_REG, CACHE_MAP_FLASH_CACHE); + REG_WRITE(CACHE_SYNC_ADDR_REG, 0); + REG_WRITE(CACHE_SYNC_SIZE_REG, 0); + REG_WRITE(CACHE_SYNC_CTRL_REG, CACHE_WRITEBACK_ENA); + while (!REG_GET_BIT(CACHE_SYNC_CTRL_REG, CACHE_SYNC_DONE)); + + REG_WRITE(CACHE_SYNC_CTRL_REG, CACHE_WRITEBACK_ENA); + while (!REG_GET_BIT(CACHE_SYNC_CTRL_REG, CACHE_SYNC_DONE)); +} + +int Cache_WriteBack_Invalidate_Addr(uint32_t addr, uint32_t size) +{ + uint32_t plus; + uint32_t cache_line_size = MIN_CACHE_LINE_SIZE; + + plus = addr & (cache_line_size - 1); + addr -= plus; + size += plus; + size = (size + cache_line_size - 1) & ~(cache_line_size - 1); + + REG_WRITE(CACHE_SYNC_MAP_REG, CACHE_MAP_FLASH_CACHE); + REG_WRITE(CACHE_SYNC_ADDR_REG, addr); + REG_WRITE(CACHE_SYNC_SIZE_REG, size); + REG_WRITE(CACHE_SYNC_CTRL_REG, CACHE_WRITEBACK_INVALIDATE_ENA); + while (!REG_GET_BIT(CACHE_SYNC_CTRL_REG, CACHE_SYNC_DONE)); + + REG_WRITE(CACHE_SYNC_CTRL_REG, CACHE_WRITEBACK_INVALIDATE_ENA); + while (!REG_GET_BIT(CACHE_SYNC_CTRL_REG, CACHE_SYNC_DONE)); + + return 0; +} + +void Cache_WriteBack_Invalidate_All(void) +{ + REG_WRITE(CACHE_SYNC_MAP_REG, CACHE_MAP_FLASH_CACHE); + REG_WRITE(CACHE_SYNC_ADDR_REG, 0); + REG_WRITE(CACHE_SYNC_SIZE_REG, 0); + REG_WRITE(CACHE_SYNC_CTRL_REG, CACHE_WRITEBACK_INVALIDATE_ENA); + while (!REG_GET_BIT(CACHE_SYNC_CTRL_REG, CACHE_SYNC_DONE)); + + REG_WRITE(CACHE_SYNC_CTRL_REG, CACHE_WRITEBACK_INVALIDATE_ENA); + while (!REG_GET_BIT(CACHE_SYNC_CTRL_REG, CACHE_SYNC_DONE)); +} diff --git a/components/esp_rom/patches/esp_rom_cache_writeback_esp32p4.c b/components/esp_rom/patches/esp_rom_cache_writeback_esp32p4.c new file mode 100644 index 00000000000..49c34adf597 --- /dev/null +++ b/components/esp_rom/patches/esp_rom_cache_writeback_esp32p4.c @@ -0,0 +1,135 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "soc/cache_reg.h" +#include "rom/cache.h" +#include "esp_attr.h" +#include "esp_rom_sys.h" + +// esp32p4 needs msp parameters in apis. +int Cache_WriteBack_Addr(uint32_t map, uint32_t addr, uint32_t size) +{ + uint32_t plus; + uint32_t cache_line_size = 0; + /* writeback readonly cache is invalid */ + if (map & CACHE_MAP_L1_ICACHE_MASK) { + return ESP_ROM_ERR_INVALID_ARG; + } + + if ((map & CACHE_MAP_DCACHE_MASK) == 0) { + return ESP_ROM_ERR_INVALID_ARG; + } + + /* esp32p4 will check l2 cache */ + if (map & CACHE_MAP_L1_DCACHE) { + cache_line_size = rom_cache_internal_table_ptr->l1_dcache_line_size(); + } + if (map & CACHE_MAP_L2_CACHE) { + cache_line_size = (cache_line_size > rom_cache_internal_table_ptr->l2_cache_line_size()) ? + cache_line_size : rom_cache_internal_table_ptr->l2_cache_line_size(); + } + + plus = addr & (cache_line_size - 1); + addr -= plus; + size += plus; + size = (size + cache_line_size - 1) & ~(cache_line_size - 1); + REG_WRITE(CACHE_SYNC_MAP_REG, map); + REG_WRITE(CACHE_SYNC_ADDR_REG, addr); + REG_WRITE(CACHE_SYNC_SIZE_REG, size); + REG_WRITE(CACHE_SYNC_CTRL_REG, CACHE_WRITEBACK_ENA); + while (!REG_GET_BIT(CACHE_SYNC_CTRL_REG, CACHE_SYNC_DONE)); + + REG_WRITE(CACHE_SYNC_CTRL_REG, CACHE_WRITEBACK_ENA); + while (!REG_GET_BIT(CACHE_SYNC_CTRL_REG, CACHE_SYNC_DONE)); + + return 0; +} + +int Cache_WriteBack_All(uint32_t map) +{ + /* writeback readonly cache is invalid */ + if (map & CACHE_MAP_L1_ICACHE_MASK) { + return ESP_ROM_ERR_INVALID_ARG; + } + + if ((map & CACHE_MAP_DCACHE_MASK) == 0) { + return ESP_ROM_ERR_INVALID_ARG; + } + + REG_WRITE(CACHE_SYNC_MAP_REG, map); + REG_WRITE(CACHE_SYNC_ADDR_REG, 0); + REG_WRITE(CACHE_SYNC_SIZE_REG, 0); + REG_WRITE(CACHE_SYNC_CTRL_REG, CACHE_WRITEBACK_ENA); + while (!REG_GET_BIT(CACHE_SYNC_CTRL_REG, CACHE_SYNC_DONE)); + + REG_WRITE(CACHE_SYNC_CTRL_REG, CACHE_WRITEBACK_ENA); + while (!REG_GET_BIT(CACHE_SYNC_CTRL_REG, CACHE_SYNC_DONE)); + + return 0; +} + +int Cache_WriteBack_Invalidate_Addr(uint32_t map, uint32_t addr, uint32_t size) +{ + uint32_t plus; + uint32_t cache_line_size = 0; + /* writeback readonly cache is invalid */ + if (map & CACHE_MAP_L1_ICACHE_MASK) { + return ESP_ROM_ERR_INVALID_ARG; + } + + if ((map & CACHE_MAP_DCACHE_MASK) == 0) { + return ESP_ROM_ERR_INVALID_ARG; + } + + /* esp32p4 will check l2 cache */ + if (map & CACHE_MAP_L1_DCACHE) { + cache_line_size = rom_cache_internal_table_ptr->l1_dcache_line_size(); + } + if (map & CACHE_MAP_L2_CACHE) { + cache_line_size = (cache_line_size > rom_cache_internal_table_ptr->l2_cache_line_size()) ? + cache_line_size : rom_cache_internal_table_ptr->l2_cache_line_size(); + } + + plus = addr & (cache_line_size - 1); + addr -= plus; + size += plus; + size = (size + cache_line_size - 1) & ~(cache_line_size - 1); + + REG_WRITE(CACHE_SYNC_MAP_REG, map); + REG_WRITE(CACHE_SYNC_ADDR_REG, addr); + REG_WRITE(CACHE_SYNC_SIZE_REG, size); + REG_WRITE(CACHE_SYNC_CTRL_REG, CACHE_WRITEBACK_INVALIDATE_ENA); + while (!REG_GET_BIT(CACHE_SYNC_CTRL_REG, CACHE_SYNC_DONE)); + + REG_WRITE(CACHE_SYNC_CTRL_REG, CACHE_WRITEBACK_INVALIDATE_ENA); + while (!REG_GET_BIT(CACHE_SYNC_CTRL_REG, CACHE_SYNC_DONE)); + + return 0; +} + +int Cache_WriteBack_Invalidate_All(uint32_t map) +{ + /* writeback readonly cache is invalid */ + if (map & CACHE_MAP_L1_ICACHE_MASK) { + return ESP_ROM_ERR_INVALID_ARG; + } + + if ((map & CACHE_MAP_DCACHE_MASK) == 0) { + return ESP_ROM_ERR_INVALID_ARG; + } + + REG_WRITE(CACHE_SYNC_MAP_REG, map); + REG_WRITE(CACHE_SYNC_ADDR_REG, 0); + REG_WRITE(CACHE_SYNC_SIZE_REG, 0); + REG_WRITE(CACHE_SYNC_CTRL_REG, CACHE_WRITEBACK_INVALIDATE_ENA); + while (!REG_GET_BIT(CACHE_SYNC_CTRL_REG, CACHE_SYNC_DONE)); + + REG_WRITE(CACHE_SYNC_CTRL_REG, CACHE_WRITEBACK_INVALIDATE_ENA); + while (!REG_GET_BIT(CACHE_SYNC_CTRL_REG, CACHE_SYNC_DONE)); + + return 0; +} From 733a5e5d026b8a2d6ad1dcd9d8d993127a4bcd41 Mon Sep 17 00:00:00 2001 From: wanglei Date: Fri, 22 May 2026 11:53:50 +0800 Subject: [PATCH 2/2] feat(esp_rom): do not patch Cache_WriteBack_All for uboot build --- .../esp_rom_cache_writeback_esp32c5_esp32c61_esp32h4.c | 2 ++ .../esp_rom/patches/esp_rom_cache_writeback_esp32p4.c | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/components/esp_rom/patches/esp_rom_cache_writeback_esp32c5_esp32c61_esp32h4.c b/components/esp_rom/patches/esp_rom_cache_writeback_esp32c5_esp32c61_esp32h4.c index 7c87535edb3..3c6051ae1c7 100644 --- a/components/esp_rom/patches/esp_rom_cache_writeback_esp32c5_esp32c61_esp32h4.c +++ b/components/esp_rom/patches/esp_rom_cache_writeback_esp32c5_esp32c61_esp32h4.c @@ -31,6 +31,7 @@ int Cache_WriteBack_Addr(uint32_t addr, uint32_t size) return 0; } +#ifndef BOOTLOADER_BUILD void Cache_WriteBack_All(void) { REG_WRITE(CACHE_SYNC_MAP_REG, CACHE_MAP_FLASH_CACHE); @@ -42,6 +43,7 @@ void Cache_WriteBack_All(void) REG_WRITE(CACHE_SYNC_CTRL_REG, CACHE_WRITEBACK_ENA); while (!REG_GET_BIT(CACHE_SYNC_CTRL_REG, CACHE_SYNC_DONE)); } +#endif int Cache_WriteBack_Invalidate_Addr(uint32_t addr, uint32_t size) { diff --git a/components/esp_rom/patches/esp_rom_cache_writeback_esp32p4.c b/components/esp_rom/patches/esp_rom_cache_writeback_esp32p4.c index 49c34adf597..f523d78bacd 100644 --- a/components/esp_rom/patches/esp_rom_cache_writeback_esp32p4.c +++ b/components/esp_rom/patches/esp_rom_cache_writeback_esp32p4.c @@ -49,6 +49,11 @@ int Cache_WriteBack_Addr(uint32_t map, uint32_t addr, uint32_t size) return 0; } +#ifndef BOOTLOADER_BUILD +/** + * ci build no test related case will check backtrace not call functions from .iram.text + * so for bootloader still use the rom function. The issue will not occur in uboot stage + */ int Cache_WriteBack_All(uint32_t map) { /* writeback readonly cache is invalid */ @@ -71,6 +76,7 @@ int Cache_WriteBack_All(uint32_t map) return 0; } +#endif int Cache_WriteBack_Invalidate_Addr(uint32_t map, uint32_t addr, uint32_t size) {