瀏覽代碼

cache: refactor cache_utils into cache_hal instade

wanlei 2 年之前
父節點
當前提交
0f7e39d15a

+ 7 - 3
components/hal/CMakeLists.txt

@@ -20,10 +20,14 @@ endif()
 
 if(NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP)
     list(APPEND srcs "mmu_hal.c")
-endif()
 
-if(NOT ${target} STREQUAL "esp32" AND NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP)
-    list(APPEND srcs "cache_hal.c")
+    # We wrap Cache ROM APIs as Cache HAL APIs for: 1. internal ram ; 2. unified APIs
+    # ESP32 cache structure / ROM APIs are different and we have a patch `cache_hal_esp32.c` for it.
+    if(${target} STREQUAL "esp32")
+        list(APPEND srcs "esp32/cache_hal_esp32.c")
+    else()
+        list(APPEND srcs "cache_hal.c")
+    endif()
 endif()
 
 if(${target} STREQUAL "esp32c6")

+ 65 - 0
components/hal/cache_hal.c

@@ -43,6 +43,10 @@
 typedef struct {
     uint32_t data_autoload_flag;
     uint32_t inst_autoload_flag;
+#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;
+#endif
 } cache_hal_context_t;
 
 static cache_hal_context_t ctx;
@@ -66,6 +70,10 @@ void cache_hal_init(void)
     cache_ll_l1_enable_bus(1, CACHE_LL_DEFAULT_DBUS_MASK);
     cache_ll_l1_enable_bus(1, CACHE_LL_DEFAULT_IBUS_MASK);
 #endif
+
+#if CACHE_LL_ENABLE_DISABLE_STATE_SW
+    ctx.cache_enabled = 1;
+#endif
 }
 
 void cache_hal_disable(cache_type_t type)
@@ -82,6 +90,10 @@ void cache_hal_disable(cache_type_t type)
         Cache_Disable_DCache();
     }
 #endif
+
+#if CACHE_LL_ENABLE_DISABLE_STATE_SW
+    ctx.cache_enabled = 0;
+#endif
 }
 
 void cache_hal_enable(cache_type_t type)
@@ -98,6 +110,59 @@ void cache_hal_enable(cache_type_t type)
         Cache_Enable_DCache(ctx.data_autoload_flag);
     }
 #endif
+
+#if CACHE_LL_ENABLE_DISABLE_STATE_SW
+    ctx.cache_enabled = 1;
+#endif
+}
+
+void cache_hal_suspend(cache_type_t type)
+{
+#if 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
+
+#if CACHE_LL_ENABLE_DISABLE_STATE_SW
+    ctx.cache_enabled = 0;
+#endif
+}
+
+void cache_hal_resume(cache_type_t type)
+{
+#if SOC_SHARED_IDCACHE_SUPPORTED
+    Cache_Resume_ICache(ctx.inst_autoload_flag);
+#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);
+    }
+#endif
+
+#if CACHE_LL_ENABLE_DISABLE_STATE_SW
+    ctx.cache_enabled = 1;
+#endif
+}
+
+bool cache_hal_is_cache_enabled(cache_type_t type)
+{
+#if CACHE_LL_ENABLE_DISABLE_STATE_SW
+    return ctx.cache_enabled;
+#else
+    return cache_ll_l1_is_cache_enabled(0, type);
+#endif
 }
 
 void cache_hal_invalidate_addr(uint32_t vaddr, uint32_t size)

+ 40 - 0
components/hal/esp32/cache_hal_esp32.c

