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
This commit is contained in:
wanglei
2026-05-22 10:19:35 +08:00
parent 128defc06a
commit 85f79ecb07
19 changed files with 273 additions and 25 deletions
+8
View File
@@ -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") list(APPEND sources "patches/esp_rom_cache_esp32c5.c")
endif() 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} idf_component_register(SRCS ${sources}
INCLUDE_DIRS ${include_dirs} INCLUDE_DIRS ${include_dirs}
PRIV_REQUIRES ${private_required_comp} PRIV_REQUIRES ${private_required_comp}
@@ -126,3 +126,7 @@ config ESP_ROM_DELAY_US_PATCH
config ESP_ROM_SUPPORT_SECURE_BOOT_FAST_WAKEUP config ESP_ROM_SUPPORT_SECURE_BOOT_FAST_WAKEUP
bool bool
default y default y
config ESP_ROM_CACHE_WRITEBACK_NEEDS_SYNC_TWICE_NO_MAP
bool
default y
@@ -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_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_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_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
+5 -5
View File
@@ -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 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -192,12 +192,12 @@ Cache_Sync_Items = 0x40000648;
Cache_Op_Addr = 0x4000064c; Cache_Op_Addr = 0x4000064c;
Cache_Invalidate_Addr = 0x40000650; Cache_Invalidate_Addr = 0x40000650;
Cache_Clean_Addr = 0x40000654; Cache_Clean_Addr = 0x40000654;
Cache_WriteBack_Addr = 0x40000658; PROVIDE( Cache_WriteBack_Addr = 0x40000658 );
Cache_WriteBack_Invalidate_Addr = 0x4000065c; PROVIDE( Cache_WriteBack_Invalidate_Addr = 0x4000065c );
Cache_Invalidate_All = 0x40000660; Cache_Invalidate_All = 0x40000660;
Cache_Clean_All = 0x40000664; Cache_Clean_All = 0x40000664;
Cache_WriteBack_All = 0x40000668; PROVIDE( Cache_WriteBack_All = 0x40000668 );
Cache_WriteBack_Invalidate_All = 0x4000066c; PROVIDE( Cache_WriteBack_Invalidate_All = 0x4000066c );
Cache_Mask_All = 0x40000670; Cache_Mask_All = 0x40000670;
Cache_UnMask_Dram0 = 0x40000674; Cache_UnMask_Dram0 = 0x40000674;
Cache_Suspend_Autoload = 0x40000678; Cache_Suspend_Autoload = 0x40000678;
@@ -118,3 +118,7 @@ config ESP_ROM_HAS_SUBOPTIMAL_NEWLIB_ON_MISALIGNED_MEMORY
config ESP_ROM_DELAY_US_PATCH config ESP_ROM_DELAY_US_PATCH
bool bool
default y default y
config ESP_ROM_CACHE_WRITEBACK_NEEDS_SYNC_TWICE_NO_MAP
bool
default y
@@ -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_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_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_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
@@ -49,6 +49,8 @@ typedef enum {
CACHE_SYNC_WRITEBACK_INVALIDATE = BIT(3), CACHE_SYNC_WRITEBACK_INVALIDATE = BIT(3),
} cache_sync_t; } cache_sync_t;
#define CACHE_MAP_FLASH_CACHE BIT(4)
typedef enum { typedef enum {
CACHE_SIZE_HALF = 0, /*!< 8KB for icache and dcache */ CACHE_SIZE_HALF = 0, /*!< 8KB for icache and dcache */
CACHE_SIZE_FULL = 1, /*!< 16KB for icache and dcache */ CACHE_SIZE_FULL = 1, /*!< 16KB for icache and dcache */
@@ -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 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -188,12 +188,12 @@ Cache_Sync_Items = 0x4000062c;
Cache_Op_Addr = 0x40000630; Cache_Op_Addr = 0x40000630;
Cache_Invalidate_Addr = 0x40000634; Cache_Invalidate_Addr = 0x40000634;
Cache_Clean_Addr = 0x40000638; Cache_Clean_Addr = 0x40000638;
Cache_WriteBack_Addr = 0x4000063c; PROVIDE( Cache_WriteBack_Addr = 0x4000063c );
Cache_WriteBack_Invalidate_Addr = 0x40000640; PROVIDE( Cache_WriteBack_Invalidate_Addr = 0x40000640 );
Cache_Invalidate_All = 0x40000644; Cache_Invalidate_All = 0x40000644;
Cache_Clean_All = 0x40000648; Cache_Clean_All = 0x40000648;
Cache_WriteBack_All = 0x4000064c; PROVIDE( Cache_WriteBack_All = 0x4000064c );
Cache_WriteBack_Invalidate_All = 0x40000650; PROVIDE( Cache_WriteBack_Invalidate_All = 0x40000650 );
Cache_Mask_All = 0x40000654; Cache_Mask_All = 0x40000654;
Cache_UnMask_Dram0 = 0x40000658; Cache_UnMask_Dram0 = 0x40000658;
Cache_Suspend_Autoload = 0x4000065c; Cache_Suspend_Autoload = 0x4000065c;
@@ -78,3 +78,7 @@ config ESP_ROM_WDT_INIT_PATCH
config ESP_ROM_RAM_APP_NEEDS_MMU_INIT config ESP_ROM_RAM_APP_NEEDS_MMU_INIT
bool bool
default y default y
config ESP_ROM_CACHE_WRITEBACK_NEEDS_SYNC_TWICE_NO_MAP
bool
default y
@@ -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_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_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_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
+5 -5
View File
@@ -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 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -182,12 +182,12 @@ Cache_Sync_Items = 0x400005e8;
Cache_Op_Addr = 0x400005ec; Cache_Op_Addr = 0x400005ec;
Cache_Invalidate_Addr = 0x400005f0; Cache_Invalidate_Addr = 0x400005f0;
Cache_Clean_Addr = 0x400005f4; Cache_Clean_Addr = 0x400005f4;
Cache_WriteBack_Addr = 0x400005f8; PROVIDE( Cache_WriteBack_Addr = 0x400005f8 );
Cache_WriteBack_Invalidate_Addr = 0x400005fc; PROVIDE( Cache_WriteBack_Invalidate_Addr = 0x400005fc );
Cache_Invalidate_All = 0x40000600; Cache_Invalidate_All = 0x40000600;
Cache_Clean_All = 0x40000604; Cache_Clean_All = 0x40000604;
Cache_WriteBack_All = 0x40000608; PROVIDE( Cache_WriteBack_All = 0x40000608 );
Cache_WriteBack_Invalidate_All = 0x4000060c; PROVIDE( Cache_WriteBack_Invalidate_All = 0x4000060c );
Cache_Mask_All = 0x40000610; Cache_Mask_All = 0x40000610;
Cache_UnMask_Dram0 = 0x40000614; Cache_UnMask_Dram0 = 0x40000614;
Cache_Suspend_Autoload = 0x40000618; Cache_Suspend_Autoload = 0x40000618;
@@ -94,3 +94,7 @@ config ESP_ROM_HAS_SUBOPTIMAL_NEWLIB_ON_MISALIGNED_MEMORY
config ESP_ROM_BOOTLOADER_OFFSET_FLASH config ESP_ROM_BOOTLOADER_OFFSET_FLASH
hex hex
default 0x2000 default 0x2000
config ESP_ROM_CACHE_WRITEBACK_NEEDS_SYNC_TWICE_MAP
bool
default y
@@ -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_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_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_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
@@ -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_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_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_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 { struct cache_internal_stub_table {
uint32_t (*l1_icache_line_size)(void); uint32_t (*l1_icache_line_size)(void);
@@ -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 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -187,17 +187,17 @@ Cache_Invalidate_Addr = 0x4fc003e4;
Cache_Invalidate_Addr_Gid = 0x4fc003e8; Cache_Invalidate_Addr_Gid = 0x4fc003e8;
Cache_Clean_Addr = 0x4fc003ec; Cache_Clean_Addr = 0x4fc003ec;
Cache_Clean_Addr_Gid = 0x4fc003f0; Cache_Clean_Addr_Gid = 0x4fc003f0;
Cache_WriteBack_Addr = 0x4fc003f4; PROVIDE( Cache_WriteBack_Addr = 0x4fc003f4 );
Cache_WriteBack_Addr_Gid = 0x4fc003f8; Cache_WriteBack_Addr_Gid = 0x4fc003f8;
Cache_WriteBack_Invalidate_Addr = 0x4fc003fc; PROVIDE( Cache_WriteBack_Invalidate_Addr = 0x4fc003fc );
Cache_WriteBack_Invalidate_Addr_Gid = 0x4fc00400; Cache_WriteBack_Invalidate_Addr_Gid = 0x4fc00400;
Cache_Invalidate_All = 0x4fc00404; Cache_Invalidate_All = 0x4fc00404;
Cache_Invalidate_All_Gid = 0x4fc00408; Cache_Invalidate_All_Gid = 0x4fc00408;
Cache_Clean_All = 0x4fc0040c; Cache_Clean_All = 0x4fc0040c;
Cache_Clean_All_Gid = 0x4fc00410; Cache_Clean_All_Gid = 0x4fc00410;
Cache_WriteBack_All = 0x4fc00414; PROVIDE( Cache_WriteBack_All = 0x4fc00414 );
Cache_WriteBack_All_Gid = 0x4fc00418; Cache_WriteBack_All_Gid = 0x4fc00418;
Cache_WriteBack_Invalidate_All = 0x4fc0041c; PROVIDE( Cache_WriteBack_Invalidate_All = 0x4fc0041c );
Cache_WriteBack_Invalidate_All_Gid = 0x4fc00420; Cache_WriteBack_Invalidate_All_Gid = 0x4fc00420;
Cache_Mask_All = 0x4fc00424; Cache_Mask_All = 0x4fc00424;
Cache_Suspend_L1_CORE0_ICache_Autoload = 0x4fc00428; Cache_Suspend_L1_CORE0_ICache_Autoload = 0x4fc00428;
+5 -5
View File
@@ -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 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -187,17 +187,17 @@ Cache_Invalidate_Addr = 0x4fc003e4;
Cache_Invalidate_Addr_Gid = 0x4fc003e8; Cache_Invalidate_Addr_Gid = 0x4fc003e8;
Cache_Clean_Addr = 0x4fc003ec; Cache_Clean_Addr = 0x4fc003ec;
Cache_Clean_Addr_Gid = 0x4fc003f0; Cache_Clean_Addr_Gid = 0x4fc003f0;
Cache_WriteBack_Addr = 0x4fc003f4; PROVIDE( Cache_WriteBack_Addr = 0x4fc003f4 );
Cache_WriteBack_Addr_Gid = 0x4fc003f8; Cache_WriteBack_Addr_Gid = 0x4fc003f8;
Cache_WriteBack_Invalidate_Addr = 0x4fc003fc; PROVIDE( Cache_WriteBack_Invalidate_Addr = 0x4fc003fc );
Cache_WriteBack_Invalidate_Addr_Gid = 0x4fc00400; Cache_WriteBack_Invalidate_Addr_Gid = 0x4fc00400;
Cache_Invalidate_All = 0x4fc00404; Cache_Invalidate_All = 0x4fc00404;
Cache_Invalidate_All_Gid = 0x4fc00408; Cache_Invalidate_All_Gid = 0x4fc00408;
Cache_Clean_All = 0x4fc0040c; Cache_Clean_All = 0x4fc0040c;
Cache_Clean_All_Gid = 0x4fc00410; Cache_Clean_All_Gid = 0x4fc00410;
Cache_WriteBack_All = 0x4fc00414; PROVIDE( Cache_WriteBack_All = 0x4fc00414 );
Cache_WriteBack_All_Gid = 0x4fc00418; Cache_WriteBack_All_Gid = 0x4fc00418;
Cache_WriteBack_Invalidate_All = 0x4fc0041c; PROVIDE( Cache_WriteBack_Invalidate_All = 0x4fc0041c );
Cache_WriteBack_Invalidate_All_Gid = 0x4fc00420; Cache_WriteBack_Invalidate_All_Gid = 0x4fc00420;
Cache_Mask_All = 0x4fc00424; Cache_Mask_All = 0x4fc00424;
Cache_Suspend_L1_CORE0_ICache_Autoload = 0x4fc00428; Cache_Suspend_L1_CORE0_ICache_Autoload = 0x4fc00428;
+4
View File
@@ -15,3 +15,7 @@ entries:
esp_rom_systimer (noflash) esp_rom_systimer (noflash)
if HAL_WDT_USE_ROM_IMPL = y: if HAL_WDT_USE_ROM_IMPL = y:
esp_rom_wdt (noflash) 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)
@@ -0,0 +1,78 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#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));
}
@@ -0,0 +1,135 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#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;
}