diff --git a/components/esp_mm/cache_esp32.c b/components/esp_mm/cache_esp32.c new file mode 100644 index 0000000000..665023a82b --- /dev/null +++ b/components/esp_mm/cache_esp32.c @@ -0,0 +1,36 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "sdkconfig.h" +#include "rom/cache.h" +#include "esp_private/esp_cache_esp32_private.h" + + +static cache_driver_t s_cache_drv = { + Cache_Flush, + NULL, +}; + + +void cache_register_writeback(cache_driver_t *func) +{ + s_cache_drv.cache_writeback_psram = func->cache_writeback_psram; +} + + +void cache_sync(void) +{ + if (s_cache_drv.cache_writeback_psram) { + s_cache_drv.cache_writeback_psram(); + } + + s_cache_drv.cache_flush(0); +#if !CONFIG_FREERTOS_UNICORE + s_cache_drv.cache_flush(1); +#endif // !CONFIG_FREERTOS_UNICORE +} diff --git a/components/esp_mm/esp_mmu_map.c b/components/esp_mm/esp_mmu_map.c index 29d158603e..c8ec6c6a8c 100644 --- a/components/esp_mm/esp_mmu_map.c +++ b/components/esp_mm/esp_mmu_map.c @@ -23,14 +23,8 @@ #include "hal/mmu_hal.h" #include "hal/mmu_ll.h" -#if CONFIG_IDF_TARGET_ESP32 -#include "esp32/rom/cache.h" -#endif #include "esp_private/cache_utils.h" -#if CONFIG_SPIRAM -#include "esp_private/esp_psram_extram.h" -#endif - +#include "esp_private/esp_cache_esp32_private.h" #include "esp_private/esp_mmu_map_private.h" #include "ext_mem_layout.h" #include "esp_mmu_map.h" @@ -333,29 +327,15 @@ esp_err_t esp_mmu_map_reserve_block_with_caps(size_t size, mmu_mem_caps_t caps, } -#if CONFIG_IDF_TARGET_ESP32 -/** - * On ESP32, due to hardware limitation, we don't have an - * easy way to sync between cache and external memory wrt - * certain range. So we do a full sync here - */ -static void IRAM_ATTR NOINLINE_ATTR s_cache_sync(void) -{ -#if CONFIG_SPIRAM - esp_psram_extram_writeback_cache(); -#endif //#if CONFIG_SPIRAM - Cache_Flush(0); -#if !CONFIG_FREERTOS_UNICORE - Cache_Flush(1); -#endif // !CONFIG_FREERTOS_UNICORE -} -#endif //#if CONFIG_IDF_TARGET_ESP32 - - static void IRAM_ATTR NOINLINE_ATTR s_do_cache_invalidate(uint32_t vaddr_start, uint32_t size) { #if CONFIG_IDF_TARGET_ESP32 - s_cache_sync(); + /** + * On ESP32, due to hardware limitation, we don't have an + * easy way to sync between cache and external memory wrt + * certain range. So we do a full sync here + */ + cache_sync(); #else //Other chips cache_hal_invalidate_addr(vaddr_start, size); #endif // CONFIG_IDF_TARGET_ESP32 diff --git a/components/esp_mm/include/esp_private/esp_cache_esp32_private.h b/components/esp_mm/include/esp_private/esp_cache_esp32_private.h new file mode 100644 index 0000000000..a8642daf5c --- /dev/null +++ b/components/esp_mm/include/esp_private/esp_cache_esp32_private.h @@ -0,0 +1,59 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Private header for cache drivers, where cache functionality requires other components + * + * @note Now only esp32, can be applied to other similar chips + */ +typedef struct cache_driver_s cache_driver_t; + +/** + * @brief Cache driver + */ +struct cache_driver_s { + + /** + * @brief Cache flush + * + * @param[in] cpu_no CPU id + */ + void (*cache_flush)(int cpu_no); + + /** + * @brief Cache writeback to psram + */ + void (*cache_writeback_psram)(void); +}; + +/** + * @brief Register cache writeback + * + * @param[in] func Cache driver + */ +void cache_register_writeback(cache_driver_t *func); + +/** + * @brief Cache sync + * + * @note This API only do cache sync, but doesn't guarantee concurrent access to cache + * @note Do not use in your application + */ +void cache_sync(void); + + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_mm/linker.lf b/components/esp_mm/linker.lf index 25672c1e20..a48fe34cbf 100644 --- a/components/esp_mm/linker.lf +++ b/components/esp_mm/linker.lf @@ -2,7 +2,8 @@ archive: libesp_mm.a entries: - esp_cache (noflash) + if APP_BUILD_TYPE_PURE_RAM_APP = n: + esp_cache (noflash) - if IDF_TARGET_ESP32S3 = y: - cache_esp32 (noflash) + if IDF_TARGET_ESP32 = y: + cache_esp32 (noflash) diff --git a/components/esp_psram/esp_psram.c b/components/esp_psram/esp_psram.c index 008d9a4533..3fe51e1782 100644 --- a/components/esp_psram/esp_psram.c +++ b/components/esp_psram/esp_psram.c @@ -32,6 +32,7 @@ #if CONFIG_IDF_TARGET_ESP32 #include "esp32/himem.h" #include "esp32/rom/cache.h" +#include "esp_private/esp_cache_esp32_private.h" #endif @@ -293,6 +294,15 @@ esp_err_t esp_psram_init(void) s_psram_ctx.regions_to_heap[PSRAM_MEM_8BIT_ALIGNED].size -= esp_himem_reserved_area_size() - 1; #endif + //will be removed, TODO: IDF-6944 +#if CONFIG_IDF_TARGET_ESP32 + cache_driver_t drv = { + NULL, + esp_psram_extram_writeback_cache, + }; + cache_register_writeback(&drv); +#endif + return ESP_OK; }