@@ -0,0 +1,40 @@
+/*
+ * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "hal/cache_ll.h"
+#include "hal/cache_hal.h"
+
+static uint32_t s_cache_status[2];
+
+void cache_hal_suspend(cache_type_t type)
+{
+    s_cache_status[0] = cache_ll_l1_get_enabled_bus(0);
+    cache_ll_l1_disable_cache(0);
+#if !CONFIG_FREERTOS_UNICORE
+    s_cache_status[1] = cache_ll_l1_get_enabled_bus(1);
+    cache_ll_l1_disable_cache(1);
+#endif
+}
+
+
+void cache_hal_resume(cache_type_t type)
+{
+    cache_ll_l1_enable_cache(0);
+    cache_ll_l1_enable_bus(0, s_cache_status[0]);
+#if !CONFIG_FREERTOS_UNICORE
+    cache_ll_l1_enable_cache(1);
+    cache_ll_l1_enable_bus(1, s_cache_status[1]);
+#endif
+}
+
+
+bool cache_hal_is_cache_enabled(cache_type_t type)
+{
+    bool result = cache_ll_l1_is_cache_enabled(0, CACHE_TYPE_ALL);
+#if !CONFIG_FREERTOS_UNICORE
+    result = result && cache_ll_l1_is_cache_enabled(1, CACHE_TYPE_ALL);
+#endif
+    return result;
+}

+ 60 - 0
components/hal/esp32/include/hal/cache_ll.h

@@ -19,6 +19,66 @@
 extern "C" {
 #endif
 
+/**
+ * @brief enable a cache unit
+ *
+ * @param cache_id  cache ID (when l1 cache is per core)
+ */
+__attribute__((always_inline))
+static inline void cache_ll_l1_enable_cache(uint32_t cache_id)
+{
+    HAL_ASSERT(cache_id == 0 || cache_id == 1);
+
+    if (cache_id == 0) {
+        DPORT_REG_SET_BIT(DPORT_PRO_CACHE_CTRL_REG, DPORT_PRO_CACHE_ENABLE);
+    } else {
+        DPORT_REG_SET_BIT(DPORT_APP_CACHE_CTRL_REG, DPORT_APP_CACHE_ENABLE);
+    }
+}
+
+/**
+ * @brief disable a cache unit
+ *
+ * @param cache_id  cache ID (when l1 cache is per core)
+ */
+__attribute__((always_inline))
+static inline void cache_ll_l1_disable_cache(uint32_t cache_id)
+{
+    if (cache_id == 0) {
+        while (DPORT_GET_PERI_REG_BITS2(DPORT_PRO_DCACHE_DBUG0_REG, DPORT_PRO_CACHE_STATE, DPORT_PRO_CACHE_STATE_S) != 1){
+            ;
+        }
+        DPORT_REG_CLR_BIT(DPORT_PRO_CACHE_CTRL_REG, DPORT_PRO_CACHE_ENABLE);
+    } else {
+        while (DPORT_GET_PERI_REG_BITS2(DPORT_APP_DCACHE_DBUG0_REG, DPORT_APP_CACHE_STATE, DPORT_APP_CACHE_STATE_S) != 1){
+            ;
+        }
+        DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL_REG, DPORT_APP_CACHE_ENABLE);
+    }
+}
+
+/**
+ * @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);
+    (void) type;    //On 32 it shares between I and D cache
+
+    bool enabled;
+    if (cache_id == 0) {
+        enabled = DPORT_REG_GET_BIT(DPORT_PRO_CACHE_CTRL_REG, DPORT_PRO_CACHE_ENABLE);
+    } else {
+        enabled = DPORT_REG_GET_BIT(DPORT_APP_CACHE_CTRL_REG, DPORT_APP_CACHE_ENABLE);
+    }
+    return enabled;
+}
+
 /**
  * @brief Get the buses of a particular cache that are mapped to a virtual address range
  *

+ 16 - 0
components/hal/esp32c2/include/hal/cache_ll.h

@@ -8,6 +8,7 @@
 
 #pragma once
 
+#include <stdbool.h>
 #include "soc/extmem_reg.h"
 #include "soc/ext_mem_defs.h"
 #include "hal/cache_types.h"
@@ -34,6 +35,21 @@ extern "C" {
 #define CACHE_LL_L1_ILG_EVENT_PRELOAD_OP_FAULT      (1<<1)
 #define CACHE_LL_L1_ILG_EVENT_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);
+    (void) type; // On C2 there's only ICache
+    return REG_GET_BIT(EXTMEM_ICACHE_CTRL_REG, EXTMEM_ICACHE_ENABLE);
+}
+
 /**
  * @brief Get the buses of a particular cache that are mapped to a virtual address range
  *

+ 17 - 1
components/hal/esp32c3/include/hal/cache_ll.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -8,6 +8,7 @@
 
 #pragma once
 
+#include <stdbool.h>
 #include "soc/extmem_reg.h"
 #include "soc/ext_mem_defs.h"
 #include "hal/cache_types.h"
@@ -35,6 +36,21 @@ extern "C" {
 #define CACHE_LL_L1_ILG_EVENT_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);
+    (void) type; // On C3 there's only ICache
+    return REG_GET_BIT(EXTMEM_ICACHE_CTRL_REG, EXTMEM_ICACHE_ENABLE);
+}
+
 /**
  * @brief Get the buses of a particular cache that are mapped to a virtual address range
  *

+ 1 - 1
components/hal/esp32c6/include/hal/cache_ll.h

@@ -16,7 +16,7 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
-
+#define CACHE_LL_ENABLE_DISABLE_STATE_SW            1   //There's no register indicating cache enable/disable state, we need to use software way for this state.
 
 #define CACHE_LL_DEFAULT_IBUS_MASK                  CACHE_BUS_IBUS0
 #define CACHE_LL_DEFAULT_DBUS_MASK                  CACHE_BUS_DBUS0

+ 1 - 1
components/hal/esp32h2/include/hal/cache_ll.h

@@ -16,7 +16,7 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
-
+#define CACHE_LL_ENABLE_DISABLE_STATE_SW            1   //There's no register indicating cache enable/disable state, we need to use software way for this state.
 
 #define CACHE_LL_DEFAULT_IBUS_MASK                  CACHE_BUS_IBUS0
 #define CACHE_LL_DEFAULT_DBUS_MASK                  CACHE_BUS_DBUS0

+ 23 - 0
components/hal/esp32s2/include/hal/cache_ll.h

@@ -22,6 +22,29 @@ extern "C" {
 #define CACHE_LL_DEFAULT_IBUS_MASK    CACHE_BUS_IBUS0
 #define CACHE_LL_DEFAULT_DBUS_MASK    CACHE_BUS_IBUS2
 
+/**
+ * @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);
+
+    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);
+    }
+    return enabled;
+}
 
 /**
  * @brief Get the buses of a particular cache that are mapped to a virtual address range

+ 24 - 0
components/hal/esp32s3/include/hal/cache_ll.h

@@ -8,6 +8,7 @@
 
 #pragma once
 
+#include <stdbool.h>
 #include "soc/extmem_reg.h"
 #include "soc/ext_mem_defs.h"
 #include "hal/cache_types.h"
@@ -37,6 +38,29 @@ 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);
+
+    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);
+    }
+    return enabled;
+}
 
 /**
  * @brief Get the buses of a particular cache that are mapped to a virtual address range

+ 30 - 0
components/hal/include/hal/cache_hal.h

@@ -7,6 +7,7 @@
 
 #pragma once
 
+#include <stdbool.h>
 #include "hal/cache_types.h"
 
 #ifdef __cplusplus
@@ -39,6 +40,35 @@ void cache_hal_disable(cache_type_t type);
  */
 void cache_hal_enable(cache_type_t type);
 
