diff --git a/components/hal/cache_hal.c b/components/hal/cache_hal.c index f567cf9340..c2ab573dcd 100644 --- a/components/hal/cache_hal.c +++ b/components/hal/cache_hal.c @@ -35,19 +35,19 @@ * #define INST_AUTOLOAD_FLAG BIT(2) */ #if CONFIG_IDF_TARGET_ESP32P4 //TODO: IDF-7516 -#define DATA_AUTOLOAD_FLAG Cache_Disable_L2_Cache() -#define INST_AUTOLOAD_FLAG Cache_Disable_L2_Cache() +#define DATA_AUTOLOAD_ENABLE Cache_Disable_L2_Cache() +#define INST_AUTOLOAD_ENABLE Cache_Disable_L2_Cache() #else -#define DATA_AUTOLOAD_FLAG Cache_Disable_ICache() -#define INST_AUTOLOAD_FLAG Cache_Disable_ICache() +#define DATA_AUTOLOAD_ENABLE cache_ll_is_cache_autoload_enabled(CACHE_TYPE_DATA) +#define INST_AUTOLOAD_ENABLE cache_ll_is_cache_autoload_enabled(CACHE_TYPE_INSTRUCTION) #endif /** * Necessary hal contexts, could be maintained by upper layer in the future */ typedef struct { - uint32_t data_autoload_flag; - uint32_t inst_autoload_flag; + bool data_autoload_en; + bool inst_autoload_en; #if CACHE_LL_ENABLE_DISABLE_STATE_SW // There's no register indicating if cache is enabled on these chips, use sw flag to save this state. volatile bool cache_enabled; @@ -58,23 +58,16 @@ static cache_hal_context_t ctx; void cache_hal_init(void) { -#if SOC_SHARED_IDCACHE_SUPPORTED - ctx.data_autoload_flag = INST_AUTOLOAD_FLAG; -#if CONFIG_IDF_TARGET_ESP32P4 - Cache_Enable_L2_Cache(ctx.data_autoload_flag); + ctx.data_autoload_en = DATA_AUTOLOAD_ENABLE; + ctx.inst_autoload_en = INST_AUTOLOAD_ENABLE; +#if SOC_CACHE_L2_SUPPORTED + Cache_Enable_L2_Cache(ctx.inst_autoload_en); #else - Cache_Enable_ICache(ctx.data_autoload_flag); -#endif -#else - ctx.data_autoload_flag = DATA_AUTOLOAD_FLAG; - Cache_Enable_DCache(ctx.data_autoload_flag); - ctx.inst_autoload_flag = INST_AUTOLOAD_FLAG; - Cache_Enable_ICache(ctx.inst_autoload_flag); -#endif + cache_ll_enable_cache(CACHE_TYPE_ALL, ctx.inst_autoload_en, ctx.data_autoload_en); +#endif //SOC_CACHE_L2_SUPPORTED cache_ll_l1_enable_bus(0, CACHE_LL_DEFAULT_DBUS_MASK); cache_ll_l1_enable_bus(0, CACHE_LL_DEFAULT_IBUS_MASK); - #if !CONFIG_FREERTOS_UNICORE cache_ll_l1_enable_bus(1, CACHE_LL_DEFAULT_DBUS_MASK); cache_ll_l1_enable_bus(1, CACHE_LL_DEFAULT_IBUS_MASK); @@ -87,22 +80,11 @@ void cache_hal_init(void) void cache_hal_disable(cache_type_t type) { -#if SOC_SHARED_IDCACHE_SUPPORTED -#if CONFIG_IDF_TARGET_ESP32P4 +#if SOC_CACHE_L2_SUPPORTED Cache_Disable_L2_Cache(); #else - Cache_Disable_ICache(); -#endif -#else - if (type == CACHE_TYPE_DATA) { - Cache_Disable_DCache(); - } else if (type == CACHE_TYPE_INSTRUCTION) { - Cache_Disable_ICache(); - } else { - Cache_Disable_ICache(); - Cache_Disable_DCache(); - } -#endif + cache_ll_disable_cache(type); +#endif //SOC_CACHE_L2_SUPPORTED #if CACHE_LL_ENABLE_DISABLE_STATE_SW ctx.cache_enabled = 0; @@ -111,22 +93,11 @@ void cache_hal_disable(cache_type_t type) void cache_hal_enable(cache_type_t type) { -#if SOC_SHARED_IDCACHE_SUPPORTED -#if CONFIG_IDF_TARGET_ESP32P4 - Cache_Enable_L2_Cache(ctx.inst_autoload_flag); +#if SOC_CACHE_L2_SUPPORTED + Cache_Enable_L2_Cache(ctx.inst_autoload_en); #else - Cache_Enable_ICache(ctx.inst_autoload_flag); -#endif -#else - if (type == CACHE_TYPE_DATA) { - Cache_Enable_DCache(ctx.data_autoload_flag); - } else if (type == CACHE_TYPE_INSTRUCTION) { - Cache_Enable_ICache(ctx.inst_autoload_flag); - } else { - Cache_Enable_ICache(ctx.inst_autoload_flag); - Cache_Enable_DCache(ctx.data_autoload_flag); - } -#endif + cache_ll_enable_cache(type, ctx.inst_autoload_en, ctx.data_autoload_en); +#endif //SOC_CACHE_L2_SUPPORTED #if CACHE_LL_ENABLE_DISABLE_STATE_SW ctx.cache_enabled = 1; @@ -137,18 +108,9 @@ void cache_hal_suspend(cache_type_t type) { #if SOC_CACHE_L2_SUPPORTED Cache_Suspend_L2_Cache(); -#elif SOC_SHARED_IDCACHE_SUPPORTED - Cache_Suspend_ICache(); #else - if (type == CACHE_TYPE_DATA) { - Cache_Suspend_DCache(); - } else if (type == CACHE_TYPE_INSTRUCTION) { - Cache_Suspend_ICache(); - } else { - Cache_Suspend_ICache(); - Cache_Suspend_DCache(); - } -#endif + cache_ll_suspend_cache(type); +#endif //SOC_CACHE_L2_SUPPORTED #if CACHE_LL_ENABLE_DISABLE_STATE_SW ctx.cache_enabled = 0; @@ -158,18 +120,9 @@ void cache_hal_suspend(cache_type_t type) void cache_hal_resume(cache_type_t type) { #if SOC_CACHE_L2_SUPPORTED - Cache_Resume_L2_Cache(ctx.inst_autoload_flag); -#elif SOC_SHARED_IDCACHE_SUPPORTED - Cache_Resume_ICache(ctx.inst_autoload_flag); + Cache_Resume_L2_Cache(ctx.inst_autoload_en); #else - if (type == CACHE_TYPE_DATA) { - Cache_Resume_DCache(ctx.data_autoload_flag); - } else if (type == CACHE_TYPE_INSTRUCTION) { - Cache_Resume_ICache(ctx.inst_autoload_flag); - } else { - Cache_Resume_ICache(ctx.inst_autoload_flag); - Cache_Resume_DCache(ctx.data_autoload_flag); - } + cache_ll_resume_cache(type, ctx.inst_autoload_en, ctx.data_autoload_en); #endif #if CACHE_LL_ENABLE_DISABLE_STATE_SW @@ -179,11 +132,13 @@ void cache_hal_resume(cache_type_t type) bool cache_hal_is_cache_enabled(cache_type_t type) { + bool enabled; #if CACHE_LL_ENABLE_DISABLE_STATE_SW - return ctx.cache_enabled; + enabled = ctx.cache_enabled; #else - return cache_ll_l1_is_cache_enabled(0, type); -#endif + enabled = cache_ll_is_cache_enabled(type); +#endif //CACHE_LL_ENABLE_DISABLE_STATE_SW + return enabled; } void cache_hal_invalidate_addr(uint32_t vaddr, uint32_t size) @@ -193,7 +148,7 @@ void cache_hal_invalidate_addr(uint32_t vaddr, uint32_t size) #if CONFIG_IDF_TARGET_ESP32P4 Cache_Invalidate_Addr(CACHE_MAP_L1_DCACHE | CACHE_MAP_L2_CACHE, vaddr, size); #else - Cache_Invalidate_Addr(vaddr, size); + cache_ll_invalidate_addr(vaddr, size); #endif } @@ -205,7 +160,7 @@ void cache_hal_writeback_addr(uint32_t vaddr, uint32_t size) Cache_WriteBack_Addr(CACHE_MAP_L1_DCACHE, vaddr, size); Cache_WriteBack_Addr(CACHE_MAP_L2_CACHE, vaddr, size); #else - Cache_WriteBack_Addr(vaddr, size); + cache_ll_writeback_addr(vaddr, size); #endif } #endif //#if SOC_CACHE_WRITEBACK_SUPPORTED @@ -214,62 +169,30 @@ void cache_hal_writeback_addr(uint32_t vaddr, uint32_t size) #if SOC_CACHE_FREEZE_SUPPORTED void cache_hal_freeze(cache_type_t type) { -#if SOC_SHARED_IDCACHE_SUPPORTED -#if CONFIG_IDF_TARGET_ESP32P4 +#if SOC_CACHE_L2_SUPPORTED Cache_Freeze_L2_Cache_Enable(CACHE_FREEZE_ACK_BUSY); #else - Cache_Freeze_ICache_Enable(CACHE_FREEZE_ACK_BUSY); -#endif -#else - if (type == CACHE_TYPE_DATA) { - Cache_Freeze_DCache_Enable(CACHE_FREEZE_ACK_BUSY); - } else if (type == CACHE_TYPE_INSTRUCTION) { - Cache_Freeze_ICache_Enable(CACHE_FREEZE_ACK_BUSY); - } else { - Cache_Freeze_ICache_Enable(CACHE_FREEZE_ACK_BUSY); - Cache_Freeze_DCache_Enable(CACHE_FREEZE_ACK_BUSY); - } -#endif + cache_ll_freeze_cache(type); +#endif //SOC_CACHE_L2_SUPPORTED } void cache_hal_unfreeze(cache_type_t type) { -#if SOC_SHARED_IDCACHE_SUPPORTED -#if CONFIG_IDF_TARGET_ESP32P4 +#if SOC_CACHE_L2_SUPPORTED Cache_Freeze_L2_Cache_Disable(); #else - Cache_Freeze_ICache_Disable(); -#endif -#else - if (type == CACHE_TYPE_DATA) { - Cache_Freeze_DCache_Disable(); - } else if (type == CACHE_TYPE_INSTRUCTION) { - Cache_Freeze_ICache_Disable(); - } else { - Cache_Freeze_DCache_Disable(); - Cache_Freeze_ICache_Disable(); - } -#endif + cache_ll_unfreeze_cache(type); +#endif //SOC_CACHE_L2_SUPPORTED } #endif //#if SOC_CACHE_FREEZE_SUPPORTED uint32_t cache_hal_get_cache_line_size(cache_type_t type) { -#if SOC_SHARED_IDCACHE_SUPPORTED -#if CONFIG_IDF_TARGET_ESP32P4 - return Cache_Get_L2_Cache_Line_Size(); + uint32_t line_size = 0; +#if SOC_CACHE_L2_SUPPORTED + line_size = Cache_Get_L2_Cache_Line_Size(); #else - return Cache_Get_ICache_Line_Size(); -#endif -#else - uint32_t size = 0; - if (type == CACHE_TYPE_DATA) { - size = Cache_Get_DCache_Line_Size(); - } else if (type == CACHE_TYPE_INSTRUCTION) { - size = Cache_Get_ICache_Line_Size(); - } else { - HAL_ASSERT(false); - } - return size; -#endif + line_size = cache_ll_get_line_size(type); +#endif //SOC_CACHE_L2_SUPPORTED + return line_size; } diff --git a/components/hal/esp32/cache_hal_esp32.c b/components/hal/esp32/cache_hal_esp32.c index fdfdfde6e6..2cd500775f 100644 --- a/components/hal/esp32/cache_hal_esp32.c +++ b/components/hal/esp32/cache_hal_esp32.c @@ -8,6 +8,12 @@ static uint32_t s_cache_status[2]; +/** + * On ESP32, The cache_hal_suspend()/cache_hal_resume() are replacements + * for Cache_Read_Disable()/Cache_Read_Enable() in ROM. + * There's a bug that Cache_Read_Disable requires a call to Cache_Flush + * before Cache_Read_Enable, even if cached data was not modified. + */ void cache_hal_suspend(cache_type_t type) { s_cache_status[0] = cache_ll_l1_get_enabled_bus(0); diff --git a/components/hal/esp32c2/include/hal/cache_ll.h b/components/hal/esp32c2/include/hal/cache_ll.h index dc059bd36c..5398a38ffc 100644 --- a/components/hal/esp32c2/include/hal/cache_ll.h +++ b/components/hal/esp32c2/include/hal/cache_ll.h @@ -13,6 +13,7 @@ #include "soc/ext_mem_defs.h" #include "hal/cache_types.h" #include "hal/assert.h" +#include "esp32c2/rom/cache.h" #ifdef __cplusplus extern "C" { @@ -35,19 +36,118 @@ extern "C" { #define CACHE_LL_L1_ILG_EVENT_PRELOAD_OP_FAULT (1<<1) #define CACHE_LL_L1_ILG_EVENT_SYNC_OP_FAULT (1<<0) +//On ESP32C2, the auto preload flag is always 0 +#define CACHE_LL_L1_ICACHE_AUTOLOAD 0 + /** - * @brief Get the status of cache if it is enabled or not + * @brief Check if Cache auto preload is enabled or not. On ESP32C2, instructions and data share Cache * - * @param cache_id cache ID (when l1 cache is per core) - * @param type see `cache_type_t` - * @return enabled or not + * @param type see `cache_type_t` + * + * @return false (On ESP32C2, it's always false) */ __attribute__((always_inline)) -static inline bool cache_ll_l1_is_cache_enabled(uint32_t cache_id, cache_type_t type) +static inline bool cache_ll_is_cache_autoload_enabled(cache_type_t type) { - HAL_ASSERT(cache_id == 0); - (void) type; // On C2 there's only ICache - return REG_GET_BIT(EXTMEM_ICACHE_CTRL_REG, EXTMEM_ICACHE_ENABLE); + bool enabled = false; + return enabled; +} + +/** + * @brief Disable Cache. On ESP32C2, instructions and data share Cache + * + * @param type see `cache_type_t` + */ +__attribute__((always_inline)) +static inline void cache_ll_disable_cache(cache_type_t type) +{ + (void) type; + Cache_Disable_ICache(); +} + +/** + * @brief Enable Cache. On ESP32C2, instructions and data share Cache + * + * @param type see `cache_type_t` + * + * @param data_autoload_en Dcache auto preload enabled + * + * @param inst_autoload_en Icache auto preload enabled + */ +__attribute__((always_inline)) +static inline void cache_ll_enable_cache(cache_type_t type, bool inst_autoload_en, bool data_autoload_en) +{ + Cache_Enable_ICache(CACHE_LL_L1_ICACHE_AUTOLOAD); +} + +/** + * @brief Suspend Cache. On ESP32C2, instructions and data share Cache + * + * @param type see `cache_type_t` + */ +__attribute__((always_inline)) +static inline void cache_ll_suspend_cache(cache_type_t type) +{ + Cache_Suspend_ICache(); +} + +/** + * @brief Resume Cache. On ESP32C2, instructions and data share Cache + * + * @param type see `cache_type_t` + * + * @param data_autoload_en Dcache auto preload enabled + * + * @param inst_autoload_en Icache auto preload enabled + */ +__attribute__((always_inline)) +static inline void cache_ll_resume_cache(cache_type_t type, bool inst_autoload_en, bool data_autoload_en) +{ + Cache_Resume_ICache(CACHE_LL_L1_ICACHE_AUTOLOAD); +} + +/** + * @brief Check if Cache is enabled or not. On ESP32C2, instructions and data share Cache + * + * @param type see `cache_type_t` + * + * @return true: enabled; false: disabled + */ +__attribute__((always_inline)) +static inline bool cache_ll_is_cache_enabled(cache_type_t type) +{ + bool enabled = false; + enabled = REG_GET_BIT(EXTMEM_ICACHE_CTRL_REG, EXTMEM_ICACHE_ENABLE); + return enabled; +} + +/** + * @brief Invalidate cache supported addr + * + * Invalidate a Cache item + * + * @param vaddr Start address of the region to be invalidated + * @param size Size of the region to be invalidated + */ +__attribute__((always_inline)) +static inline void cache_ll_invalidate_addr(uint32_t vaddr, uint32_t size) +{ + Cache_Invalidate_Addr(vaddr, size); +} + +/** + * @brief Get Cache line size, in bytes + * + * @param type see `cache_type_t` + * + * @return Cache line size, in bytes + */ +__attribute__((always_inline)) +static inline uint32_t cache_ll_get_line_size(cache_type_t type) +{ + uint32_t size = 0; + size = Cache_Get_ICache_Line_Size(); + return size; } /** diff --git a/components/hal/esp32c3/include/hal/cache_ll.h b/components/hal/esp32c3/include/hal/cache_ll.h index a2bea9ef6e..2dc5e081f8 100644 --- a/components/hal/esp32c3/include/hal/cache_ll.h +++ b/components/hal/esp32c3/include/hal/cache_ll.h @@ -13,6 +13,7 @@ #include "soc/ext_mem_defs.h" #include "hal/cache_types.h" #include "hal/assert.h" +#include "esp32c3/rom/cache.h" #ifdef __cplusplus extern "C" { @@ -35,20 +36,120 @@ extern "C" { #define CACHE_LL_L1_ILG_EVENT_PRELOAD_OP_FAULT (1<<1) #define CACHE_LL_L1_ILG_EVENT_SYNC_OP_FAULT (1<<0) +#define CACHE_LL_L1_ICACHE_AUTOLOAD (1<<2) /** - * @brief Get the status of cache if it is enabled or not + * @brief Check if Cache auto preload is enabled or not. On ESP32C3, instructions and data share Cache * - * @param cache_id cache ID (when l1 cache is per core) - * @param type see `cache_type_t` - * @return enabled or not + * @param type see `cache_type_t` + * + * @return true: enabled; false: disabled */ __attribute__((always_inline)) -static inline bool cache_ll_l1_is_cache_enabled(uint32_t cache_id, cache_type_t type) +static inline bool cache_ll_is_cache_autoload_enabled(cache_type_t type) { - HAL_ASSERT(cache_id == 0); - (void) type; // On C3 there's only ICache - return REG_GET_BIT(EXTMEM_ICACHE_CTRL_REG, EXTMEM_ICACHE_ENABLE); + bool enabled = false; + if (REG_GET_BIT(EXTMEM_ICACHE_AUTOLOAD_CTRL_REG, EXTMEM_ICACHE_AUTOLOAD_ENA)) { + enabled = true; + } + return enabled; +} + +/** + * @brief Disable Cache. On ESP32C3, instructions and data share Cache + * + * @param type see `cache_type_t` + */ +__attribute__((always_inline)) +static inline void cache_ll_disable_cache(cache_type_t type) +{ + (void) type; + Cache_Disable_ICache(); +} + +/** + * @brief Enable Cache. On ESP32C3, instructions and data share Cache + * + * @param type see `cache_type_t` + * + * @param data_autoload_en Dcache auto preload enabled + * + * @param inst_autoload_en Icache auto preload enabled + */ +__attribute__((always_inline)) +static inline void cache_ll_enable_cache(cache_type_t type, bool inst_autoload_en, bool data_autoload_en) +{ + Cache_Enable_ICache(inst_autoload_en ? CACHE_LL_L1_ICACHE_AUTOLOAD : 0); +} + +/** + * @brief Suspend Cache. On ESP32C3, instructions and data share Cache + * + * @param type see `cache_type_t` + */ +__attribute__((always_inline)) +static inline void cache_ll_suspend_cache(cache_type_t type) +{ + Cache_Suspend_ICache(); +} + +/** + * @brief Resume Cache. On ESP32C3, instructions and data share Cache + * + * @param type see `cache_type_t` + * + * @param data_autoload_en Dcache auto preload enabled + * + * @param inst_autoload_en Icache auto preload enabled + */ +__attribute__((always_inline)) +static inline void cache_ll_resume_cache(cache_type_t type, bool inst_autoload_en, bool data_autoload_en) +{ + Cache_Resume_ICache(inst_autoload_en ? CACHE_LL_L1_ICACHE_AUTOLOAD : 0); +} + +/** + * @brief Check if Cache is enabled or not. On ESP32C3, instructions and data share Cache + * + * @param type see `cache_type_t` + * + * @return true: enabled; false: disabled + */ +__attribute__((always_inline)) +static inline bool cache_ll_is_cache_enabled(cache_type_t type) +{ + bool enabled = false; + enabled = REG_GET_BIT(EXTMEM_ICACHE_CTRL_REG, EXTMEM_ICACHE_ENABLE); + return enabled; +} + +/** + * @brief Invalidate cache supported addr + * + * Invalidate a Cache + * + * @param vaddr Start address of the region to be invalidated + * @param size Size of the region to be invalidated + */ +__attribute__((always_inline)) +static inline void cache_ll_invalidate_addr(uint32_t vaddr, uint32_t size) +{ + Cache_Invalidate_Addr(vaddr, size); +} + +/** + * @brief Get Cache line size, in bytes + * + * @param type see `cache_type_t` + * + * @return Cache line size, in bytes + */ +__attribute__((always_inline)) +static inline uint32_t cache_ll_get_line_size(cache_type_t type) +{ + uint32_t size = 0; + size = Cache_Get_ICache_Line_Size(); + return size; } /** diff --git a/components/hal/esp32c6/include/hal/cache_ll.h b/components/hal/esp32c6/include/hal/cache_ll.h index 82769b32d9..aa7a21544f 100644 --- a/components/hal/esp32c6/include/hal/cache_ll.h +++ b/components/hal/esp32c6/include/hal/cache_ll.h @@ -8,10 +8,12 @@ #pragma once +#include #include "soc/extmem_reg.h" #include "soc/ext_mem_defs.h" #include "hal/cache_types.h" #include "hal/assert.h" +#include "esp32c6/rom/cache.h" #ifdef __cplusplus extern "C" { @@ -24,6 +26,128 @@ extern "C" { #define CACHE_LL_L1_ACCESS_EVENT_MASK (1<<4) #define CACHE_LL_L1_ACCESS_EVENT_CACHE_FAIL (1<<4) +#define CACHE_LL_L1_ICACHE_AUTOLOAD (1<<0) + +/** + * @brief Check if Cache auto preload is enabled or not. On ESP32C6, instructions and data share Cache + * + * @param type see `cache_type_t` + * + * @return true: enabled; false: disabled + */ +__attribute__((always_inline)) +static inline bool cache_ll_is_cache_autoload_enabled(cache_type_t type) +{ + bool enabled = false; + if (REG_GET_BIT(EXTMEM_L1_CACHE_AUTOLOAD_CTRL_REG, EXTMEM_L1_CACHE_AUTOLOAD_ENA)) { + enabled = true; + } + return enabled; +} + +/** + * @brief Disable Cache. On ESP32C6, instructions and data share Cache + * + * @param type see `cache_type_t` + */ +__attribute__((always_inline)) +static inline void cache_ll_disable_cache(cache_type_t type) +{ + (void) type; + Cache_Disable_ICache(); +} + +/** + * @brief Enable Cache. On ESP32C6, instructions and data share Cache + * + * @param type see `cache_type_t` + * + * @param data_autoload_en Dcache auto preload enabled + * + * @param inst_autoload_en Icache auto preload enabled + */ +__attribute__((always_inline)) +static inline void cache_ll_enable_cache(cache_type_t type, bool inst_autoload_en, bool data_autoload_en) +{ + Cache_Enable_ICache(inst_autoload_en ? CACHE_LL_L1_ICACHE_AUTOLOAD : 0); +} + +/** + * @brief Suspend Cache. On ESP32C6, instructions and data share Cache + * + * @param type see `cache_type_t` + */ +__attribute__((always_inline)) +static inline void cache_ll_suspend_cache(cache_type_t type) +{ + Cache_Suspend_ICache(); +} + +/** + * @brief Resume Cache. On ESP326, instructions and data share Cache + * + * @param type see `cache_type_t` + * + * @param data_autoload_en Dcache auto preload enabled + * + * @param inst_autoload_en Icache auto preload enabled + */ +__attribute__((always_inline)) +static inline void cache_ll_resume_cache(cache_type_t type, bool inst_autoload_en, bool data_autoload_en) +{ + Cache_Resume_ICache(inst_autoload_en ? CACHE_LL_L1_ICACHE_AUTOLOAD : 0); +} + +/** + * @brief Invalidate cache supported addr + * + * Invalidate a Cache item + * + * @param vaddr Start address of the region to be invalidated + * @param size Size of the region to be invalidated + */ +__attribute__((always_inline)) +static inline void cache_ll_invalidate_addr(uint32_t vaddr, uint32_t size) +{ + Cache_Invalidate_Addr(vaddr, size); +} + +/** + * @brief Freeze Cache. On ESP32C6, instructions and data share Cache + * + * @param type see `cache_type_t` + */ +__attribute__((always_inline)) +static inline void cache_ll_freeze_cache(cache_type_t type) +{ + Cache_Freeze_ICache_Enable(CACHE_FREEZE_ACK_BUSY); +} + +/** + * @brief Unfreeze Cache. On ESP32C6, instructions and data share Cache + * + * @param type see `cache_type_t` + */ +__attribute__((always_inline)) +static inline void cache_ll_unfreeze_cache(cache_type_t type) +{ + Cache_Freeze_ICache_Disable(); +} + +/** + * @brief Get cache line size, in bytes + * + * @param type see `cache_type_t` + * + * @return cache line size, in bytes + */ +__attribute__((always_inline)) +static inline uint32_t cache_ll_get_line_size(cache_type_t type) +{ + uint32_t size = 0; + size = Cache_Get_ICache_Line_Size(); + return size; +} /** * @brief Get the buses of a particular cache that are mapped to a virtual address range diff --git a/components/hal/esp32h2/include/hal/cache_ll.h b/components/hal/esp32h2/include/hal/cache_ll.h index 88d7dbbd0c..dfc161de5c 100644 --- a/components/hal/esp32h2/include/hal/cache_ll.h +++ b/components/hal/esp32h2/include/hal/cache_ll.h @@ -8,10 +8,12 @@ #pragma once +#include #include "soc/extmem_reg.h" #include "soc/ext_mem_defs.h" #include "hal/cache_types.h" #include "hal/assert.h" +#include "esp32h2/rom/cache.h" #ifdef __cplusplus extern "C" { @@ -24,6 +26,128 @@ extern "C" { #define CACHE_LL_L1_ACCESS_EVENT_MASK (1<<4) #define CACHE_LL_L1_ACCESS_EVENT_CACHE_FAIL (1<<4) +#define CACHE_LL_L1_ICACHE_AUTOLOAD (1<<0) + +/** + * @brief Check if Cache auto preload is enabled or not. On ESP32h2, instructions and data share Cache + * + * @param type see `cache_type_t` + * + * @return true: enabled; false: disabled + */ +__attribute__((always_inline)) +static inline bool cache_ll_is_cache_autoload_enabled(cache_type_t type) +{ + bool enabled = false; + if (REG_GET_BIT(CACHE_L1_CACHE_AUTOLOAD_CTRL_REG, CACHE_L1_CACHE_AUTOLOAD_ENA)) { + enabled = true; + } + return enabled; +} + +/** + * @brief Disable Cache. On ESP32H2, instructions and data share Cache + * + * @param type see `cache_type_t` + */ +__attribute__((always_inline)) +static inline void cache_ll_disable_cache(cache_type_t type) +{ + (void) type; + Cache_Disable_ICache(); +} + +/** + * @brief Enable Cache. On ESP32H2, instructions and data share Cache + * + * @param type see `cache_type_t` + * + * @param data_autoload_en Dcache auto preload enabled + * + * @param inst_autoload_en Icache auto preload enabled + */ +__attribute__((always_inline)) +static inline void cache_ll_enable_cache(cache_type_t type, bool inst_autoload_en, bool data_autoload_en) +{ + Cache_Enable_ICache(inst_autoload_en ? CACHE_LL_L1_ICACHE_AUTOLOAD : 0); +} + +/** + * @brief Suspend Cache. On ESP32H2, instructions and data share Cache + * + * @param type see `cache_type_t` + */ +__attribute__((always_inline)) +static inline void cache_ll_suspend_cache(cache_type_t type) +{ + Cache_Suspend_ICache(); +} + +/** + * @brief Resume Cache. On ESP326, instructions and data share Cache + * + * @param type see `cache_type_t` + * + * @param data_autoload_en Dcache auto preload enabled + * + * @param inst_autoload_en Icache auto preload enabled + */ +__attribute__((always_inline)) +static inline void cache_ll_resume_cache(cache_type_t type, bool inst_autoload_en, bool data_autoload_en) +{ + Cache_Resume_ICache(inst_autoload_en ? CACHE_LL_L1_ICACHE_AUTOLOAD : 0); +} + +/** + * @brief Invalidate cache supported addr + * + * Invalidate a Cache item + * + * @param vaddr Start address of the region to be invalidated + * @param size Size of the region to be invalidated + */ +__attribute__((always_inline)) +static inline void cache_ll_invalidate_addr(uint32_t vaddr, uint32_t size) +{ + Cache_Invalidate_Addr(vaddr, size); +} + +/** + * @brief Freeze Cache. On ESP32H2, instructions and data share Cache + * + * @param type see `cache_type_t` + */ +__attribute__((always_inline)) +static inline void cache_ll_freeze_cache(cache_type_t type) +{ + Cache_Freeze_ICache_Enable(CACHE_FREEZE_ACK_BUSY); +} + +/** + * @brief Unfreeze Cache. On ESP32H2, instructions and data share Cache + * + * @param type see `cache_type_t` + */ +__attribute__((always_inline)) +static inline void cache_ll_unfreeze_cache(cache_type_t type) +{ + Cache_Freeze_ICache_Disable(); +} + +/** + * @brief Get cache line size, in bytes + * + * @param type see `cache_type_t` + * + * @return cache line size, in bytes + */ +__attribute__((always_inline)) +static inline uint32_t cache_ll_get_line_size(cache_type_t type) +{ + uint32_t size = 0; + size = Cache_Get_ICache_Line_Size(); + return size; +} /** * @brief Get the buses of a particular cache that are mapped to a virtual address range diff --git a/components/hal/esp32s2/include/hal/cache_ll.h b/components/hal/esp32s2/include/hal/cache_ll.h index 73db4611f2..4306f3098a 100644 --- a/components/hal/esp32s2/include/hal/cache_ll.h +++ b/components/hal/esp32s2/include/hal/cache_ll.h @@ -13,6 +13,7 @@ #include "soc/ext_mem_defs.h" #include "hal/cache_types.h" #include "hal/assert.h" +#include "esp32s2/rom/cache.h" #ifdef __cplusplus extern "C" { @@ -22,30 +23,384 @@ extern "C" { #define CACHE_LL_DEFAULT_IBUS_MASK CACHE_BUS_IBUS0 #define CACHE_LL_DEFAULT_DBUS_MASK CACHE_BUS_IBUS2 +#define CACHE_LL_L1_ICACHE_AUTOLOAD (1<<0) +#define CACHE_LL_L1_DCACHE_AUTOLOAD (1<<0) + /** - * @brief Get the status of cache if it is enabled or not + * @brief Check if ICache auto preload is enabled or not * - * @param cache_id cache ID (when l1 cache is per core) - * @param type see `cache_type_t` - * @return enabled or not + * @return true: enabled; false: disabled +*/ +__attribute__((always_inline)) +static inline bool cache_ll_l1_is_icache_autoload_enabled(void) +{ + bool enabled = false; + if (REG_GET_BIT(EXTMEM_PRO_ICACHE_CTRL_REG, EXTMEM_PRO_ICACHE_AUTOLOAD_ENA)) { + enabled = true; + } + return enabled; +} + +/** + * @brief Check if DCache auto preload is enabled or not + * + * @return true: enabled; false: disabled */ __attribute__((always_inline)) -static inline bool cache_ll_l1_is_cache_enabled(uint32_t cache_id, cache_type_t type) +static inline bool cache_ll_l1_is_dcache_autoload_enabled(void) +{ + bool enabled = false; + if (REG_GET_BIT(EXTMEM_PRO_DCACHE_CTRL_REG, EXTMEM_PRO_DCACHE_AUTOLOAD_ENA)) { + enabled = true; + } + return enabled; +} + +/** + * @brief Check if ICache or DCache auto preload is enabled or not + * + * @param type see `cache_type_t` + * + * @return true: enabled; false: disabled + */ +__attribute__((always_inline)) +static inline bool cache_ll_is_cache_autoload_enabled(cache_type_t type) +{ + bool enabled = false; + switch (type) + { + case CACHE_TYPE_INSTRUCTION: + enabled = cache_ll_l1_is_icache_autoload_enabled(); + break; + case CACHE_TYPE_DATA: + enabled = cache_ll_l1_is_dcache_autoload_enabled(); + break; + default: //CACHE_TYPE_ALL + enabled = cache_ll_l1_is_icache_autoload_enabled() && cache_ll_l1_is_dcache_autoload_enabled(); + break; + } + return enabled; +} + +/** + * @brief Disable ICache + */ +__attribute__((always_inline)) +static inline void cache_ll_l1_disable_icache(void) +{ + Cache_Disable_ICache(); +} + +/** + * @brief Disable DCache + */ +__attribute__((always_inline)) +static inline void cache_ll_l1_disable_dcache(void) +{ + Cache_Disable_DCache(); +} + +/** + * @brief Disable ICache or DCache or both + * + * @param type see `cache_type_t` + */ +__attribute__((always_inline)) +static inline void cache_ll_disable_cache(cache_type_t type) +{ + switch (type) + { + case CACHE_TYPE_INSTRUCTION: + cache_ll_l1_disable_icache(); + break; + case CACHE_TYPE_DATA: + cache_ll_l1_disable_dcache(); + break; + default: //CACHE_TYPE_ALL + cache_ll_l1_disable_icache(); + cache_ll_l1_disable_dcache(); + break; + } +} + +/** + * @brief Enable ICache + * + * @param inst_autoload_en ICache auto preload enabled + */ +__attribute__((always_inline)) +static inline void cache_ll_l1_enable_icache(bool inst_autoload_en) +{ + Cache_Enable_ICache(inst_autoload_en ? CACHE_LL_L1_ICACHE_AUTOLOAD : 0); +} + +/** + * @brief Enable DCache + * + * @param data_autoload_en DCache auto preload enabled + */ +__attribute__((always_inline)) +static inline void cache_ll_l1_enable_dcache(bool data_autoload_en) +{ + Cache_Enable_DCache(data_autoload_en ? CACHE_LL_L1_DCACHE_AUTOLOAD : 0); +} + +/** + * @brief Enable ICache or DCache or both + * + * @param type see `cache_type_t` + * + * @param data_autoload_en Dcache auto preload enabled + * + * @param inst_autoload_en Icache auto preload enabled + */ +__attribute__((always_inline)) +static inline void cache_ll_enable_cache(cache_type_t type, bool inst_autoload_en, bool data_autoload_en) +{ + switch (type) + { + case CACHE_TYPE_INSTRUCTION: + cache_ll_l1_enable_icache(inst_autoload_en); + break; + case CACHE_TYPE_DATA: + cache_ll_l1_enable_dcache(data_autoload_en); + break; + default: //CACHE_TYPE_ALL + cache_ll_l1_enable_icache(inst_autoload_en); + cache_ll_l1_enable_dcache(data_autoload_en); + break; + } +} + +/** + * @brief Suspend ICache + */ +__attribute__((always_inline)) +static inline void cache_ll_l1_suspend_icache(void) +{ + Cache_Suspend_ICache(); +} + +/** + * @brief Suspend DCache + */ +__attribute__((always_inline)) +static inline void cache_ll_l1_suspend_dcache(void) +{ + Cache_Suspend_DCache(); +} + +/** + * @brief Suspend ICache or DCache or both + * + * @param type see `cache_type_t` + */ +__attribute__((always_inline)) +static inline void cache_ll_suspend_cache(cache_type_t type) +{ + switch (type) + { + case CACHE_TYPE_INSTRUCTION: + cache_ll_l1_suspend_icache(); + break; + case CACHE_TYPE_DATA: + cache_ll_l1_suspend_dcache(); + break; + default: //CACHE_TYPE_ALL + cache_ll_l1_suspend_icache(); + cache_ll_l1_suspend_dcache(); + break; + } +} + +/** + * @brief Resume ICache + * + * @param inst_autoload_en ICache auto preload enabled + */ +__attribute__((always_inline)) +static inline void cache_ll_l1_resume_icache(bool inst_autoload_en) +{ + Cache_Resume_ICache(inst_autoload_en ? CACHE_LL_L1_ICACHE_AUTOLOAD : 0); +} + +/** + * @brief Resume DCache + * + * @param data_autoload_en DCache auto preload enabled + */ +__attribute__((always_inline)) +static inline void cache_ll_l1_resume_dcache(bool data_autoload_en) +{ + Cache_Resume_DCache(data_autoload_en ? CACHE_LL_L1_DCACHE_AUTOLOAD : 0); +} + +/** + * @brief Resume ICache or DCache or both + * + * @param type see `cache_type_t` + * + * @param data_autoload_en Dcache auto preload enabled + * + * @param inst_autoload_en Icache auto preload enabled + */ +__attribute__((always_inline)) +static inline void cache_ll_resume_cache(cache_type_t type, bool inst_autoload_en, bool data_autoload_en) +{ + switch (type) + { + case CACHE_TYPE_INSTRUCTION: + cache_ll_l1_resume_icache(inst_autoload_en); + break; + case CACHE_TYPE_DATA: + cache_ll_l1_resume_dcache(data_autoload_en); + break; + default: //CACHE_TYPE_ALL + cache_ll_l1_resume_icache(inst_autoload_en); + cache_ll_l1_resume_dcache(data_autoload_en); + break; + } +} + +/** + * @brief Check if ICache is enabled or not + * + * @param cache_id cache ID (when l1 cache is per core) + * + * @return true: enabled; false: disabled + */ +__attribute__((always_inline)) +static inline bool cache_ll_l1_is_icache_enabled(uint32_t cache_id){ + HAL_ASSERT(cache_id == 0); + + bool enabled; + enabled = REG_GET_BIT(EXTMEM_PRO_ICACHE_CTRL_REG, EXTMEM_PRO_ICACHE_ENABLE); + return enabled; +} + +/** + * @brief Check if DCache is enabled or not + * + * @param cache_id cache ID (when l1 cache is per core) + * + * @return true: enabled; false: disabled + */ +__attribute__((always_inline)) +static inline bool cache_ll_l1_is_dcache_enabled(uint32_t cache_id) { HAL_ASSERT(cache_id == 0); bool enabled; - if (type == CACHE_TYPE_INSTRUCTION) { - enabled = REG_GET_BIT(EXTMEM_PRO_ICACHE_CTRL_REG, EXTMEM_PRO_ICACHE_ENABLE); - } else if (type == CACHE_TYPE_DATA) { - enabled = REG_GET_BIT(EXTMEM_PRO_DCACHE_CTRL_REG, EXTMEM_PRO_DCACHE_ENABLE); - } else { - enabled = REG_GET_BIT(EXTMEM_PRO_ICACHE_CTRL_REG, EXTMEM_PRO_ICACHE_ENABLE); - enabled = enabled && REG_GET_BIT(EXTMEM_PRO_DCACHE_CTRL_REG, EXTMEM_PRO_DCACHE_ENABLE); + enabled = REG_GET_BIT(EXTMEM_PRO_DCACHE_CTRL_REG, EXTMEM_PRO_DCACHE_ENABLE); + return enabled; +} + +/** + * @brief Check if ICache or DCache or both is enabled or not + * + * @param type see `cache_type_t` + * + * @return true: enabled; false: disabled + */ +__attribute__((always_inline)) +static inline bool cache_ll_is_cache_enabled(cache_type_t type) +{ + bool enabled = false; + switch (type) + { + case CACHE_TYPE_DATA: + enabled = cache_ll_l1_is_dcache_enabled(0); + break; + case CACHE_TYPE_INSTRUCTION: + enabled = cache_ll_l1_is_icache_enabled(0); + break; + default: //CACHE_TYPE_ALL + enabled = cache_ll_l1_is_dcache_enabled(0) && cache_ll_l1_is_icache_enabled(0); + break; } return enabled; } +/** + * @brief Invalidate cache supported addr + * + * Invalidate a Cache item for either ICache or DCache. + * + * @param vaddr Start address of the region to be invalidated + * @param size Size of the region to be invalidated + */ +__attribute__((always_inline)) +static inline void cache_ll_invalidate_addr(uint32_t vaddr, uint32_t size) +{ + Cache_Invalidate_Addr(vaddr, size); +} + +/** + * @brief Writeback cache supported addr + * + * Writeback the DCache item to external memory + * + * @param vaddr Start address of the region to writeback + * @param size Size of the region to writeback + */ +__attribute__((always_inline)) +static inline void cache_ll_writeback_addr(uint32_t vaddr, uint32_t size) +{ + Cache_WriteBack_Addr(vaddr, size); +} + +/** + * @brief Get ICache line size, in bytes + * + * @return ICache line size, in bytes + */ +__attribute__((always_inline)) +static inline uint32_t cache_ll_l1_icache_get_line_size(void) +{ + uint32_t size = 0; + size = Cache_Get_ICache_Line_Size(); + return size; +} + +/** + * @brief Get DCache line size, in bytes + * + * @return DCache line size, in bytes + */ +__attribute__((always_inline)) +static inline uint32_t cache_ll_l1_dcache_get_line_size(void) +{ + uint32_t size = 0; + size = Cache_Get_DCache_Line_Size(); + return size; +} + +/** + * @brief Get ICache or DCache line size, in bytes + * + * @param type see `cache_type_t` + * + * @return ICache/DCache line size, in bytes + */ +__attribute__((always_inline)) +static inline uint32_t cache_ll_get_line_size(cache_type_t type) +{ + uint32_t size = 0; + switch (type) + { + case CACHE_TYPE_INSTRUCTION: + size = cache_ll_l1_icache_get_line_size(); + break; + case CACHE_TYPE_DATA: + size = cache_ll_l1_dcache_get_line_size(); + break; + default: //CACHE_TYPE_ALL + HAL_ASSERT(false); + break; + } + return size; +} + /** * @brief Get the buses of a particular cache that are mapped to a virtual address range * diff --git a/components/hal/esp32s3/include/hal/cache_ll.h b/components/hal/esp32s3/include/hal/cache_ll.h index a5439ca4ff..85a915c6b2 100644 --- a/components/hal/esp32s3/include/hal/cache_ll.h +++ b/components/hal/esp32s3/include/hal/cache_ll.h @@ -13,7 +13,7 @@ #include "soc/ext_mem_defs.h" #include "hal/cache_types.h" #include "hal/assert.h" - +#include "esp32s3/rom/cache.h" #ifdef __cplusplus extern "C" { @@ -38,30 +38,461 @@ extern "C" { #define CACHE_LL_L1_ILG_EVENT_ICACHE_PRELOAD_OP_FAULT (1<<1) #define CACHE_LL_L1_ILG_EVENT_ICACHE_SYNC_OP_FAULT (1<<0) -/** - * @brief Get the status of cache if it is enabled or not - * - * @param cache_id cache ID (when l1 cache is per core) - * @param type see `cache_type_t` - * @return enabled or not - */ -__attribute__((always_inline)) -static inline bool cache_ll_l1_is_cache_enabled(uint32_t cache_id, cache_type_t type) -{ - HAL_ASSERT(cache_id == 0 || cache_id == 1); +#define CACHE_LL_L1_ICACHE_AUTOLOAD (1<<2) +#define CACHE_LL_L1_DCACHE_AUTOLOAD (1<<2) - bool enabled; - if (type == CACHE_TYPE_INSTRUCTION) { - enabled = REG_GET_BIT(EXTMEM_ICACHE_CTRL_REG, EXTMEM_ICACHE_ENABLE); - } else if (type == CACHE_TYPE_DATA) { - enabled = REG_GET_BIT(EXTMEM_DCACHE_CTRL_REG, EXTMEM_DCACHE_ENABLE); - } else { - enabled = REG_GET_BIT(EXTMEM_ICACHE_CTRL_REG, EXTMEM_ICACHE_ENABLE); - enabled = enabled && REG_GET_BIT(EXTMEM_DCACHE_CTRL_REG, EXTMEM_DCACHE_ENABLE); +/** + * @brief Check if ICache auto preload is enabled or not + * + * @return true: enabled; false: disabled +*/ +__attribute__((always_inline)) +static inline bool cache_ll_l1_is_icache_autoload_enabled(void) +{ + bool enabled = false; + if (REG_GET_BIT(EXTMEM_ICACHE_AUTOLOAD_CTRL_REG, EXTMEM_ICACHE_AUTOLOAD_ENA)) { + enabled = true; } return enabled; } +/** + * @brief Check if DCache auto preload is enabled or not + * + * @return true: enabled; false: disabled + */ +__attribute__((always_inline)) +static inline bool cache_ll_l1_is_dcache_autoload_enabled(void) +{ + bool enabled = false; + if (REG_GET_BIT(EXTMEM_DCACHE_AUTOLOAD_CTRL_REG, EXTMEM_DCACHE_AUTOLOAD_ENA)) { + enabled = true; + } + return enabled; +} + +/** + * @brief Check if ICache or DCache auto preload is enabled or not + * + * @param type see `cache_type_t` + * + * @return true: enabled; false: disabled + */ +__attribute__((always_inline)) +static inline bool cache_ll_is_cache_autoload_enabled(cache_type_t type) +{ + bool enabled = false; + switch (type) + { + case CACHE_TYPE_INSTRUCTION: + enabled = cache_ll_l1_is_icache_autoload_enabled(); + break; + case CACHE_TYPE_DATA: + enabled = cache_ll_l1_is_dcache_autoload_enabled(); + break; + default: //CACHE_TYPE_ALL + enabled = cache_ll_l1_is_icache_autoload_enabled() && cache_ll_l1_is_dcache_autoload_enabled(); + break; + } + return enabled; +} + +/** + * @brief Disable ICache + */ +__attribute__((always_inline)) +static inline void cache_ll_l1_disable_icache(void) +{ + Cache_Disable_ICache(); +} + +/** + * @brief Disable DCache + */ +__attribute__((always_inline)) +static inline void cache_ll_l1_disable_dcache(void) +{ + Cache_Disable_DCache(); +} + +/** + * @brief Disable ICache or DCache or both + * + * @param type see `cache_type_t` + */ +__attribute__((always_inline)) +static inline void cache_ll_disable_cache(cache_type_t type) +{ + switch (type) + { + case CACHE_TYPE_INSTRUCTION: + cache_ll_l1_disable_icache(); + break; + case CACHE_TYPE_DATA: + cache_ll_l1_disable_dcache(); + break; + default: //CACHE_TYPE_ALL + cache_ll_l1_disable_icache(); + cache_ll_l1_disable_dcache(); + break; + } +} + +/** + * @brief Enable ICache + * + * @param inst_autoload_en ICache auto preload enabled + */ +__attribute__((always_inline)) +static inline void cache_ll_l1_enable_icache(bool inst_autoload_en) +{ + Cache_Enable_ICache(inst_autoload_en ? CACHE_LL_L1_ICACHE_AUTOLOAD : 0); +} + +/** + * @brief Enable DCache + * + * @param data_autoload_en DCache auto preload enabled + */ +__attribute__((always_inline)) +static inline void cache_ll_l1_enable_dcache(bool data_autoload_en) +{ + Cache_Enable_DCache(data_autoload_en ? CACHE_LL_L1_DCACHE_AUTOLOAD : 0); +} + +/** + * @brief Enable ICache or DCache or both + * + * @param type see `cache_type_t` + * + * @param data_autoload_en Dcache auto preload enabled + * + * @param inst_autoload_en Icache auto preload enabled + */ +__attribute__((always_inline)) +static inline void cache_ll_enable_cache(cache_type_t type, bool inst_autoload_en, bool data_autoload_en) +{ + switch (type) + { + case CACHE_TYPE_INSTRUCTION: + cache_ll_l1_enable_icache(inst_autoload_en); + break; + case CACHE_TYPE_DATA: + cache_ll_l1_enable_dcache(data_autoload_en); + break; + default: //CACHE_TYPE_ALL + cache_ll_l1_enable_icache(inst_autoload_en); + cache_ll_l1_enable_dcache(data_autoload_en); + break; + } +} + +/** + * @brief Suspend ICache + */ +__attribute__((always_inline)) +static inline void cache_ll_l1_suspend_icache(void) +{ + Cache_Suspend_ICache(); +} + +/** + * @brief Suspend DCache + */ +__attribute__((always_inline)) +static inline void cache_ll_l1_suspend_dcache(void) +{ + Cache_Suspend_DCache(); +} + +/** + * @brief Suspend ICache or DCache or both + * + * @param type see `cache_type_t` + */ +__attribute__((always_inline)) +static inline void cache_ll_suspend_cache(cache_type_t type) +{ + switch (type) + { + case CACHE_TYPE_INSTRUCTION: + cache_ll_l1_suspend_icache(); + break; + case CACHE_TYPE_DATA: + cache_ll_l1_suspend_dcache(); + break; + default: //CACHE_TYPE_ALL + cache_ll_l1_suspend_icache(); + cache_ll_l1_suspend_dcache(); + break; + } +} + +/** + * @brief Resume ICache + * + * @param inst_autoload_en ICache auto preload enabled + */ +__attribute__((always_inline)) +static inline void cache_ll_l1_resume_icache(bool inst_autoload_en) +{ + Cache_Resume_ICache(inst_autoload_en ? CACHE_LL_L1_ICACHE_AUTOLOAD : 0); +} + +/** + * @brief Resume DCache + * + * @param data_autoload_en DCache auto preload enabled + */ +__attribute__((always_inline)) +static inline void cache_ll_l1_resume_dcache(bool data_autoload_en) +{ + Cache_Resume_DCache(data_autoload_en ? CACHE_LL_L1_DCACHE_AUTOLOAD : 0); +} + +/** + * @brief Resume ICache or DCache or both + * + * @param type see `cache_type_t` + * + * @param data_autoload_en Dcache auto preload enabled + * + * @param inst_autoload_en Icache auto preload enabled + */ +__attribute__((always_inline)) +static inline void cache_ll_resume_cache(cache_type_t type, bool inst_autoload_en, bool data_autoload_en) +{ + switch (type) + { + case CACHE_TYPE_INSTRUCTION: + cache_ll_l1_resume_icache(inst_autoload_en); + break; + case CACHE_TYPE_DATA: + cache_ll_l1_resume_dcache(data_autoload_en); + break; + default: //CACHE_TYPE_ALL + cache_ll_l1_resume_icache(inst_autoload_en); + cache_ll_l1_resume_dcache(data_autoload_en); + break; + } +} + +/** + * @brief Check if ICache is enabled or not + * + * @param cache_id cache ID (when l1 cache is per core) + * + * @return true: enabled; false: disabled + */ +__attribute__((always_inline)) +static inline bool cache_ll_l1_is_icache_enabled(uint32_t cache_id) +{ + HAL_ASSERT(cache_id == 0 || cache_id == 1); + return REG_GET_BIT(EXTMEM_ICACHE_CTRL_REG, EXTMEM_ICACHE_ENABLE); +} + +/** + * @brief Check if DCache is enabled or not + * + * @param cache_id cache ID (when l1 cache is per core) + * + * @return true: enabled; false: disabled + */ +__attribute__((always_inline)) +static inline bool cache_ll_l1_is_dcache_enabled(uint32_t cache_id) +{ + HAL_ASSERT(cache_id == 0 || cache_id == 1); + return REG_GET_BIT(EXTMEM_DCACHE_CTRL_REG, EXTMEM_DCACHE_ENABLE); +} + +/** + * @brief Check if ICache or DCache or both is enabled or not + * + * @param type see `cache_type_t` + * + * @return true: enabled; false: disabled + */ +__attribute__((always_inline)) +static inline bool cache_ll_is_cache_enabled(cache_type_t type) +{ + bool enabled = false; + switch (type) + { + case CACHE_TYPE_DATA: + enabled = cache_ll_l1_is_dcache_enabled(0); + break; + case CACHE_TYPE_INSTRUCTION: + enabled = cache_ll_l1_is_icache_enabled(0); + break; + default: //CACHE_TYPE_ALL + enabled = cache_ll_l1_is_dcache_enabled(0) && cache_ll_l1_is_icache_enabled(0); + break; + } + return enabled; +} + +/** + * @brief Invalidate cache supported addr + * + * Invalidate a Cache item for either ICache or DCache. + * + * @param vaddr Start address of the region to be invalidated + * @param size Size of the region to be invalidated + */ +__attribute__((always_inline)) +static inline void cache_ll_invalidate_addr(uint32_t vaddr, uint32_t size) +{ + Cache_Invalidate_Addr(vaddr, size); +} + +/** + * @brief Writeback cache supported addr + * + * Writeback the DCache item to external memory + * + * @param vaddr Start address of the region to writeback + * @param size Size of the region to writeback + */ +__attribute__((always_inline)) +static inline void cache_ll_writeback_addr(uint32_t vaddr, uint32_t size) +{ + Cache_WriteBack_Addr(vaddr, size); +} + +/** + * @brief Freeze ICache + */ +__attribute__((always_inline)) +static inline void cache_ll_l1_freeze_icache(void) +{ + Cache_Freeze_ICache_Enable(CACHE_FREEZE_ACK_BUSY); +} + +/** + * @brief Freeze DCache + */ +__attribute__((always_inline)) +static inline void cache_ll_l1_freeze_dcache(void) +{ + Cache_Freeze_DCache_Enable(CACHE_FREEZE_ACK_BUSY); +} + +/** + * @brief Freeze ICache or DCache or both + * + * @param type see `cache_type_t` + */ +__attribute__((always_inline)) +static inline void cache_ll_freeze_cache(cache_type_t type) +{ + switch (type) + { + case CACHE_TYPE_INSTRUCTION: + cache_ll_l1_freeze_icache(); + break; + case CACHE_TYPE_DATA: + cache_ll_l1_freeze_dcache(); + break; + default: //CACHE_TYPE_ALL + cache_ll_l1_freeze_icache(); + cache_ll_l1_freeze_dcache(); + break; + } +} + +/** + * @brief Unfreeze ICache + */ +__attribute__((always_inline)) +static inline void cache_ll_l1_unfreeze_icache(void) +{ + Cache_Freeze_ICache_Disable(); +} + +/** + * @brief Unfreeze DCache + */ +__attribute__((always_inline)) +static inline void cache_ll_l1_unfreeze_dcache(void) +{ + Cache_Freeze_DCache_Disable(); +} + +/** + * @brief Unfreeze ICache or DCache or both + * + * @param type see `cache_type_t` + */ +__attribute__((always_inline)) +static inline void cache_ll_unfreeze_cache(cache_type_t type) +{ + switch (type) + { + case CACHE_TYPE_INSTRUCTION: + cache_ll_l1_unfreeze_icache(); + break; + case CACHE_TYPE_DATA: + cache_ll_l1_unfreeze_dcache(); + break; + default: //CACHE_TYPE_ALL + cache_ll_l1_unfreeze_icache(); + cache_ll_l1_unfreeze_dcache(); + break; + } +} + +/** + * @brief Get ICache line size, in bytes + * + * @return ICache line size, in bytes + */ +__attribute__((always_inline)) +static inline uint32_t cache_ll_l1_icache_get_line_size(void) +{ + uint32_t size = 0; + size = Cache_Get_ICache_Line_Size(); + return size; +} + +/** + * @brief Get DCache line size, in bytes + * + * @return DCache line size, in bytes + */ +__attribute__((always_inline)) +static inline uint32_t cache_ll_l1_dcache_get_line_size(void) +{ + uint32_t size = 0; + size = Cache_Get_DCache_Line_Size(); + return size; +} + +/** + * @brief Get ICache or DCache line size, in bytes + * + * @param type see `cache_type_t` + * + * @return ICache/DCache line size, in bytes + */ +__attribute__((always_inline)) +static inline uint32_t cache_ll_get_line_size(cache_type_t type) +{ + uint32_t size = 0; + switch (type) + { + case CACHE_TYPE_INSTRUCTION: + size = cache_ll_l1_icache_get_line_size(); + break; + case CACHE_TYPE_DATA: + size = cache_ll_l1_dcache_get_line_size(); + break; + default: //CACHE_TYPE_ALL + HAL_ASSERT(false); + break; + } + return size; +} + /** * @brief Get the buses of a particular cache that are mapped to a virtual address range * diff --git a/components/spi_flash/cache_utils.c b/components/spi_flash/cache_utils.c index f486cfb6a0..c1e7e75c76 100644 --- a/components/spi_flash/cache_utils.c +++ b/components/spi_flash/cache_utils.c @@ -358,11 +358,6 @@ void IRAM_ATTR spi_flash_enable_cache(uint32_t cpuid) #endif } -/** - * The following two functions are replacements for Cache_Read_Disable and Cache_Read_Enable - * function in ROM. They are used to work around a bug where Cache_Read_Disable requires a call to - * Cache_Flush before Cache_Read_Enable, even if cached data was not modified. - */ void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t *saved_state) { cache_hal_suspend(CACHE_TYPE_ALL);