mirror of
https://github.com/espressif/esp-idf.git
synced 2026-08-18 06:35:35 +03:00
Merge branch 'fix/for_cache_after_p4_wb_loss_issue_v5.4' into 'release/v5.4'
fix(esp_rom): avoid critical issue in writeback v5.4 See merge request espressif/esp-idf!48816
This commit is contained in:
@@ -67,8 +67,8 @@ if(CONFIG_ESP_ROM_HAS_FLASH_COUNT_PAGES_BUG OR CONFIG_ESP_ROM_HAS_CACHE_WRITEBAC
|
||||
list(APPEND sources "patches/esp_rom_cache_esp32s2_esp32s3.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_ESP_ROM_CACHE_WB_INVLD_LOW_RANGE)
|
||||
list(APPEND sources "patches/esp_rom_cache_esp32c61.c")
|
||||
if(CONFIG_ESP_ROM_CACHE_WB_INVLD_LOW_RANGE OR CONFIG_ESP_ROM_CACHE_WRITEBACK_NEEDS_SYNC_TWICE_NO_MAP)
|
||||
list(APPEND sources "patches/esp_rom_cache_esp32c5_esp32c61.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_ESP_ROM_HAS_CACHE_WRITEBACK_BUG)
|
||||
@@ -79,6 +79,10 @@ if(CONFIG_ESP_ROM_NO_USB_SERIAL_OUTPUT_API)
|
||||
list(APPEND sources "patches/esp_rom_usb_serial.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_ESP_ROM_CACHE_WRITEBACK_NEEDS_SYNC_TWICE_MAP)
|
||||
list(APPEND sources "patches/esp_rom_cache_writeback_esp32p4.c")
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS ${sources}
|
||||
INCLUDE_DIRS ${include_dirs}
|
||||
PRIV_REQUIRES ${private_required_comp}
|
||||
|
||||
@@ -110,3 +110,7 @@ config ESP_ROM_CLIC_INT_THRESH_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
|
||||
|
||||
@@ -33,3 +33,4 @@
|
||||
#define ESP_ROM_HAS_OUTPUT_PUTC_FUNC (1) // ROM has esp_rom_output_putc (or ets_write_char_uart)
|
||||
#define ESP_ROM_CLIC_INT_THRESH_PATCH (1) // ROM version of esprv_intc_int_set_threshold incorrectly assumes lowest MINTTHRESH is 0x1F, should be 0xF
|
||||
#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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-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;
|
||||
|
||||
@@ -106,3 +106,7 @@ config ESP_ROM_HAS_OUTPUT_PUTC_FUNC
|
||||
config ESP_ROM_CACHE_WB_INVLD_LOW_RANGE
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_CACHE_WRITEBACK_NEEDS_SYNC_TWICE_NO_MAP
|
||||
bool
|
||||
default y
|
||||
|
||||
@@ -32,3 +32,4 @@
|
||||
#define ESP_ROM_USB_OTG_NUM (-1) // No USB_OTG CDC in the ROM, set -1 for Kconfig usage.
|
||||
#define ESP_ROM_HAS_OUTPUT_PUTC_FUNC (1) // ROM has esp_rom_output_putc (or ets_write_char_uart)
|
||||
#define ESP_ROM_CACHE_WB_INVLD_LOW_RANGE (1) // ROM `Cache_WriteBack_Addr` and `Cache_Invalidate_Addr` can only access low vaddr parts
|
||||
#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_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 */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -195,11 +195,11 @@ Cache_Op_Addr = 0x40000630;
|
||||
/*Cache_Invalidate_Addr = 0x40000634; rom version API has issue that unable to access higher vaddr range, use IDF patch */
|
||||
Cache_Clean_Addr = 0x40000638;
|
||||
/*Cache_WriteBack_Addr = 0x4000063c; rom version API has issue that unable to access higher vaddr range, use IDF patch */
|
||||
Cache_WriteBack_Invalidate_Addr = 0x40000640;
|
||||
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;
|
||||
|
||||
@@ -82,3 +82,7 @@ config ESP_ROM_CLIC_INT_TYPE_PATCH
|
||||
config ESP_ROM_HAS_OUTPUT_PUTC_FUNC
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_CACHE_WRITEBACK_NEEDS_SYNC_TWICE_MAP
|
||||
bool
|
||||
default y
|
||||
|
||||
@@ -26,3 +26,4 @@
|
||||
#define ESP_ROM_HAS_VERSION (1) // ROM has version/eco information
|
||||
#define ESP_ROM_CLIC_INT_TYPE_PATCH (1) // ROM api esprv_intc_int_set_type configuring edge type interrupt is invalid TODO: IDF-13409
|
||||
#define ESP_ROM_HAS_OUTPUT_PUTC_FUNC (1) // ROM has esp_rom_output_putc (or ets_write_char_uart)
|
||||
#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_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);
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
@@ -209,17 +209,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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -8,11 +8,13 @@ entries:
|
||||
esp_rom_cache_esp32s2_esp32s3 (noflash)
|
||||
if ESP_ROM_HAS_CACHE_WRITEBACK_BUG = y:
|
||||
esp_rom_cache_writeback_esp32s3 (noflash)
|
||||
if ESP_ROM_CACHE_WB_INVLD_LOW_RANGE = y:
|
||||
esp_rom_cache_esp32c61 (noflash)
|
||||
if ESP_ROM_CACHE_WB_INVLD_LOW_RANGE = y || ESP_ROM_CACHE_WRITEBACK_NEEDS_SYNC_TWICE_NO_MAP = y:
|
||||
esp_rom_cache_esp32c5_esp32c61 (noflash)
|
||||
if HEAP_TLSF_USE_ROM_IMPL = y && (ESP_ROM_TLSF_CHECK_PATCH = y || HEAP_TLSF_CHECK_PATCH = y):
|
||||
esp_rom_tlsf (noflash)
|
||||
if SOC_SYSTIMER_SUPPORTED = y:
|
||||
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)
|
||||
|
||||
240
components/esp_rom/patches/esp_rom_cache_esp32c5_esp32c61.c
Normal file
240
components/esp_rom/patches/esp_rom_cache_esp32c5_esp32c61.c
Normal file
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_rom_caps.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/cache_reg.h"
|
||||
#include "soc/cache_struct.h"
|
||||
#include "soc/ext_mem_defs.h"
|
||||
#include "hal/assert.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32C61
|
||||
#include "esp32c61/rom/cache.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5
|
||||
#include "esp32c5/rom/cache.h"
|
||||
#else
|
||||
#error "This patch is only applied to ESP32C5 or ESP32C61"
|
||||
#endif
|
||||
|
||||
#include "esp_rom_sys.h"
|
||||
|
||||
/**
|
||||
* For ESP32C61, we will patch:
|
||||
* 1. writeback/invalidate not work with high address, https://jira.espressif.com:8443/browse/IDF-11008
|
||||
* 2. cache writeback skip, https://jira.espressif.com:8443/browse/DIG-829
|
||||
*
|
||||
* For ESP32C5, we will only patch cache writeback skip issue
|
||||
*/
|
||||
#if CONFIG_IDF_TARGET_ESP32C61
|
||||
|
||||
#define CACHE_MAX_SYNC_NUM ((CACHE_SYNC_SIZE + 1) >> 1)
|
||||
|
||||
/**
|
||||
* @brief Sync Cache items
|
||||
*
|
||||
* @param type sync type
|
||||
* @param addr address
|
||||
* @param bytes bytes to be synced
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void s_cache_sync_items(uint32_t type, uint32_t addr, uint32_t bytes)
|
||||
{
|
||||
REG_WRITE(CACHE_SYNC_ADDR_REG, addr);
|
||||
REG_SET_FIELD(CACHE_SYNC_SIZE_REG, CACHE_SYNC_SIZE, bytes);
|
||||
REG_SET_BIT(CACHE_SYNC_CTRL_REG, type);
|
||||
while (!REG_GET_BIT(CACHE_SYNC_CTRL_REG, CACHE_SYNC_DONE))
|
||||
;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline void s_cache_sync_items_twice(uint32_t type, uint32_t addr, uint32_t bytes)
|
||||
{
|
||||
REG_WRITE(CACHE_SYNC_ADDR_REG, addr);
|
||||
REG_SET_FIELD(CACHE_SYNC_SIZE_REG, CACHE_SYNC_SIZE, bytes);
|
||||
REG_SET_BIT(CACHE_SYNC_CTRL_REG, type);
|
||||
while (!REG_GET_BIT(CACHE_SYNC_CTRL_REG, CACHE_SYNC_DONE))
|
||||
;
|
||||
|
||||
REG_SET_BIT(CACHE_SYNC_CTRL_REG, type);
|
||||
while (!REG_GET_BIT(CACHE_SYNC_CTRL_REG, CACHE_SYNC_DONE))
|
||||
;
|
||||
}
|
||||
|
||||
int Cache_Invalidate_Addr(uint32_t vaddr, uint32_t size)
|
||||
{
|
||||
uint32_t plus = 0;
|
||||
uint32_t cache_line_size = 32;
|
||||
uint32_t cache_max_sync_size = CACHE_MAX_SYNC_NUM;
|
||||
if (size == 0) {
|
||||
HAL_ASSERT(false);
|
||||
}
|
||||
//aligned start address to cache line size
|
||||
plus = vaddr & (cache_line_size - 1);
|
||||
vaddr -= plus;
|
||||
//make the length fit the start address
|
||||
size += plus;
|
||||
//aligned the length to cache line size(0->0)
|
||||
size = (size + cache_line_size - 1) & ~(cache_line_size - 1);
|
||||
|
||||
while (size > 0) {
|
||||
//aligned to cache_max_sync_size, (0->cache_max_sync_size)
|
||||
uint32_t this_size = ((vaddr + cache_max_sync_size) & ~(cache_max_sync_size - 1)) - vaddr;
|
||||
if (this_size > size) {
|
||||
this_size = size;
|
||||
}
|
||||
s_cache_sync_items(CACHE_SYNC_INVALIDATE, vaddr, this_size);
|
||||
vaddr += this_size;
|
||||
size -= this_size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Cache_WriteBack_Addr(uint32_t vaddr, uint32_t size)
|
||||
{
|
||||
uint32_t plus = 0;
|
||||
uint32_t cache_line_size = 32;
|
||||
uint32_t cache_max_sync_size = CACHE_MAX_SYNC_NUM;
|
||||
if (size == 0) {
|
||||
HAL_ASSERT(false);
|
||||
}
|
||||
//aligned start address to cache line size
|
||||
plus = vaddr & (cache_line_size - 1);
|
||||
vaddr -= plus;
|
||||
//make the length fit the start address
|
||||
size += plus;
|
||||
//aligned the length to cache line size(0->0)
|
||||
size = (size + cache_line_size - 1) & ~(cache_line_size - 1);
|
||||
|
||||
while (size > 0) {
|
||||
//aligned to cache_max_sync_size, (0->cache_max_sync_size)
|
||||
uint32_t this_size = ((vaddr + cache_max_sync_size) & ~(cache_max_sync_size - 1)) - vaddr;
|
||||
if (this_size > size) {
|
||||
this_size = size;
|
||||
}
|
||||
s_cache_sync_items_twice(CACHE_SYNC_WRITEBACK, vaddr, this_size);
|
||||
vaddr += this_size;
|
||||
size -= this_size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Cache_WriteBack_Invalidate_Addr(uint32_t addr, uint32_t size)
|
||||
{
|
||||
uint32_t plus = 0;
|
||||
uint32_t cache_line_size = 32;
|
||||
uint32_t cache_max_sync_size = CACHE_MAX_SYNC_NUM;
|
||||
if (size == 0) {
|
||||
HAL_ASSERT(false);
|
||||
}
|
||||
//aligned start address to cache line size
|
||||
plus = vaddr & (cache_line_size - 1);
|
||||
vaddr -= plus;
|
||||
//make the length fit the start address
|
||||
size += plus;
|
||||
//aligned the length to cache line size(0->0)
|
||||
size = (size + cache_line_size - 1) & ~(cache_line_size - 1);
|
||||
|
||||
while (size > 0) {
|
||||
//aligned to cache_max_sync_size, (0->cache_max_sync_size)
|
||||
uint32_t this_size = ((vaddr + cache_max_sync_size) & ~(cache_max_sync_size - 1)) - vaddr;
|
||||
if (this_size > size) {
|
||||
this_size = size;
|
||||
}
|
||||
s_cache_sync_items_twice(CACHE_SYNC_WRITEBACK_INVALIDATE, vaddr, this_size);
|
||||
vaddr += this_size;
|
||||
size -= this_size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
void Cache_WriteBack_All(void)
|
||||
{
|
||||
s_cache_sync_items_twice(CACHE_SYNC_WRITEBACK, 0, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
void Cache_WriteBack_Invalidate_All(void)
|
||||
{
|
||||
s_cache_sync_items_twice(CACHE_SYNC_WRITEBACK_INVALIDATE, 0, 0);
|
||||
}
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5
|
||||
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;
|
||||
}
|
||||
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
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));
|
||||
}
|
||||
#endif
|
||||
|
||||
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));
|
||||
}
|
||||
#endif
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_rom_caps.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/cache_reg.h"
|
||||
#include "soc/cache_struct.h"
|
||||
#include "soc/ext_mem_defs.h"
|
||||
#include "hal/assert.h"
|
||||
#include "esp32c61/rom/cache.h"
|
||||
|
||||
#include "esp_rom_sys.h"
|
||||
|
||||
#define CACHE_MAX_SYNC_NUM ((CACHE_SYNC_SIZE + 1) >> 1)
|
||||
|
||||
/**
|
||||
* @brief Sync Cache items
|
||||
*
|
||||
* @param type sync type
|
||||
* @param addr address
|
||||
* @param bytes bytes to be synced
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void s_cache_sync_items(uint32_t type, uint32_t addr, uint32_t bytes)
|
||||
{
|
||||
REG_WRITE(CACHE_SYNC_ADDR_REG, addr);
|
||||
REG_SET_FIELD(CACHE_SYNC_SIZE_REG, CACHE_SYNC_SIZE, bytes);
|
||||
REG_SET_BIT(CACHE_SYNC_CTRL_REG, type);
|
||||
while (!REG_GET_BIT(CACHE_SYNC_CTRL_REG, CACHE_SYNC_DONE))
|
||||
;
|
||||
}
|
||||
|
||||
int Cache_Invalidate_Addr(uint32_t vaddr, uint32_t size)
|
||||
{
|
||||
uint32_t plus = 0;
|
||||
uint32_t cache_line_size = 32;
|
||||
uint32_t cache_max_sync_size = CACHE_MAX_SYNC_NUM;
|
||||
if (size == 0) {
|
||||
HAL_ASSERT(false);
|
||||
}
|
||||
//aligned start address to cache line size
|
||||
plus = vaddr & (cache_line_size - 1);
|
||||
vaddr -= plus;
|
||||
//make the length fit the start address
|
||||
size += plus;
|
||||
//aligned the length to cache line size(0->0)
|
||||
size = (size + cache_line_size - 1) & ~(cache_line_size - 1);
|
||||
|
||||
while (size > 0) {
|
||||
//aligned to cache_max_sync_size, (0->cache_max_sync_size)
|
||||
uint32_t this_size = ((vaddr + cache_max_sync_size) & ~(cache_max_sync_size - 1)) - vaddr;
|
||||
if (this_size > size) {
|
||||
this_size = size;
|
||||
}
|
||||
s_cache_sync_items(CACHE_SYNC_INVALIDATE, vaddr, this_size);
|
||||
vaddr += this_size;
|
||||
size -= this_size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Cache_WriteBack_Addr(uint32_t vaddr, uint32_t size)
|
||||
{
|
||||
uint32_t plus = 0;
|
||||
uint32_t cache_line_size = 32;
|
||||
uint32_t cache_max_sync_size = CACHE_MAX_SYNC_NUM;
|
||||
if (size == 0) {
|
||||
HAL_ASSERT(false);
|
||||
}
|
||||
//aligned start address to cache line size
|
||||
plus = vaddr & (cache_line_size - 1);
|
||||
vaddr -= plus;
|
||||
//make the length fit the start address
|
||||
size += plus;
|
||||
//aligned the length to cache line size(0->0)
|
||||
size = (size + cache_line_size - 1) & ~(cache_line_size - 1);
|
||||
|
||||
while (size > 0) {
|
||||
//aligned to cache_max_sync_size, (0->cache_max_sync_size)
|
||||
uint32_t this_size = ((vaddr + cache_max_sync_size) & ~(cache_max_sync_size - 1)) - vaddr;
|
||||
if (this_size > size) {
|
||||
this_size = size;
|
||||
}
|
||||
s_cache_sync_items(CACHE_SYNC_WRITEBACK, vaddr, this_size);
|
||||
vaddr += this_size;
|
||||
size -= this_size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
137
components/esp_rom/patches/esp_rom_cache_writeback_esp32p4.c
Normal file
137
components/esp_rom/patches/esp_rom_cache_writeback_esp32p4.c
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* 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 map 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;
|
||||
}
|
||||
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user