+/**
+ * @brief Suspend cache
+ *
+ * Suspend the ICache or DCache or both,suspends the CPU access to cache for a while, without invalidation.
+ *
+ * @param type  see `cache_type_t`
+ *
+ * @return  Current status of corresponding Cache(s)
+ */
+void cache_hal_suspend(cache_type_t type);
+
+/**
+ * @brief Resume cache
+ *
+ * Resume the ICache or DCache or both.
+ *
+ * @param type  see `cache_type_t`
+ */
+void cache_hal_resume(cache_type_t type);
+
+/**
+ * @brief Check if corresponding cache is enabled or not
+ *
+ * @param type  see `cache_type_t`
+ *
+ * @return true: enabled; false: disabled
+ */
+bool cache_hal_is_cache_enabled(cache_type_t type);
+
 /**
  * @brief Invalidate cache supported addr
  *

+ 4 - 2
components/hal/linker.lf

@@ -5,8 +5,10 @@ entries:
         mmu_hal (noflash)
         spi_flash_hal_iram (noflash)
         spi_flash_encrypt_hal_iram (noflash)
-    if IDF_TARGET_ESP32 = n && APP_BUILD_TYPE_PURE_RAM_APP = n:
-        cache_hal (noflash)
+        if IDF_TARGET_ESP32 = y:
+            cache_hal_esp32 (noflash)
+        else:
+            cache_hal (noflash)
     if SOC_GPSPI_SUPPORTED = y:
         if HAL_SPI_MASTER_FUNC_IN_IRAM = y:
             spi_hal_iram (noflash)

+ 21 - 107
components/spi_flash/cache_utils.c

@@ -41,6 +41,8 @@
 #include "soc/ext_mem_defs.h"
 #endif
 #include "esp_rom_spiflash.h"
+#include "hal/cache_hal.h"
+#include "hal/cache_ll.h"
 #include <soc/soc.h>
 #include "sdkconfig.h"
 #ifndef CONFIG_FREERTOS_UNICORE
@@ -58,18 +60,6 @@
 
 static __attribute__((unused)) const char *TAG = "cache";
 
-#define DPORT_CACHE_BIT(cpuid, regid) DPORT_ ## cpuid ## regid
-
-#define DPORT_CACHE_MASK(cpuid) (DPORT_CACHE_BIT(cpuid, _CACHE_MASK_OPSDRAM) | DPORT_CACHE_BIT(cpuid, _CACHE_MASK_DROM0) | \
-                                DPORT_CACHE_BIT(cpuid, _CACHE_MASK_DRAM1) | DPORT_CACHE_BIT(cpuid, _CACHE_MASK_IROM0) | \
-                                DPORT_CACHE_BIT(cpuid, _CACHE_MASK_IRAM1) | DPORT_CACHE_BIT(cpuid, _CACHE_MASK_IRAM0) )
-
-#define DPORT_CACHE_VAL(cpuid) (~(DPORT_CACHE_BIT(cpuid, _CACHE_MASK_DROM0) | \
-                                        DPORT_CACHE_BIT(cpuid, _CACHE_MASK_DRAM1) | \
-                                        DPORT_CACHE_BIT(cpuid, _CACHE_MASK_IRAM0)))
-
-#define DPORT_CACHE_GET_VAL(cpuid) (cpuid == 0) ? DPORT_CACHE_VAL(PRO) : DPORT_CACHE_VAL(APP)
-#define DPORT_CACHE_GET_MASK(cpuid) (cpuid == 0) ? DPORT_CACHE_MASK(PRO) : DPORT_CACHE_MASK(APP)
 
 /**
  * These two shouldn't be declared as static otherwise if `CONFIG_SPI_FLASH_ROM_IMPL` is enabled,
@@ -78,15 +68,9 @@ static __attribute__((unused)) const char *TAG = "cache";
 void spi_flash_disable_cache(uint32_t cpuid, uint32_t *saved_state);
 void spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_state);
 
+// Used only on ROM impl. in idf, this param unused, cache status hold by hal
 static uint32_t s_flash_op_cache_state[2];
 
-#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
-/* esp32c6 does not has a register indicating if cache is enabled
- * so we use s static data to store to state of cache, every time
- * disable/restore api is called, the state will be updated
- */
-static volatile DRAM_ATTR bool s_cache_enabled = 1;
-#endif
 
 #ifndef CONFIG_FREERTOS_UNICORE
 static SemaphoreHandle_t s_flash_op_mutex;
