| 
									
										
										
										
											2021-11-06 17:23:21 +08:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2025-01-09 21:46:38 +08:00
										 |  |  |  * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD | 
					
						
							| 
									
										
										
										
											2021-11-06 17:23:21 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * SPDX-License-Identifier: Apache-2.0 | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2016-08-17 23:08:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-12 18:54:45 +08:00
										 |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <assert.h>
 | 
					
						
							| 
									
										
										
										
											2016-09-13 16:40:05 +08:00
										 |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-17 23:08:22 +08:00
										 |  |  | #include <freertos/FreeRTOS.h>
 | 
					
						
							|  |  |  | #include <freertos/task.h>
 | 
					
						
							|  |  |  | #include <freertos/semphr.h>
 | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  | #if CONFIG_IDF_TARGET_ESP32
 | 
					
						
							| 
									
										
										
										
											2020-11-26 19:56:13 +11:00
										 |  |  | #include "soc/dport_reg.h"
 | 
					
						
							| 
									
										
										
										
											2019-03-14 17:29:32 +08:00
										 |  |  | #include <esp32/rom/cache.h>
 | 
					
						
							| 
									
										
										
										
											2020-01-17 11:47:08 +08:00
										 |  |  | #elif CONFIG_IDF_TARGET_ESP32S2
 | 
					
						
							|  |  |  | #include "esp32s2/rom/cache.h"
 | 
					
						
							| 
									
										
										
										
											2019-12-26 15:25:24 +08:00
										 |  |  | #include "soc/extmem_reg.h"
 | 
					
						
							| 
									
										
										
										
											2022-02-11 15:30:54 +08:00
										 |  |  | #include "soc/ext_mem_defs.h"
 | 
					
						
							| 
									
										
										
										
											2020-07-29 13:13:51 +08:00
										 |  |  | #elif CONFIG_IDF_TARGET_ESP32S3
 | 
					
						
							|  |  |  | #include "esp32s3/rom/cache.h"
 | 
					
						
							|  |  |  | #include "soc/extmem_reg.h"
 | 
					
						
							| 
									
										
										
										
											2022-02-11 15:30:54 +08:00
										 |  |  | #include "soc/ext_mem_defs.h"
 | 
					
						
							| 
									
										
										
										
											2020-11-26 19:56:13 +11:00
										 |  |  | #elif CONFIG_IDF_TARGET_ESP32C3
 | 
					
						
							|  |  |  | #include "esp32c3/rom/cache.h"
 | 
					
						
							|  |  |  | #include "soc/extmem_reg.h"
 | 
					
						
							| 
									
										
										
										
											2022-02-11 15:30:54 +08:00
										 |  |  | #include "soc/ext_mem_defs.h"
 | 
					
						
							| 
									
										
										
										
											2022-01-18 10:32:56 +08:00
										 |  |  | #elif CONFIG_IDF_TARGET_ESP32C2
 | 
					
						
							|  |  |  | #include "esp32c2/rom/cache.h"
 | 
					
						
							| 
									
										
										
										
											2021-11-06 17:23:21 +08:00
										 |  |  | #include "soc/extmem_reg.h"
 | 
					
						
							| 
									
										
										
										
											2022-02-11 15:30:54 +08:00
										 |  |  | #include "soc/ext_mem_defs.h"
 | 
					
						
							| 
									
										
										
										
											2022-07-12 21:19:35 +08:00
										 |  |  | #elif CONFIG_IDF_TARGET_ESP32C6
 | 
					
						
							|  |  |  | #include "esp32c6/rom/cache.h"
 | 
					
						
							|  |  |  | #include "soc/extmem_reg.h"
 | 
					
						
							|  |  |  | #include "soc/ext_mem_defs.h"
 | 
					
						
							| 
									
										
										
										
											2024-03-13 14:24:43 +08:00
										 |  |  | #elif CONFIG_IDF_TARGET_ESP32C61    //TODO: IDF-9526, refactor this
 | 
					
						
							|  |  |  | #include "esp32c61/rom/cache.h"
 | 
					
						
							|  |  |  | #include "soc/cache_reg.h"
 | 
					
						
							|  |  |  | #include "soc/ext_mem_defs.h"
 | 
					
						
							| 
									
										
										
										
											2022-12-29 11:01:13 +08:00
										 |  |  | #elif CONFIG_IDF_TARGET_ESP32H2
 | 
					
						
							|  |  |  | #include "esp32h2/rom/cache.h"
 | 
					
						
							|  |  |  | #include "soc/extmem_reg.h"
 | 
					
						
							|  |  |  | #include "soc/ext_mem_defs.h"
 | 
					
						
							| 
									
										
										
										
											2023-07-21 12:37:06 +08:00
										 |  |  | #elif CONFIG_IDF_TARGET_ESP32P4
 | 
					
						
							|  |  |  | #include "esp32p4/rom/cache.h"
 | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2021-09-28 14:12:56 +08:00
										 |  |  | #include "esp_rom_spiflash.h"
 | 
					
						
							| 
									
										
										
										
											2023-06-13 11:56:14 +08:00
										 |  |  | #include "hal/cache_hal.h"
 | 
					
						
							|  |  |  | #include "hal/cache_ll.h"
 | 
					
						
							| 
									
										
										
										
											2016-09-12 18:54:45 +08:00
										 |  |  | #include <soc/soc.h>
 | 
					
						
							| 
									
										
										
										
											2016-08-24 18:01:01 +08:00
										 |  |  | #include "sdkconfig.h"
 | 
					
						
							| 
									
										
										
										
											2020-04-27 14:29:54 +08:00
										 |  |  | #ifndef CONFIG_FREERTOS_UNICORE
 | 
					
						
							| 
									
										
										
										
											2023-12-28 16:50:55 +08:00
										 |  |  | #include "esp_private/esp_ipc.h"
 | 
					
						
							| 
									
										
										
										
											2020-04-27 14:29:54 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-09-12 18:54:45 +08:00
										 |  |  | #include "esp_attr.h"
 | 
					
						
							| 
									
										
										
										
											2022-07-21 19:14:41 +08:00
										 |  |  | #include "esp_memory_utils.h"
 | 
					
						
							| 
									
										
										
										
											2016-11-25 17:33:51 +08:00
										 |  |  | #include "esp_intr_alloc.h"
 | 
					
						
							| 
									
										
										
										
											2023-02-10 14:51:11 +08:00
										 |  |  | #include "spi_flash_override.h"
 | 
					
						
							| 
									
										
										
										
											2025-03-26 16:06:50 +08:00
										 |  |  | #include "esp_private/esp_cache_private.h"
 | 
					
						
							| 
									
										
										
										
											2025-01-09 21:46:38 +08:00
										 |  |  | #include "esp_private/cache_utils.h"
 | 
					
						
							| 
									
										
										
										
											2023-02-10 14:51:11 +08:00
										 |  |  | #include "esp_private/spi_flash_os.h"
 | 
					
						
							| 
									
										
										
										
											2023-04-06 21:26:17 +08:00
										 |  |  | #include "esp_private/freertos_idf_additions_priv.h"
 | 
					
						
							| 
									
										
										
										
											2016-09-23 08:44:45 +08:00
										 |  |  | #include "esp_log.h"
 | 
					
						
							| 
									
										
										
										
											2016-08-17 23:08:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-26 15:25:24 +08:00
										 |  |  | static __attribute__((unused)) const char *TAG = "cache"; | 
					
						
							| 
									
										
										
										
											2019-09-16 10:56:48 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 11:56:14 +08:00
										 |  |  | // Used only on ROM impl. in idf, this param unused, cache status hold by hal
 | 
					
						
							| 
									
										
										
										
											2016-09-12 18:54:45 +08:00
										 |  |  | static uint32_t s_flash_op_cache_state[2]; | 
					
						
							| 
									
										
										
										
											2016-08-24 18:01:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-12 21:19:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-12 18:54:45 +08:00
										 |  |  | #ifndef CONFIG_FREERTOS_UNICORE
 | 
					
						
							| 
									
										
										
										
											2016-08-24 18:01:01 +08:00
										 |  |  | static SemaphoreHandle_t s_flash_op_mutex; | 
					
						
							| 
									
										
										
										
											2016-11-08 09:02:30 +08:00
										 |  |  | static volatile bool s_flash_op_can_start = false; | 
					
						
							|  |  |  | static volatile bool s_flash_op_complete = false; | 
					
						
							| 
									
										
										
										
											2017-01-18 15:07:27 +08:00
										 |  |  | #ifndef NDEBUG
 | 
					
						
							|  |  |  | static volatile int s_flash_op_cpu = -1; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-09-13 16:40:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-29 11:35:42 +08:00
										 |  |  | static inline bool esp_task_stack_is_sane_cache_disabled(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const void *sp = (const void *)esp_cpu_get_sp(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return esp_ptr_in_dram(sp) | 
					
						
							|  |  |  | #if CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP
 | 
					
						
							| 
									
										
										
										
											2023-12-28 16:50:55 +08:00
										 |  |  |            || esp_ptr_in_rtc_dram_fast(sp) | 
					
						
							| 
									
										
										
										
											2021-10-29 11:35:42 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2023-12-28 16:50:55 +08:00
										 |  |  |            ; | 
					
						
							| 
									
										
										
										
											2021-10-29 11:35:42 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-16 16:33:30 +07:00
										 |  |  | void spi_flash_init_lock(void) | 
					
						
							| 
									
										
										
										
											2016-10-19 17:08:05 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-11-17 15:00:16 +11:00
										 |  |  |     s_flash_op_mutex = xSemaphoreCreateRecursiveMutex(); | 
					
						
							| 
									
										
										
										
											2017-07-12 11:33:51 +08:00
										 |  |  |     assert(s_flash_op_mutex != NULL); | 
					
						
							| 
									
										
										
										
											2016-10-19 17:08:05 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-09-13 16:40:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-16 16:33:30 +07:00
										 |  |  | void spi_flash_op_lock(void) | 
					
						
							| 
									
										
										
										
											2016-10-19 17:08:05 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-11-17 15:00:16 +11:00
										 |  |  |     xSemaphoreTakeRecursive(s_flash_op_mutex, portMAX_DELAY); | 
					
						
							| 
									
										
										
										
											2016-10-19 17:08:05 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-08-24 18:01:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-16 16:33:30 +07:00
										 |  |  | void spi_flash_op_unlock(void) | 
					
						
							| 
									
										
										
										
											2016-10-19 17:08:05 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-11-17 15:00:16 +11:00
										 |  |  |     xSemaphoreGiveRecursive(s_flash_op_mutex); | 
					
						
							| 
									
										
										
										
											2016-10-19 17:08:05 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-09-04 20:11:15 +08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  If you're going to modify this, keep in mind that while the flash caches of the pro and app | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  |  cpu are separate, the psram cache is *not*. If one of the CPUs returns from a flash routine | 
					
						
							| 
									
										
										
										
											2017-09-04 20:11:15 +08:00
										 |  |  |  with its cache enabled but the other CPUs cache is not enabled yet, you will have problems | 
					
						
							|  |  |  |  when accessing psram from the former CPU. | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2016-09-12 18:54:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-26 15:25:24 +08:00
										 |  |  | void IRAM_ATTR spi_flash_op_block_func(void *arg) | 
					
						
							| 
									
										
										
										
											2016-08-17 23:08:22 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-09-12 18:54:45 +08:00
										 |  |  |     // Disable scheduler on this CPU
 | 
					
						
							| 
									
										
										
										
											2024-02-02 23:38:00 +08:00
										 |  |  | #if ( ( CONFIG_FREERTOS_SMP ) && ( !CONFIG_FREERTOS_UNICORE ) )
 | 
					
						
							| 
									
										
										
										
											2022-02-25 21:50:58 +08:00
										 |  |  |     /*
 | 
					
						
							|  |  |  |     Note: FreeRTOS SMP has changed the behavior of scheduler suspension. But the vTaskPreemptionDisable() function should | 
					
						
							|  |  |  |     achieve the same affect as before (i.e., prevent the current task from being preempted). | 
					
						
							|  |  |  |     */ | 
					
						
							|  |  |  |     vTaskPreemptionDisable(NULL); | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2016-09-12 18:54:45 +08:00
										 |  |  |     vTaskSuspendAll(); | 
					
						
							| 
									
										
										
										
											2024-02-02 23:38:00 +08:00
										 |  |  | #endif // #if ( ( CONFIG_FREERTOS_SMP ) && ( !CONFIG_FREERTOS_UNICORE ) )
 | 
					
						
							| 
									
										
										
										
											2016-11-25 17:33:51 +08:00
										 |  |  |     // Restore interrupts that aren't located in IRAM
 | 
					
						
							|  |  |  |     esp_intr_noniram_disable(); | 
					
						
							| 
									
										
										
										
											2016-08-24 18:01:01 +08:00
										 |  |  |     uint32_t cpuid = (uint32_t) arg; | 
					
						
							| 
									
										
										
										
											2017-03-28 01:02:58 +08:00
										 |  |  |     // s_flash_op_complete flag is cleared on *this* CPU, otherwise the other
 | 
					
						
							|  |  |  |     // CPU may reset the flag back to false before IPC task has a chance to check it
 | 
					
						
							|  |  |  |     // (if it is preempted by an ISR taking non-trivial amount of time)
 | 
					
						
							|  |  |  |     s_flash_op_complete = false; | 
					
						
							| 
									
										
										
										
											2016-09-12 18:54:45 +08:00
										 |  |  |     s_flash_op_can_start = true; | 
					
						
							|  |  |  |     while (!s_flash_op_complete) { | 
					
						
							|  |  |  |         // busy loop here and wait for the other CPU to finish flash operation
 | 
					
						
							| 
									
										
										
										
											2016-08-17 23:08:22 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-09-12 18:54:45 +08:00
										 |  |  |     // Flash operation is complete, re-enable cache
 | 
					
						
							|  |  |  |     spi_flash_restore_cache(cpuid, s_flash_op_cache_state[cpuid]); | 
					
						
							| 
									
										
										
										
											2016-11-25 17:33:51 +08:00
										 |  |  |     // Restore interrupts that aren't located in IRAM
 | 
					
						
							|  |  |  |     esp_intr_noniram_enable(); | 
					
						
							| 
									
										
										
										
											2024-02-02 23:38:00 +08:00
										 |  |  | #if ( ( CONFIG_FREERTOS_SMP ) && ( !CONFIG_FREERTOS_UNICORE ) )
 | 
					
						
							| 
									
										
										
										
											2022-02-25 21:50:58 +08:00
										 |  |  |     //Note: Scheduler suspension behavior changed in FreeRTOS SMP
 | 
					
						
							|  |  |  |     vTaskPreemptionEnable(NULL); | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2016-09-12 18:54:45 +08:00
										 |  |  |     // Re-enable scheduler
 | 
					
						
							|  |  |  |     xTaskResumeAll(); | 
					
						
							| 
									
										
										
										
											2024-02-02 23:38:00 +08:00
										 |  |  | #endif // #if ( ( CONFIG_FREERTOS_SMP ) && ( !CONFIG_FREERTOS_UNICORE ) )
 | 
					
						
							| 
									
										
										
										
											2016-08-17 23:08:22 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-16 16:33:30 +07:00
										 |  |  | void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu(void) | 
					
						
							| 
									
										
										
										
											2016-08-24 18:01:01 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-10-29 11:35:42 +08:00
										 |  |  |     assert(esp_task_stack_is_sane_cache_disabled()); | 
					
						
							| 
									
										
										
										
											2020-03-02 20:40:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-19 17:08:05 +08:00
										 |  |  |     spi_flash_op_lock(); | 
					
						
							| 
									
										
										
										
											2016-09-12 18:54:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-28 16:50:55 +08:00
										 |  |  |     int cpuid = xPortGetCoreID(); | 
					
						
							|  |  |  |     uint32_t other_cpuid = (cpuid == 0) ? 1 : 0; | 
					
						
							| 
									
										
										
										
											2017-01-18 15:07:27 +08:00
										 |  |  | #ifndef NDEBUG
 | 
					
						
							|  |  |  |     // For sanity check later: record the CPU which has started doing flash operation
 | 
					
						
							|  |  |  |     assert(s_flash_op_cpu == -1); | 
					
						
							|  |  |  |     s_flash_op_cpu = cpuid; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-09-12 18:54:45 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED) { | 
					
						
							| 
									
										
										
										
											2016-09-13 12:47:21 +08:00
										 |  |  |         // Scheduler hasn't been started yet, it means that spi_flash API is being
 | 
					
						
							|  |  |  |         // called from the 2nd stage bootloader or from user_start_cpu0, i.e. from
 | 
					
						
							|  |  |  |         // PRO CPU. APP CPU is either in reset or spinning inside user_start_cpu1,
 | 
					
						
							| 
									
										
										
										
											2021-04-25 21:25:58 +08:00
										 |  |  |         // which is in IRAM. So it is safe to disable cache for the other_cpuid after
 | 
					
						
							|  |  |  |         // esp_intr_noniram_disable.
 | 
					
						
							| 
									
										
										
										
											2016-09-13 12:47:21 +08:00
										 |  |  |         assert(other_cpuid == 1); | 
					
						
							| 
									
										
										
										
											2016-09-12 18:54:45 +08:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2023-12-28 16:50:55 +08:00
										 |  |  |         bool ipc_call_was_send_to_other_cpu; | 
					
						
							|  |  |  |         do { | 
					
						
							|  |  |  | #if ( ( CONFIG_FREERTOS_SMP ) && ( !CONFIG_FREERTOS_UNICORE ) )
 | 
					
						
							|  |  |  |             //Note: Scheduler suspension behavior changed in FreeRTOS SMP
 | 
					
						
							|  |  |  |             vTaskPreemptionDisable(NULL); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |             // Disable scheduler on the current CPU
 | 
					
						
							|  |  |  |             vTaskSuspendAll(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |             cpuid = xPortGetCoreID(); | 
					
						
							|  |  |  |             other_cpuid = (cpuid == 0) ? 1 : 0; | 
					
						
							|  |  |  | #ifndef NDEBUG
 | 
					
						
							|  |  |  |             s_flash_op_cpu = cpuid; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |             s_flash_op_can_start = false; | 
					
						
							|  |  |  |             ipc_call_was_send_to_other_cpu = esp_ipc_call_nonblocking(other_cpuid, &spi_flash_op_block_func, (void *) other_cpuid) == ESP_OK; | 
					
						
							|  |  |  |             if (!ipc_call_was_send_to_other_cpu) { | 
					
						
							|  |  |  |                 // IPC call was not send to other cpu because another nonblocking API is running now.
 | 
					
						
							|  |  |  |                 // Enable the Scheduler again will not help the IPC to speed it up
 | 
					
						
							|  |  |  |                 // but there is a benefit to schedule to a higher priority task before the nonblocking running IPC call is done.
 | 
					
						
							|  |  |  | #if ( ( CONFIG_FREERTOS_SMP ) && ( !CONFIG_FREERTOS_UNICORE ) )
 | 
					
						
							|  |  |  |                 //Note: Scheduler suspension behavior changed in FreeRTOS SMP
 | 
					
						
							|  |  |  |                 vTaskPreemptionEnable(NULL); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |                 xTaskResumeAll(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } while (!ipc_call_was_send_to_other_cpu); | 
					
						
							| 
									
										
										
										
											2021-02-12 16:01:05 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-12 18:54:45 +08:00
										 |  |  |         while (!s_flash_op_can_start) { | 
					
						
							|  |  |  |             // Busy loop and wait for spi_flash_op_block_func to disable cache
 | 
					
						
							|  |  |  |             // on the other CPU
 | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-08-24 18:01:01 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-12-28 16:50:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-25 17:33:51 +08:00
										 |  |  |     // Kill interrupts that aren't located in IRAM
 | 
					
						
							|  |  |  |     esp_intr_noniram_disable(); | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  |     // This CPU executes this routine, with non-IRAM interrupts and the scheduler
 | 
					
						
							| 
									
										
										
										
											2017-09-04 20:11:15 +08:00
										 |  |  |     // disabled. The other CPU is spinning in the spi_flash_op_block_func task, also
 | 
					
						
							|  |  |  |     // with non-iram interrupts and the scheduler disabled. None of these CPUs will
 | 
					
						
							|  |  |  |     // touch external RAM or flash this way, so we can safely disable caches.
 | 
					
						
							| 
									
										
										
										
											2016-09-12 18:54:45 +08:00
										 |  |  |     spi_flash_disable_cache(cpuid, &s_flash_op_cache_state[cpuid]); | 
					
						
							| 
									
										
										
										
											2023-05-24 16:27:11 +08:00
										 |  |  | #if SOC_IDCACHE_PER_CORE
 | 
					
						
							|  |  |  |     //only needed if cache(s) is per core
 | 
					
						
							| 
									
										
										
										
											2017-09-04 20:11:15 +08:00
										 |  |  |     spi_flash_disable_cache(other_cpuid, &s_flash_op_cache_state[other_cpuid]); | 
					
						
							| 
									
										
										
										
											2023-05-24 16:27:11 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-08-24 18:01:01 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-16 16:33:30 +07:00
										 |  |  | void IRAM_ATTR spi_flash_enable_interrupts_caches_and_other_cpu(void) | 
					
						
							| 
									
										
										
										
											2016-08-24 18:01:01 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-11-17 12:48:35 +08:00
										 |  |  |     const int cpuid = xPortGetCoreID(); | 
					
						
							| 
									
										
										
										
											2023-05-24 16:27:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-18 15:07:27 +08:00
										 |  |  | #ifndef NDEBUG
 | 
					
						
							|  |  |  |     // Sanity check: flash operation ends on the same CPU as it has started
 | 
					
						
							|  |  |  |     assert(cpuid == s_flash_op_cpu); | 
					
						
							| 
									
										
										
										
											2017-09-04 20:11:15 +08:00
										 |  |  |     // More sanity check: if scheduler isn't started, only CPU0 can call this.
 | 
					
						
							|  |  |  |     assert(!(xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED && cpuid != 0)); | 
					
						
							| 
									
										
										
										
											2017-01-18 15:07:27 +08:00
										 |  |  |     s_flash_op_cpu = -1; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-09-12 18:54:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 11:56:14 +08:00
										 |  |  |     // Re-enable cache. After this, cache (flash and external RAM) should work again.
 | 
					
						
							| 
									
										
										
										
											2016-09-12 18:54:45 +08:00
										 |  |  |     spi_flash_restore_cache(cpuid, s_flash_op_cache_state[cpuid]); | 
					
						
							| 
									
										
										
										
											2023-05-24 16:27:11 +08:00
										 |  |  | #if SOC_IDCACHE_PER_CORE
 | 
					
						
							|  |  |  |     //only needed if cache(s) is per core
 | 
					
						
							|  |  |  |     const uint32_t other_cpuid = (cpuid == 0) ? 1 : 0; | 
					
						
							| 
									
										
										
										
											2017-09-04 20:11:15 +08:00
										 |  |  |     spi_flash_restore_cache(other_cpuid, s_flash_op_cache_state[other_cpuid]); | 
					
						
							| 
									
										
										
										
											2023-05-24 16:27:11 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-09-12 18:54:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-04 20:11:15 +08:00
										 |  |  |     if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { | 
					
						
							| 
									
										
										
										
											2016-09-12 18:54:45 +08:00
										 |  |  |         // Signal to spi_flash_op_block_task that flash operation is complete
 | 
					
						
							|  |  |  |         s_flash_op_complete = true; | 
					
						
							| 
									
										
										
										
											2017-01-18 15:07:27 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-09-04 20:11:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-18 15:07:27 +08:00
										 |  |  |     // Re-enable non-iram interrupts
 | 
					
						
							|  |  |  |     esp_intr_noniram_enable(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Resume tasks on the current CPU, if the scheduler has started.
 | 
					
						
							|  |  |  |     // NOTE: enabling non-IRAM interrupts has to happen before this,
 | 
					
						
							|  |  |  |     // because once the scheduler has started, due to preemption the
 | 
					
						
							|  |  |  |     // current task can end up being moved to the other CPU.
 | 
					
						
							|  |  |  |     // But esp_intr_noniram_enable has to be called on the same CPU which
 | 
					
						
							|  |  |  |     // called esp_intr_noniram_disable
 | 
					
						
							|  |  |  |     if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { | 
					
						
							| 
									
										
										
										
											2024-02-02 23:38:00 +08:00
										 |  |  | #if ( ( CONFIG_FREERTOS_SMP ) && ( !CONFIG_FREERTOS_UNICORE ) )
 | 
					
						
							| 
									
										
										
										
											2022-02-25 21:50:58 +08:00
										 |  |  |         //Note: Scheduler suspension behavior changed in FreeRTOS SMP
 | 
					
						
							|  |  |  |         vTaskPreemptionEnable(NULL); | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2016-09-12 18:54:45 +08:00
										 |  |  |         xTaskResumeAll(); | 
					
						
							| 
									
										
										
										
											2024-02-02 23:38:00 +08:00
										 |  |  | #endif // #if ( ( CONFIG_FREERTOS_SMP ) && ( !CONFIG_FREERTOS_UNICORE ) )
 | 
					
						
							| 
									
										
										
										
											2016-09-12 18:54:45 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-08-24 18:01:01 +08:00
										 |  |  |     // Release API lock
 | 
					
						
							| 
									
										
										
										
											2016-10-19 17:08:05 +08:00
										 |  |  |     spi_flash_op_unlock(); | 
					
						
							| 
									
										
										
										
											2016-08-24 18:01:01 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-16 16:33:30 +07:00
										 |  |  | void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu_no_os(void) | 
					
						
							| 
									
										
										
										
											2016-12-22 02:56:23 +03:00
										 |  |  | { | 
					
						
							|  |  |  |     const uint32_t cpuid = xPortGetCoreID(); | 
					
						
							|  |  |  |     const uint32_t other_cpuid = (cpuid == 0) ? 1 : 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // do not care about other CPU, it was halted upon entering panic handler
 | 
					
						
							|  |  |  |     spi_flash_disable_cache(other_cpuid, &s_flash_op_cache_state[other_cpuid]); | 
					
						
							|  |  |  |     // Kill interrupts that aren't located in IRAM
 | 
					
						
							|  |  |  |     esp_intr_noniram_disable(); | 
					
						
							|  |  |  |     // Disable cache on this CPU as well
 | 
					
						
							|  |  |  |     spi_flash_disable_cache(cpuid, &s_flash_op_cache_state[cpuid]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-16 16:33:30 +07:00
										 |  |  | void IRAM_ATTR spi_flash_enable_interrupts_caches_no_os(void) | 
					
						
							| 
									
										
										
										
											2016-12-22 02:56:23 +03:00
										 |  |  | { | 
					
						
							|  |  |  |     const uint32_t cpuid = xPortGetCoreID(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Re-enable cache on this CPU
 | 
					
						
							|  |  |  |     spi_flash_restore_cache(cpuid, s_flash_op_cache_state[cpuid]); | 
					
						
							|  |  |  |     // Re-enable non-iram interrupts
 | 
					
						
							|  |  |  |     esp_intr_noniram_enable(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-19 17:08:05 +08:00
										 |  |  | #else // CONFIG_FREERTOS_UNICORE
 | 
					
						
							| 
									
										
										
										
											2016-08-24 18:01:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-16 16:33:30 +07:00
										 |  |  | void spi_flash_init_lock(void) | 
					
						
							| 
									
										
										
										
											2016-08-24 18:01:01 +08:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-16 16:33:30 +07:00
										 |  |  | void spi_flash_op_lock(void) | 
					
						
							| 
									
										
										
										
											2016-08-17 23:08:22 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-02-02 23:38:00 +08:00
										 |  |  | #if ( ( CONFIG_FREERTOS_SMP ) && ( !CONFIG_FREERTOS_UNICORE ) )
 | 
					
						
							| 
									
										
										
										
											2022-02-25 21:50:58 +08:00
										 |  |  |     if (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING) { | 
					
						
							|  |  |  |         //Note: Scheduler suspension behavior changed in FreeRTOS SMP
 | 
					
						
							|  |  |  |         vTaskPreemptionDisable(NULL); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2016-08-17 23:08:22 +08:00
										 |  |  |     vTaskSuspendAll(); | 
					
						
							| 
									
										
										
										
											2024-02-02 23:38:00 +08:00
										 |  |  | #endif // #if ( ( CONFIG_FREERTOS_SMP ) && ( !CONFIG_FREERTOS_UNICORE ) )
 | 
					
						
							| 
									
										
										
										
											2016-08-17 23:08:22 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-16 16:33:30 +07:00
										 |  |  | void spi_flash_op_unlock(void) | 
					
						
							| 
									
										
										
										
											2016-08-17 23:08:22 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-02-02 23:38:00 +08:00
										 |  |  | #if ( ( CONFIG_FREERTOS_SMP ) && ( !CONFIG_FREERTOS_UNICORE ) )
 | 
					
						
							| 
									
										
										
										
											2022-02-25 21:50:58 +08:00
										 |  |  |     if (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING) { | 
					
						
							|  |  |  |         //Note: Scheduler suspension behavior changed in FreeRTOS SMP
 | 
					
						
							|  |  |  |         vTaskPreemptionEnable(NULL); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2016-08-17 23:08:22 +08:00
										 |  |  |     xTaskResumeAll(); | 
					
						
							| 
									
										
										
										
											2024-02-02 23:38:00 +08:00
										 |  |  | #endif // #if ( ( CONFIG_FREERTOS_SMP ) && ( !CONFIG_FREERTOS_UNICORE ) )
 | 
					
						
							| 
									
										
										
										
											2016-08-17 23:08:22 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-24 18:01:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-16 16:33:30 +07:00
										 |  |  | void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu(void) | 
					
						
							| 
									
										
										
										
											2016-09-13 15:16:36 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-11-17 15:00:51 +11:00
										 |  |  |     spi_flash_op_lock(); | 
					
						
							| 
									
										
										
										
											2017-02-21 21:57:53 +08:00
										 |  |  |     esp_intr_noniram_disable(); | 
					
						
							| 
									
										
										
										
											2016-10-19 17:08:05 +08:00
										 |  |  |     spi_flash_disable_cache(0, &s_flash_op_cache_state[0]); | 
					
						
							| 
									
										
										
										
											2016-09-13 15:16:36 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-16 16:33:30 +07:00
										 |  |  | void IRAM_ATTR spi_flash_enable_interrupts_caches_and_other_cpu(void) | 
					
						
							| 
									
										
										
										
											2016-08-17 23:08:22 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-19 17:08:05 +08:00
										 |  |  |     spi_flash_restore_cache(0, s_flash_op_cache_state[0]); | 
					
						
							| 
									
										
										
										
											2016-11-25 17:33:51 +08:00
										 |  |  |     esp_intr_noniram_enable(); | 
					
						
							| 
									
										
										
										
											2017-02-21 21:57:53 +08:00
										 |  |  |     spi_flash_op_unlock(); | 
					
						
							| 
									
										
										
										
											2016-08-17 23:08:22 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-16 16:33:30 +07:00
										 |  |  | void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu_no_os(void) | 
					
						
							| 
									
										
										
										
											2016-12-22 02:56:23 +03:00
										 |  |  | { | 
					
						
							|  |  |  |     // Kill interrupts that aren't located in IRAM
 | 
					
						
							|  |  |  |     esp_intr_noniram_disable(); | 
					
						
							|  |  |  |     // Disable cache on this CPU as well
 | 
					
						
							|  |  |  |     spi_flash_disable_cache(0, &s_flash_op_cache_state[0]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-16 16:33:30 +07:00
										 |  |  | void IRAM_ATTR spi_flash_enable_interrupts_caches_no_os(void) | 
					
						
							| 
									
										
										
										
											2016-12-22 02:56:23 +03:00
										 |  |  | { | 
					
						
							|  |  |  |     // Re-enable cache on this CPU
 | 
					
						
							|  |  |  |     spi_flash_restore_cache(0, s_flash_op_cache_state[0]); | 
					
						
							|  |  |  |     // Re-enable non-iram interrupts
 | 
					
						
							|  |  |  |     esp_intr_noniram_enable(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-19 17:08:05 +08:00
										 |  |  | #endif // CONFIG_FREERTOS_UNICORE
 | 
					
						
							| 
									
										
										
										
											2016-08-17 23:08:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 11:56:14 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-24 16:16:46 +08:00
										 |  |  | void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t *saved_state) | 
					
						
							| 
									
										
										
										
											2016-09-12 18:54:45 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2025-04-02 18:07:40 +08:00
										 |  |  | #if SOC_BRANCH_PREDICTOR_SUPPORTED
 | 
					
						
							|  |  |  |     //branch predictor will start cache request as well
 | 
					
						
							|  |  |  |     esp_cpu_branch_prediction_disable(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2025-03-26 16:06:50 +08:00
										 |  |  |     esp_cache_suspend_ext_mem_cache(); | 
					
						
							| 
									
										
										
										
											2016-09-12 18:54:45 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-24 16:16:46 +08:00
										 |  |  | void IRAM_ATTR spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_state) | 
					
						
							| 
									
										
										
										
											2016-09-12 18:54:45 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2025-03-26 16:06:50 +08:00
										 |  |  |     esp_cache_resume_ext_mem_cache(); | 
					
						
							| 
									
										
										
										
											2025-04-02 18:07:40 +08:00
										 |  |  | #if SOC_BRANCH_PREDICTOR_SUPPORTED
 | 
					
						
							|  |  |  |     esp_cpu_branch_prediction_enable(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-09-12 18:54:45 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-09-13 16:40:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 11:56:14 +08:00
										 |  |  | bool IRAM_ATTR spi_flash_cache_enabled(void) | 
					
						
							| 
									
										
										
										
											2017-03-02 15:21:03 +11:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-09-15 20:11:52 +08:00
										 |  |  |     return cache_hal_is_cache_enabled(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); | 
					
						
							| 
									
										
										
										
											2017-03-02 15:21:03 +11:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-17 11:47:08 +08:00
										 |  |  | #if CONFIG_IDF_TARGET_ESP32S2
 | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  | IRAM_ATTR void esp_config_instruction_cache_mode(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     cache_size_t cache_size; | 
					
						
							|  |  |  |     cache_ways_t cache_ways; | 
					
						
							|  |  |  |     cache_line_size_t cache_line_size; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-10 15:07:12 +08:00
										 |  |  | #if CONFIG_ESP32S2_INSTRUCTION_CACHE_8KB
 | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  |     Cache_Allocate_SRAM(CACHE_MEMORY_ICACHE_LOW, CACHE_MEMORY_INVALID, CACHE_MEMORY_INVALID, CACHE_MEMORY_INVALID); | 
					
						
							|  |  |  |     cache_size = CACHE_SIZE_8KB; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     Cache_Allocate_SRAM(CACHE_MEMORY_ICACHE_LOW, CACHE_MEMORY_ICACHE_HIGH, CACHE_MEMORY_INVALID, CACHE_MEMORY_INVALID); | 
					
						
							|  |  |  |     cache_size = CACHE_SIZE_16KB; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     cache_ways = CACHE_4WAYS_ASSOC; | 
					
						
							| 
									
										
										
										
											2019-08-22 14:17:46 +08:00
										 |  |  | #if CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_16B
 | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  |     cache_line_size = CACHE_LINE_SIZE_16B; | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2020-01-07 16:58:14 +08:00
										 |  |  |     cache_line_size = CACHE_LINE_SIZE_32B; | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2020-01-07 16:58:14 +08:00
										 |  |  |     ESP_EARLY_LOGI(TAG, "Instruction cache \t: size %dKB, %dWays, cache line size %dByte", cache_size == CACHE_SIZE_8KB ? 8 : 16, 4, cache_line_size == CACHE_LINE_SIZE_16B ? 16 : 32); | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  |     Cache_Suspend_ICache(); | 
					
						
							|  |  |  |     Cache_Set_ICache_Mode(cache_size, cache_ways, cache_line_size); | 
					
						
							|  |  |  |     Cache_Invalidate_ICache_All(); | 
					
						
							|  |  |  |     Cache_Resume_ICache(0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | IRAM_ATTR void esp_config_data_cache_mode(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-01-04 12:03:53 +08:00
										 |  |  | #define CACHE_SIZE_0KB  99  //If Cache set to 0 KB, cache is bypassed, the cache size doesn't take into effect. Set this macro to a unique value for log
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  |     cache_size_t cache_size; | 
					
						
							|  |  |  |     cache_ways_t cache_ways; | 
					
						
							|  |  |  |     cache_line_size_t cache_line_size; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-10 15:07:12 +08:00
										 |  |  | #if CONFIG_ESP32S2_INSTRUCTION_CACHE_8KB
 | 
					
						
							| 
									
										
										
										
											2024-01-04 12:03:53 +08:00
										 |  |  | #if CONFIG_ESP32S2_DATA_CACHE_0KB
 | 
					
						
							|  |  |  |     Cache_Allocate_SRAM(CACHE_MEMORY_ICACHE_LOW, CACHE_MEMORY_INVALID, CACHE_MEMORY_INVALID, CACHE_MEMORY_INVALID); | 
					
						
							|  |  |  |     cache_size = CACHE_SIZE_0KB; | 
					
						
							|  |  |  | #elif CONFIG_ESP32S2_DATA_CACHE_8KB
 | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  |     Cache_Allocate_SRAM(CACHE_MEMORY_ICACHE_LOW, CACHE_MEMORY_DCACHE_LOW, CACHE_MEMORY_INVALID, CACHE_MEMORY_INVALID); | 
					
						
							|  |  |  |     cache_size = CACHE_SIZE_8KB; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     Cache_Allocate_SRAM(CACHE_MEMORY_ICACHE_LOW, CACHE_MEMORY_DCACHE_LOW, CACHE_MEMORY_DCACHE_HIGH, CACHE_MEMORY_INVALID); | 
					
						
							|  |  |  |     cache_size = CACHE_SIZE_16KB; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2024-01-04 12:03:53 +08:00
										 |  |  | #if CONFIG_ESP32S2_DATA_CACHE_0KB
 | 
					
						
							|  |  |  |     Cache_Allocate_SRAM(CACHE_MEMORY_ICACHE_LOW, CACHE_MEMORY_ICACHE_HIGH, CACHE_MEMORY_INVALID, CACHE_MEMORY_INVALID); | 
					
						
							|  |  |  |     cache_size = CACHE_SIZE_0KB; | 
					
						
							|  |  |  | #elif CONFIG_ESP32S2_DATA_CACHE_8KB
 | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  |     Cache_Allocate_SRAM(CACHE_MEMORY_ICACHE_LOW, CACHE_MEMORY_ICACHE_HIGH, CACHE_MEMORY_DCACHE_LOW, CACHE_MEMORY_INVALID); | 
					
						
							|  |  |  |     cache_size = CACHE_SIZE_8KB; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     Cache_Allocate_SRAM(CACHE_MEMORY_ICACHE_LOW, CACHE_MEMORY_ICACHE_HIGH, CACHE_MEMORY_DCACHE_LOW, CACHE_MEMORY_DCACHE_HIGH); | 
					
						
							|  |  |  |     cache_size = CACHE_SIZE_16KB; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     cache_ways = CACHE_4WAYS_ASSOC; | 
					
						
							| 
									
										
										
										
											2019-06-10 15:07:12 +08:00
										 |  |  | #if CONFIG_ESP32S2_DATA_CACHE_LINE_16B
 | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  |     cache_line_size = CACHE_LINE_SIZE_16B; | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2020-01-07 16:58:14 +08:00
										 |  |  |     cache_line_size = CACHE_LINE_SIZE_32B; | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2024-01-04 12:03:53 +08:00
										 |  |  |     ESP_EARLY_LOGI(TAG, "Data cache \t\t: size %dKB, %dWays, cache line size %dByte", (cache_size == CACHE_SIZE_0KB) ? 0 : ((cache_size == CACHE_SIZE_8KB) ? 8 : 16), 4, cache_line_size == CACHE_LINE_SIZE_16B ? 16 : 32); | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  |     Cache_Set_DCache_Mode(cache_size, cache_ways, cache_line_size); | 
					
						
							|  |  |  |     Cache_Invalidate_DCache_All(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static IRAM_ATTR void esp_enable_cache_flash_wrap(bool icache, bool dcache) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     uint32_t i_autoload, d_autoload; | 
					
						
							|  |  |  |     if (icache) { | 
					
						
							|  |  |  |         i_autoload = Cache_Suspend_ICache(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (dcache) { | 
					
						
							|  |  |  |         d_autoload = Cache_Suspend_DCache(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-12-26 15:25:24 +08:00
										 |  |  |     REG_SET_BIT(EXTMEM_PRO_CACHE_WRAP_AROUND_CTRL_REG, EXTMEM_PRO_CACHE_FLASH_WRAP_AROUND); | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  |     if (icache) { | 
					
						
							|  |  |  |         Cache_Resume_ICache(i_autoload); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (dcache) { | 
					
						
							|  |  |  |         Cache_Resume_DCache(d_autoload); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-10 12:27:36 +08:00
										 |  |  | #if (CONFIG_IDF_TARGET_ESP32S2 && CONFIG_SPIRAM)
 | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  | static IRAM_ATTR void esp_enable_cache_spiram_wrap(bool icache, bool dcache) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     uint32_t i_autoload, d_autoload; | 
					
						
							|  |  |  |     if (icache) { | 
					
						
							|  |  |  |         i_autoload = Cache_Suspend_ICache(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (dcache) { | 
					
						
							|  |  |  |         d_autoload = Cache_Suspend_DCache(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-01-07 16:58:14 +08:00
										 |  |  |     REG_SET_BIT(EXTMEM_PRO_CACHE_WRAP_AROUND_CTRL_REG, EXTMEM_PRO_CACHE_SRAM_RD_WRAP_AROUND); | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  |     if (icache) { | 
					
						
							|  |  |  |         Cache_Resume_ICache(i_autoload); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (dcache) { | 
					
						
							|  |  |  |         Cache_Resume_DCache(d_autoload); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable, bool dcache_wrap_enable) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int icache_wrap_size = 0, dcache_wrap_size = 0; | 
					
						
							| 
									
										
										
										
											2019-12-26 15:25:24 +08:00
										 |  |  |     int flash_wrap_sizes[2] = {-1, -1}, spiram_wrap_sizes[2] = {-1, -1}; | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  |     int flash_wrap_size = 0, spiram_wrap_size = 0; | 
					
						
							|  |  |  |     int flash_count = 0, spiram_count = 0; | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  |     bool flash_spiram_wrap_together, flash_support_wrap = true, spiram_support_wrap = true; | 
					
						
							| 
									
										
										
										
											2019-12-26 15:25:24 +08:00
										 |  |  |     uint32_t drom0_in_icache = 1;//always 1 in esp32s2
 | 
					
						
							| 
									
										
										
										
											2024-03-13 14:24:43 +08:00
										 |  |  | #if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C61 //TODO: [ESP32C61] IDF-9253
 | 
					
						
							| 
									
										
										
										
											2020-07-29 13:13:51 +08:00
										 |  |  |     drom0_in_icache = 0; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2020-01-07 16:58:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  |     if (icache_wrap_enable) { | 
					
						
							| 
									
										
										
										
											2022-03-15 18:25:05 +08:00
										 |  |  | #if CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_16B || CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_16B
 | 
					
						
							| 
									
										
										
										
											2023-02-10 14:51:11 +08:00
										 |  |  |         icache_wrap_size = FLASH_WRAP_SIZE_16B; | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2023-02-10 14:51:11 +08:00
										 |  |  |         icache_wrap_size = FLASH_WRAP_SIZE_32B; | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (dcache_wrap_enable) { | 
					
						
							| 
									
										
										
										
											2022-03-15 18:25:05 +08:00
										 |  |  | #if CONFIG_ESP32S2_DATA_CACHE_LINE_16B || CONFIG_ESP32S3_DATA_CACHE_LINE_16B
 | 
					
						
							| 
									
										
										
										
											2023-02-10 14:51:11 +08:00
										 |  |  |         dcache_wrap_size = FLASH_WRAP_SIZE_16B; | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2023-02-10 14:51:11 +08:00
										 |  |  |         dcache_wrap_size = FLASH_WRAP_SIZE_32B; | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     uint32_t instruction_use_spiram = 0; | 
					
						
							|  |  |  |     uint32_t rodata_use_spiram = 0; | 
					
						
							| 
									
										
										
										
											2019-08-22 14:17:46 +08:00
										 |  |  | #if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
 | 
					
						
							| 
									
										
										
										
											2020-05-21 17:34:21 +08:00
										 |  |  |     extern uint32_t esp_spiram_instruction_access_enabled(void); | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  |     instruction_use_spiram = esp_spiram_instruction_access_enabled(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-08-22 14:17:46 +08:00
										 |  |  | #if CONFIG_SPIRAM_RODATA
 | 
					
						
							| 
									
										
										
										
											2020-05-21 17:34:21 +08:00
										 |  |  |     extern uint32_t esp_spiram_rodata_access_enabled(void); | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  |     rodata_use_spiram = esp_spiram_rodata_access_enabled(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (instruction_use_spiram) { | 
					
						
							|  |  |  |         spiram_wrap_sizes[0] = icache_wrap_size; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         flash_wrap_sizes[0] = icache_wrap_size; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (rodata_use_spiram) { | 
					
						
							| 
									
										
										
										
											2019-12-26 15:25:24 +08:00
										 |  |  |         if (drom0_in_icache) { | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  |             spiram_wrap_sizes[0] = icache_wrap_size; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             spiram_wrap_sizes[1] = dcache_wrap_size; | 
					
						
							| 
									
										
										
										
											2019-11-05 13:03:33 +08:00
										 |  |  |             flash_wrap_sizes[1] = dcache_wrap_size; | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  |         } | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2019-12-26 15:25:24 +08:00
										 |  |  |         if (drom0_in_icache) { | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  |             flash_wrap_sizes[0] = icache_wrap_size; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             flash_wrap_sizes[1] = dcache_wrap_size; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-05-10 12:27:36 +08:00
										 |  |  | #if (CONFIG_IDF_TARGET_ESP32S2 && CONFIG_SPIRAM)
 | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  |     spiram_wrap_sizes[1] = dcache_wrap_size; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     for (i = 0; i < 2; i++) { | 
					
						
							|  |  |  |         if (flash_wrap_sizes[i] != -1) { | 
					
						
							|  |  |  |             flash_count++; | 
					
						
							|  |  |  |             flash_wrap_size = flash_wrap_sizes[i]; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     for (i = 0; i < 2; i++) { | 
					
						
							|  |  |  |         if (spiram_wrap_sizes[i] != -1) { | 
					
						
							|  |  |  |             spiram_count++; | 
					
						
							|  |  |  |             spiram_wrap_size = spiram_wrap_sizes[i]; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (flash_count + spiram_count <= 2) { | 
					
						
							|  |  |  |         flash_spiram_wrap_together = false; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         flash_spiram_wrap_together = true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-08-22 14:17:46 +08:00
										 |  |  |     ESP_EARLY_LOGI(TAG, "flash_count=%d, size=%d, spiram_count=%d, size=%d,together=%d", flash_count, flash_wrap_size, spiram_count, spiram_wrap_size, flash_spiram_wrap_together); | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  |     if (flash_count > 1 && flash_wrap_sizes[0] != flash_wrap_sizes[1]) { | 
					
						
							|  |  |  |         ESP_EARLY_LOGW(TAG, "Flash wrap with different length %d and %d, abort wrap.", flash_wrap_sizes[0], flash_wrap_sizes[1]); | 
					
						
							|  |  |  |         if (spiram_wrap_size == 0) { | 
					
						
							|  |  |  |             return ESP_FAIL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (flash_spiram_wrap_together) { | 
					
						
							|  |  |  |             ESP_EARLY_LOGE(TAG, "Abort spiram wrap because flash wrap length not fixed."); | 
					
						
							|  |  |  |             return ESP_FAIL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (spiram_count > 1 && spiram_wrap_sizes[0] != spiram_wrap_sizes[1]) { | 
					
						
							|  |  |  |         ESP_EARLY_LOGW(TAG, "SPIRAM wrap with different length %d and %d, abort wrap.", spiram_wrap_sizes[0], spiram_wrap_sizes[1]); | 
					
						
							|  |  |  |         if (flash_wrap_size == 0) { | 
					
						
							|  |  |  |             return ESP_FAIL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (flash_spiram_wrap_together) { | 
					
						
							|  |  |  |             ESP_EARLY_LOGW(TAG, "Abort flash wrap because spiram wrap length not fixed."); | 
					
						
							|  |  |  |             return ESP_FAIL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (flash_spiram_wrap_together && flash_wrap_size != spiram_wrap_size) { | 
					
						
							|  |  |  |         ESP_EARLY_LOGW(TAG, "SPIRAM has different wrap length with flash, %d and %d, abort wrap.", spiram_wrap_size, flash_wrap_size); | 
					
						
							|  |  |  |         return ESP_FAIL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-15 16:28:53 +08:00
										 |  |  | #ifdef CONFIG_ESPTOOLPY_FLASHMODE_QIO
 | 
					
						
							| 
									
										
										
										
											2020-01-07 16:58:14 +08:00
										 |  |  |     flash_support_wrap = true; | 
					
						
							| 
									
										
										
										
											2023-02-14 11:47:56 +08:00
										 |  |  |     spi_flash_wrap_probe(); | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  |     if (!spi_flash_support_wrap_size(flash_wrap_size)) { | 
					
						
							|  |  |  |         flash_support_wrap = false; | 
					
						
							|  |  |  |         ESP_EARLY_LOGW(TAG, "Flash do not support wrap size %d.", flash_wrap_size); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-01-07 16:58:14 +08:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2020-07-29 13:13:51 +08:00
										 |  |  |     ESP_EARLY_LOGW(TAG, "Flash is not in QIO mode, do not support wrap."); | 
					
						
							| 
									
										
										
										
											2020-01-07 16:58:14 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-10 12:27:36 +08:00
										 |  |  | #if (CONFIG_IDF_TARGET_ESP32S2 && CONFIG_SPIRAM)
 | 
					
						
							| 
									
										
										
										
											2019-12-26 15:25:24 +08:00
										 |  |  |     extern bool psram_support_wrap_size(uint32_t wrap_size); | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  |     if (!psram_support_wrap_size(spiram_wrap_size)) { | 
					
						
							|  |  |  |         spiram_support_wrap = false; | 
					
						
							|  |  |  |         ESP_EARLY_LOGW(TAG, "SPIRAM do not support wrap size %d.", spiram_wrap_size); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (flash_spiram_wrap_together && !(flash_support_wrap && spiram_support_wrap)) { | 
					
						
							|  |  |  |         ESP_EARLY_LOGW(TAG, "Flash and SPIRAM should support wrap together."); | 
					
						
							|  |  |  |         return ESP_FAIL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (flash_support_wrap && flash_wrap_size > 0) { | 
					
						
							| 
									
										
										
										
											2020-01-07 16:58:14 +08:00
										 |  |  |         ESP_EARLY_LOGI(TAG, "Flash wrap enabled, size = %d.", flash_wrap_size); | 
					
						
							| 
									
										
										
										
											2023-02-14 11:47:56 +08:00
										 |  |  |         spi_flash_wrap_enable(flash_wrap_size); | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  |         esp_enable_cache_flash_wrap((flash_wrap_sizes[0] > 0), (flash_wrap_sizes[1] > 0)); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-05-10 12:27:36 +08:00
										 |  |  | #if (CONFIG_IDF_TARGET_ESP32S2 && CONFIG_SPIRAM)
 | 
					
						
							| 
									
										
										
										
											2019-12-26 15:25:24 +08:00
										 |  |  |     extern esp_err_t psram_enable_wrap(uint32_t wrap_size); | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  |     if (spiram_support_wrap && spiram_wrap_size > 0) { | 
					
						
							| 
									
										
										
										
											2020-01-07 16:58:14 +08:00
										 |  |  |         ESP_EARLY_LOGI(TAG, "SPIRAM wrap enabled, size = %d.", spiram_wrap_size); | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  |         psram_enable_wrap(spiram_wrap_size); | 
					
						
							|  |  |  |         esp_enable_cache_spiram_wrap((spiram_wrap_sizes[0] > 0), (spiram_wrap_sizes[1] > 0)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return ESP_OK; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-29 13:13:51 +08:00
										 |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #if CONFIG_IDF_TARGET_ESP32S3
 | 
					
						
							|  |  |  | IRAM_ATTR void esp_config_instruction_cache_mode(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     cache_size_t cache_size; | 
					
						
							|  |  |  |     cache_ways_t cache_ways; | 
					
						
							|  |  |  |     cache_line_size_t cache_line_size; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if CONFIG_ESP32S3_INSTRUCTION_CACHE_16KB
 | 
					
						
							|  |  |  |     Cache_Occupy_ICache_MEMORY(CACHE_MEMORY_IBANK0, CACHE_MEMORY_INVALID); | 
					
						
							|  |  |  |     cache_size = CACHE_SIZE_HALF; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     Cache_Occupy_ICache_MEMORY(CACHE_MEMORY_IBANK0, CACHE_MEMORY_IBANK1); | 
					
						
							|  |  |  |     cache_size = CACHE_SIZE_FULL; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #if CONFIG_ESP32S3_INSTRUCTION_CACHE_4WAYS
 | 
					
						
							|  |  |  |     cache_ways = CACHE_4WAYS_ASSOC; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     cache_ways = CACHE_8WAYS_ASSOC; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #if CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_16B
 | 
					
						
							|  |  |  |     cache_line_size = CACHE_LINE_SIZE_16B; | 
					
						
							|  |  |  | #elif CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_32B
 | 
					
						
							|  |  |  |     cache_line_size = CACHE_LINE_SIZE_32B; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     cache_line_size = CACHE_LINE_SIZE_64B; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     ESP_EARLY_LOGI(TAG, "Instruction cache: size %dKB, %dWays, cache line size %dByte", cache_size == CACHE_SIZE_HALF ? 16 : 32, cache_ways == CACHE_4WAYS_ASSOC ? 4 : 8, cache_line_size == CACHE_LINE_SIZE_16B ? 16 : (cache_line_size == CACHE_LINE_SIZE_32B ? 32 : 64)); | 
					
						
							|  |  |  |     Cache_Set_ICache_Mode(cache_size, cache_ways, cache_line_size); | 
					
						
							|  |  |  |     Cache_Invalidate_ICache_All(); | 
					
						
							|  |  |  |     extern void Cache_Enable_ICache(uint32_t autoload); | 
					
						
							|  |  |  |     Cache_Enable_ICache(0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | IRAM_ATTR void esp_config_data_cache_mode(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     cache_size_t cache_size; | 
					
						
							|  |  |  |     cache_ways_t cache_ways; | 
					
						
							|  |  |  |     cache_line_size_t cache_line_size; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if CONFIG_ESP32S3_DATA_CACHE_32KB
 | 
					
						
							|  |  |  |     Cache_Occupy_DCache_MEMORY(CACHE_MEMORY_DBANK1, CACHE_MEMORY_INVALID); | 
					
						
							|  |  |  |     cache_size = CACHE_SIZE_HALF; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     Cache_Occupy_DCache_MEMORY(CACHE_MEMORY_DBANK0, CACHE_MEMORY_DBANK1); | 
					
						
							|  |  |  |     cache_size = CACHE_SIZE_FULL; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #if CONFIG_ESP32S3_DATA_CACHE_4WAYS
 | 
					
						
							|  |  |  |     cache_ways = CACHE_4WAYS_ASSOC; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     cache_ways = CACHE_8WAYS_ASSOC; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #if CONFIG_ESP32S3_DATA_CACHE_LINE_16B
 | 
					
						
							|  |  |  |     cache_line_size = CACHE_LINE_SIZE_16B; | 
					
						
							|  |  |  | #elif CONFIG_ESP32S3_DATA_CACHE_LINE_32B
 | 
					
						
							|  |  |  |     cache_line_size = CACHE_LINE_SIZE_32B; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     cache_line_size = CACHE_LINE_SIZE_64B; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     // ESP_EARLY_LOGI(TAG, "Data cache: size %dKB, %dWays, cache line size %dByte", cache_size == CACHE_SIZE_HALF ? 32 : 64, cache_ways == CACHE_4WAYS_ASSOC ? 4 : 8, cache_line_size == CACHE_LINE_SIZE_16B ? 16 : (cache_line_size == CACHE_LINE_SIZE_32B ? 32 : 64));
 | 
					
						
							|  |  |  |     Cache_Set_DCache_Mode(cache_size, cache_ways, cache_line_size); | 
					
						
							|  |  |  |     Cache_Invalidate_DCache_All(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static IRAM_ATTR void esp_enable_cache_flash_wrap(bool icache, bool dcache) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     uint32_t i_autoload, d_autoload; | 
					
						
							|  |  |  |     if (icache) { | 
					
						
							|  |  |  |         i_autoload = Cache_Suspend_ICache(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (dcache) { | 
					
						
							|  |  |  |         d_autoload = Cache_Suspend_DCache(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     REG_SET_BIT(EXTMEM_CACHE_WRAP_AROUND_CTRL_REG, EXTMEM_CACHE_FLASH_WRAP_AROUND); | 
					
						
							|  |  |  |     if (icache) { | 
					
						
							|  |  |  |         Cache_Resume_ICache(i_autoload); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (dcache) { | 
					
						
							|  |  |  |         Cache_Resume_DCache(d_autoload); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-10 12:27:36 +08:00
										 |  |  | #if (CONFIG_IDF_TARGET_ESP32S3 && CONFIG_SPIRAM)
 | 
					
						
							| 
									
										
										
										
											2020-07-29 13:13:51 +08:00
										 |  |  | static IRAM_ATTR void esp_enable_cache_spiram_wrap(bool icache, bool dcache) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     uint32_t i_autoload, d_autoload; | 
					
						
							|  |  |  |     if (icache) { | 
					
						
							|  |  |  |         i_autoload = Cache_Suspend_ICache(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (dcache) { | 
					
						
							|  |  |  |         d_autoload = Cache_Suspend_DCache(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     REG_SET_BIT(EXTMEM_CACHE_WRAP_AROUND_CTRL_REG, EXTMEM_CACHE_SRAM_RD_WRAP_AROUND); | 
					
						
							|  |  |  |     if (icache) { | 
					
						
							|  |  |  |         Cache_Resume_ICache(i_autoload); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (dcache) { | 
					
						
							|  |  |  |         Cache_Resume_DCache(d_autoload); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable, bool dcache_wrap_enable) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int icache_wrap_size = 0, dcache_wrap_size = 0; | 
					
						
							|  |  |  |     int flash_wrap_sizes[2] = {-1, -1}, spiram_wrap_sizes[2] = {-1, -1}; | 
					
						
							|  |  |  |     int flash_wrap_size = 0, spiram_wrap_size = 0; | 
					
						
							|  |  |  |     int flash_count = 0, spiram_count = 0; | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  |     bool flash_spiram_wrap_together, flash_support_wrap = false, spiram_support_wrap = true; | 
					
						
							|  |  |  |     uint32_t drom0_in_icache = 0;//always 0 in chip7.2.4
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (icache_wrap_enable) { | 
					
						
							|  |  |  | #if CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_16B
 | 
					
						
							| 
									
										
										
										
											2023-02-10 14:51:11 +08:00
										 |  |  |         icache_wrap_size = FLASH_WRAP_SIZE_16B; | 
					
						
							| 
									
										
										
										
											2020-07-29 13:13:51 +08:00
										 |  |  | #elif CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_32B
 | 
					
						
							| 
									
										
										
										
											2023-02-10 14:51:11 +08:00
										 |  |  |         icache_wrap_size = FLASH_WRAP_SIZE_32B; | 
					
						
							| 
									
										
										
										
											2020-07-29 13:13:51 +08:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2023-02-10 14:51:11 +08:00
										 |  |  |         icache_wrap_size = FLASH_WRAP_SIZE_64B; | 
					
						
							| 
									
										
										
										
											2020-07-29 13:13:51 +08:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (dcache_wrap_enable) { | 
					
						
							|  |  |  | #if CONFIG_ESP32S3_DATA_CACHE_LINE_16B
 | 
					
						
							| 
									
										
										
										
											2023-02-10 14:51:11 +08:00
										 |  |  |         dcache_wrap_size = FLASH_WRAP_SIZE_16B; | 
					
						
							| 
									
										
										
										
											2020-07-29 13:13:51 +08:00
										 |  |  | #elif CONFIG_ESP32S3_DATA_CACHE_LINE_32B
 | 
					
						
							| 
									
										
										
										
											2023-02-10 14:51:11 +08:00
										 |  |  |         dcache_wrap_size = FLASH_WRAP_SIZE_32B; | 
					
						
							| 
									
										
										
										
											2020-07-29 13:13:51 +08:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2023-02-10 14:51:11 +08:00
										 |  |  |         dcache_wrap_size = FLASH_WRAP_SIZE_64B; | 
					
						
							| 
									
										
										
										
											2020-07-29 13:13:51 +08:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     uint32_t instruction_use_spiram = 0; | 
					
						
							|  |  |  |     uint32_t rodata_use_spiram = 0; | 
					
						
							|  |  |  | #if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
 | 
					
						
							| 
									
										
										
										
											2022-01-05 12:40:26 +08:00
										 |  |  |     extern uint32_t esp_spiram_instruction_access_enabled(void); | 
					
						
							| 
									
										
										
										
											2020-07-29 13:13:51 +08:00
										 |  |  |     instruction_use_spiram = esp_spiram_instruction_access_enabled(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #if CONFIG_SPIRAM_RODATA
 | 
					
						
							| 
									
										
										
										
											2022-01-05 12:40:26 +08:00
										 |  |  |     extern uint32_t esp_spiram_rodata_access_enabled(void); | 
					
						
							| 
									
										
										
										
											2020-07-29 13:13:51 +08:00
										 |  |  |     rodata_use_spiram = esp_spiram_rodata_access_enabled(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (instruction_use_spiram) { | 
					
						
							|  |  |  |         spiram_wrap_sizes[0] = icache_wrap_size; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         flash_wrap_sizes[0] = icache_wrap_size; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (rodata_use_spiram) { | 
					
						
							|  |  |  |         if (drom0_in_icache) { | 
					
						
							|  |  |  |             spiram_wrap_sizes[0] = icache_wrap_size; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             spiram_wrap_sizes[1] = dcache_wrap_size; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         if (drom0_in_icache) { | 
					
						
							|  |  |  |             flash_wrap_sizes[0] = icache_wrap_size; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             flash_wrap_sizes[1] = dcache_wrap_size; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-05-10 12:27:36 +08:00
										 |  |  | #if (CONFIG_IDF_TARGET_ESP32S3 && CONFIG_SPIRAM)
 | 
					
						
							| 
									
										
										
										
											2020-07-29 13:13:51 +08:00
										 |  |  |     spiram_wrap_sizes[1] = dcache_wrap_size; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     for (i = 0; i < 2; i++) { | 
					
						
							|  |  |  |         if (flash_wrap_sizes[i] != -1) { | 
					
						
							|  |  |  |             flash_count++; | 
					
						
							|  |  |  |             flash_wrap_size = flash_wrap_sizes[i]; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     for (i = 0; i < 2; i++) { | 
					
						
							|  |  |  |         if (spiram_wrap_sizes[i] != -1) { | 
					
						
							|  |  |  |             spiram_count++; | 
					
						
							|  |  |  |             spiram_wrap_size = spiram_wrap_sizes[i]; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (flash_count + spiram_count <= 2) { | 
					
						
							|  |  |  |         flash_spiram_wrap_together = false; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         flash_spiram_wrap_together = true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (flash_count > 1 && flash_wrap_sizes[0] != flash_wrap_sizes[1]) { | 
					
						
							|  |  |  |         ESP_EARLY_LOGW(TAG, "Flash wrap with different length %d and %d, abort wrap.", flash_wrap_sizes[0], flash_wrap_sizes[1]); | 
					
						
							|  |  |  |         if (spiram_wrap_size == 0) { | 
					
						
							|  |  |  |             return ESP_FAIL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (flash_spiram_wrap_together) { | 
					
						
							|  |  |  |             ESP_EARLY_LOGE(TAG, "Abort spiram wrap because flash wrap length not fixed."); | 
					
						
							|  |  |  |             return ESP_FAIL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (spiram_count > 1 && spiram_wrap_sizes[0] != spiram_wrap_sizes[1]) { | 
					
						
							|  |  |  |         ESP_EARLY_LOGW(TAG, "SPIRAM wrap with different length %d and %d, abort wrap.", spiram_wrap_sizes[0], spiram_wrap_sizes[1]); | 
					
						
							|  |  |  |         if (flash_wrap_size == 0) { | 
					
						
							|  |  |  |             return ESP_FAIL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (flash_spiram_wrap_together) { | 
					
						
							|  |  |  |             ESP_EARLY_LOGW(TAG, "Abort flash wrap because spiram wrap length not fixed."); | 
					
						
							|  |  |  |             return ESP_FAIL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (flash_spiram_wrap_together && flash_wrap_size != spiram_wrap_size) { | 
					
						
							|  |  |  |         ESP_EARLY_LOGW(TAG, "SPIRAM has different wrap length with flash, %d and %d, abort wrap.", spiram_wrap_size, flash_wrap_size); | 
					
						
							|  |  |  |         return ESP_FAIL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-15 16:28:53 +08:00
										 |  |  | #ifdef CONFIG_ESPTOOLPY_FLASHMODE_QIO
 | 
					
						
							| 
									
										
										
										
											2020-07-29 13:13:51 +08:00
										 |  |  |     flash_support_wrap = true; | 
					
						
							| 
									
										
										
										
											2023-02-14 11:47:56 +08:00
										 |  |  |     spi_flash_wrap_probe(); | 
					
						
							| 
									
										
										
										
											2020-07-29 13:13:51 +08:00
										 |  |  |     if (!spi_flash_support_wrap_size(flash_wrap_size)) { | 
					
						
							|  |  |  |         flash_support_wrap = false; | 
					
						
							|  |  |  |         ESP_EARLY_LOGW(TAG, "Flash do not support wrap size %d.", flash_wrap_size); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     ESP_EARLY_LOGW(TAG, "Flash is not in QIO mode, do not support wrap."); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-10 12:27:36 +08:00
										 |  |  | #if (CONFIG_IDF_TARGET_ESP32S3 && CONFIG_SPIRAM)
 | 
					
						
							| 
									
										
										
										
											2020-07-29 13:13:51 +08:00
										 |  |  |     extern bool psram_support_wrap_size(uint32_t wrap_size); | 
					
						
							|  |  |  |     if (!psram_support_wrap_size(spiram_wrap_size)) { | 
					
						
							|  |  |  |         spiram_support_wrap = false; | 
					
						
							|  |  |  |         ESP_EARLY_LOGW(TAG, "SPIRAM do not support wrap size %d.", spiram_wrap_size); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (flash_spiram_wrap_together && !(flash_support_wrap && spiram_support_wrap)) { | 
					
						
							|  |  |  |         ESP_EARLY_LOGW(TAG, "Flash and SPIRAM should support wrap together."); | 
					
						
							|  |  |  |         return ESP_FAIL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (flash_support_wrap && flash_wrap_size > 0) { | 
					
						
							|  |  |  |         ESP_EARLY_LOGI(TAG, "Flash wrap enabled, size = %d.", flash_wrap_size); | 
					
						
							| 
									
										
										
										
											2023-02-14 11:47:56 +08:00
										 |  |  |         spi_flash_wrap_enable(flash_wrap_size); | 
					
						
							| 
									
										
										
										
											2020-07-29 13:13:51 +08:00
										 |  |  |         esp_enable_cache_flash_wrap((flash_wrap_sizes[0] > 0), (flash_wrap_sizes[1] > 0)); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-05-10 12:27:36 +08:00
										 |  |  | #if (CONFIG_IDF_TARGET_ESP32S3 && CONFIG_SPIRAM)
 | 
					
						
							| 
									
										
										
										
											2020-07-29 13:13:51 +08:00
										 |  |  |     extern esp_err_t psram_enable_wrap(uint32_t wrap_size); | 
					
						
							|  |  |  |     if (spiram_support_wrap && spiram_wrap_size > 0) { | 
					
						
							|  |  |  |         ESP_EARLY_LOGI(TAG, "SPIRAM wrap enabled, size = %d.", spiram_wrap_size); | 
					
						
							|  |  |  |         psram_enable_wrap(spiram_wrap_size); | 
					
						
							|  |  |  |         esp_enable_cache_spiram_wrap((spiram_wrap_sizes[0] > 0), (spiram_wrap_sizes[1] > 0)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return ESP_OK; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-06 10:57:29 +08:00
										 |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-09-16 10:56:48 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-13 14:32:25 +08:00
										 |  |  | #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2
 | 
					
						
							| 
									
										
										
										
											2020-12-16 14:50:13 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  | static IRAM_ATTR void esp_enable_cache_flash_wrap(bool icache) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     uint32_t i_autoload; | 
					
						
							|  |  |  |     if (icache) { | 
					
						
							|  |  |  |         i_autoload = Cache_Suspend_ICache(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     REG_SET_BIT(EXTMEM_CACHE_WRAP_AROUND_CTRL_REG, EXTMEM_CACHE_FLASH_WRAP_AROUND); | 
					
						
							|  |  |  |     if (icache) { | 
					
						
							|  |  |  |         Cache_Resume_ICache(i_autoload); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int flash_wrap_size = 0; | 
					
						
							|  |  |  |     bool flash_support_wrap = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (icache_wrap_enable) { | 
					
						
							|  |  |  |         flash_wrap_size = 32; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-15 16:28:53 +08:00
										 |  |  | #ifdef CONFIG_ESPTOOLPY_FLASHMODE_QIO
 | 
					
						
							| 
									
										
										
										
											2020-12-16 14:50:13 +11:00
										 |  |  |     flash_support_wrap = true; | 
					
						
							| 
									
										
										
										
											2023-02-14 11:47:56 +08:00
										 |  |  |     spi_flash_wrap_probe(); | 
					
						
							| 
									
										
										
										
											2020-12-16 14:50:13 +11:00
										 |  |  |     if (!spi_flash_support_wrap_size(flash_wrap_size)) { | 
					
						
							|  |  |  |         flash_support_wrap = false; | 
					
						
							|  |  |  |         ESP_EARLY_LOGW(TAG, "Flash do not support wrap size %d.", flash_wrap_size); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     ESP_EARLY_LOGW(TAG, "Flash is not in QIO mode, do not support wrap."); | 
					
						
							| 
									
										
										
										
											2022-03-15 16:28:53 +08:00
										 |  |  | #endif // CONFIG_ESPTOOLPY_FLASHMODE_QIO
 | 
					
						
							| 
									
										
										
										
											2020-12-16 14:50:13 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (flash_support_wrap && flash_wrap_size > 0) { | 
					
						
							|  |  |  |         ESP_EARLY_LOGI(TAG, "Flash wrap enabled, size = %d.", flash_wrap_size); | 
					
						
							| 
									
										
										
										
											2023-02-14 11:47:56 +08:00
										 |  |  |         spi_flash_wrap_enable(flash_wrap_size); | 
					
						
							| 
									
										
										
										
											2020-12-16 14:50:13 +11:00
										 |  |  |         esp_enable_cache_flash_wrap((flash_wrap_size > 0)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return ESP_OK; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-04-13 14:32:25 +08:00
										 |  |  | #endif // CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2
 | 
					
						
							| 
									
										
										
										
											2023-07-21 12:37:06 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if CONFIG_IDF_TARGET_ESP32P4
 | 
					
						
							|  |  |  | //TODO: IDF-5670
 | 
					
						
							| 
									
										
										
										
											2024-04-11 15:42:02 +08:00
										 |  |  | void IRAM_ATTR esp_config_l2_cache_mode(void) | 
					
						
							| 
									
										
										
										
											2023-07-21 12:37:06 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     cache_size_t cache_size; | 
					
						
							|  |  |  |     cache_line_size_t cache_line_size; | 
					
						
							| 
									
										
										
										
											2023-09-14 12:14:08 +08:00
										 |  |  | #if CONFIG_CACHE_L2_CACHE_128KB
 | 
					
						
							| 
									
										
										
										
											2023-07-21 12:37:06 +08:00
										 |  |  |     cache_size = CACHE_SIZE_128K; | 
					
						
							| 
									
										
										
										
											2023-09-14 12:14:08 +08:00
										 |  |  | #elif CONFIG_CACHE_L2_CACHE_256KB
 | 
					
						
							| 
									
										
										
										
											2023-07-21 12:37:06 +08:00
										 |  |  |     cache_size = CACHE_SIZE_256K; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     cache_size = CACHE_SIZE_512K; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-14 12:14:08 +08:00
										 |  |  | #if CONFIG_CACHE_L2_CACHE_LINE_64B
 | 
					
						
							| 
									
										
										
										
											2023-07-21 12:37:06 +08:00
										 |  |  |     cache_line_size = CACHE_LINE_SIZE_64B; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     cache_line_size = CACHE_LINE_SIZE_128B; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Cache_Set_L2_Cache_Mode(cache_size, 8, cache_line_size); | 
					
						
							|  |  |  |     Cache_Invalidate_All(CACHE_MAP_L2_CACHE); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 |