@@ -239,7 +223,7 @@ void IRAM_ATTR spi_flash_enable_interrupts_caches_and_other_cpu(void)
     s_flash_op_cpu = -1;
 #endif
 
-    // Re-enable cache on both CPUs. After this, cache (flash and external RAM) should work again.
+    // Re-enable cache. After this, cache (flash and external RAM) should work again.
     spi_flash_restore_cache(cpuid, s_flash_op_cache_state[cpuid]);
 #if SOC_IDCACHE_PER_CORE
     //only needed if cache(s) is per core
@@ -359,6 +343,19 @@ void IRAM_ATTR spi_flash_enable_interrupts_caches_no_os(void)
 
 #endif // CONFIG_FREERTOS_UNICORE
 
+
+void IRAM_ATTR spi_flash_enable_cache(uint32_t cpuid)
+{
+#if CONFIG_IDF_TARGET_ESP32
+    uint32_t cache_value = cache_ll_l1_get_enabled_bus(cpuid);
+
+    // Re-enable cache on this CPU
+    spi_flash_restore_cache(cpuid, cache_value);
+#else
+    spi_flash_restore_cache(0, 0); // TODO cache_value should be non-zero
+#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
@@ -366,87 +363,17 @@ void IRAM_ATTR spi_flash_enable_interrupts_caches_no_os(void)
  */
 void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t *saved_state)
 {
-#if CONFIG_IDF_TARGET_ESP32
-    uint32_t ret = 0;
-    const uint32_t cache_mask = DPORT_CACHE_GET_MASK(cpuid);
-    if (cpuid == 0) {
-        ret |= DPORT_GET_PERI_REG_BITS2(DPORT_PRO_CACHE_CTRL1_REG, cache_mask, 0);
-        while (DPORT_GET_PERI_REG_BITS2(DPORT_PRO_DCACHE_DBUG0_REG, DPORT_PRO_CACHE_STATE, DPORT_PRO_CACHE_STATE_S) != 1) {
-            ;
-        }
-        DPORT_SET_PERI_REG_BITS(DPORT_PRO_CACHE_CTRL_REG, 1, 0, DPORT_PRO_CACHE_ENABLE_S);
-    }
-#if !CONFIG_FREERTOS_UNICORE
-    else {
-        ret |= DPORT_GET_PERI_REG_BITS2(DPORT_APP_CACHE_CTRL1_REG, cache_mask, 0);
-        while (DPORT_GET_PERI_REG_BITS2(DPORT_APP_DCACHE_DBUG0_REG, DPORT_APP_CACHE_STATE, DPORT_APP_CACHE_STATE_S) != 1) {
-            ;
-        }
-        DPORT_SET_PERI_REG_BITS(DPORT_APP_CACHE_CTRL_REG, 1, 0, DPORT_APP_CACHE_ENABLE_S);
-    }
-#endif
-    *saved_state = ret;
-#elif CONFIG_IDF_TARGET_ESP32S2
-    *saved_state = Cache_Suspend_ICache();
-#elif CONFIG_IDF_TARGET_ESP32S3
-    uint32_t icache_state, dcache_state;
-    icache_state = Cache_Suspend_ICache() << 16;
-    dcache_state = Cache_Suspend_DCache();
-    *saved_state = icache_state | dcache_state;
-#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2
-    uint32_t icache_state;
-    icache_state = Cache_Suspend_ICache() << 16;
-    *saved_state = icache_state;
-#elif CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
-    uint32_t icache_state;
-    icache_state = Cache_Suspend_ICache();
-    *saved_state = icache_state;
-    s_cache_enabled = 0;
-#endif
+    cache_hal_suspend(CACHE_TYPE_ALL);
 }
 
 void IRAM_ATTR spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_state)
 {
-#if CONFIG_IDF_TARGET_ESP32
-    const uint32_t cache_mask = DPORT_CACHE_GET_MASK(cpuid);
-    if (cpuid == 0) {
-        DPORT_SET_PERI_REG_BITS(DPORT_PRO_CACHE_CTRL_REG, 1, 1, DPORT_PRO_CACHE_ENABLE_S);
-        DPORT_SET_PERI_REG_BITS(DPORT_PRO_CACHE_CTRL1_REG, cache_mask, saved_state, 0);
-    }
-#if !CONFIG_FREERTOS_UNICORE
-    else {
-        DPORT_SET_PERI_REG_BITS(DPORT_APP_CACHE_CTRL_REG, 1, 1, DPORT_APP_CACHE_ENABLE_S);
-        DPORT_SET_PERI_REG_BITS(DPORT_APP_CACHE_CTRL1_REG, cache_mask, saved_state, 0);
-    }
-#endif
-#elif CONFIG_IDF_TARGET_ESP32S2
-    Cache_Resume_ICache(saved_state);
-#elif CONFIG_IDF_TARGET_ESP32S3
-    Cache_Resume_DCache(saved_state & 0xffff);
-    Cache_Resume_ICache(saved_state >> 16);
-#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2
-    Cache_Resume_ICache(saved_state >> 16);
-#elif CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
-    Cache_Resume_ICache(saved_state);
-    s_cache_enabled = 1;
-#endif
+    cache_hal_resume(CACHE_TYPE_ALL);
 }
 
-IRAM_ATTR bool spi_flash_cache_enabled(void)
+bool IRAM_ATTR spi_flash_cache_enabled(void)
 {
-#if CONFIG_IDF_TARGET_ESP32
-    bool result = (DPORT_REG_GET_BIT(DPORT_PRO_CACHE_CTRL_REG, DPORT_PRO_CACHE_ENABLE) != 0);
-#if portNUM_PROCESSORS == 2
-    result = result && (DPORT_REG_GET_BIT(DPORT_APP_CACHE_CTRL_REG, DPORT_APP_CACHE_ENABLE) != 0);
-#endif
-#elif CONFIG_IDF_TARGET_ESP32S2
-    bool result = (REG_GET_BIT(EXTMEM_PRO_ICACHE_CTRL_REG, EXTMEM_PRO_ICACHE_ENABLE) != 0);
-#elif CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2
-    bool result = (REG_GET_BIT(EXTMEM_ICACHE_CTRL_REG, EXTMEM_ICACHE_ENABLE) != 0);
-#elif CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
-    bool result = s_cache_enabled;
-#endif
-    return result;
+    return cache_hal_is_cache_enabled(CACHE_TYPE_ALL);
 }
 
 #if CONFIG_IDF_TARGET_ESP32S2
@@ -987,16 +914,3 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable)
     return ESP_OK;
 }
 #endif // CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2
-
-void IRAM_ATTR spi_flash_enable_cache(uint32_t cpuid)
-{
-#if CONFIG_IDF_TARGET_ESP32
-    uint32_t cache_value = DPORT_CACHE_GET_VAL(cpuid);
-    cache_value &= DPORT_CACHE_GET_MASK(cpuid);
-
-    // Re-enable cache on this CPU
-    spi_flash_restore_cache(cpuid, cache_value);
-#else
-    spi_flash_restore_cache(0, 0); // TODO cache_value should be non-zero
-#endif
-}

+ 13 - 0
components/spi_flash/test_apps/mspi_test/CMakeLists.txt

@@ -3,3 +3,16 @@ cmake_minimum_required(VERSION 3.16)
 
 include($ENV{IDF_PATH}/tools/cmake/project.cmake)
 project(mspi_test)
+
+if(CONFIG_COMPILER_DUMP_RTL_FILES)
+    add_custom_target(check_test_app_sections ALL
+                      COMMAND ${PYTHON} $ENV{IDF_PATH}/tools/ci/check_callgraph.py
+                      --rtl-dir ${CMAKE_BINARY_DIR}/esp-idf/driver/
+                      --elf-file ${CMAKE_BINARY_DIR}/mspi_test.elf
+                      find-refs
+                      --from-sections=.iram0.text
+                      --to-sections=.flash.text,.flash.rodata
+                      --exit-code
+                      DEPENDS ${elf}
+                      )
+endif()

+ 1 - 7
components/spi_flash/test_apps/mspi_test/pytest_mspi_test.py

@@ -5,13 +5,7 @@ import pytest
 from pytest_embedded import Dut
 
 
-@pytest.mark.esp32
-@pytest.mark.esp32s2
-@pytest.mark.esp32s3
-@pytest.mark.esp32c3
-@pytest.mark.esp32c2
-@pytest.mark.esp32c6
-@pytest.mark.esp32h2
+@pytest.mark.supported_targets
 @pytest.mark.generic
 @pytest.mark.parametrize(
     'config',

+ 1 - 0
components/spi_flash/test_apps/mspi_test/sdkconfig.ci.special

@@ -2,3 +2,4 @@
 CONFIG_ESP_SYSTEM_MEMPROT_FEATURE=n
 CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y
 CONFIG_COMPILER_OPTIMIZATION_NONE=y
+CONFIG_COMPILER_DUMP_RTL_FILES=y