1 /*
2 * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <stdint.h>
10 #include <zephyr/kernel.h>
11
12 #include <zephyr/drivers/interrupt_controller/intc_esp32.h>
13 #if CONFIG_SOC_SERIES_ESP32S2
14 #include "esp32s2/rom/cache.h"
15 #include <soc/extmem_reg.h>
16 #include "soc/ext_mem_defs.h"
17 #elif CONFIG_SOC_SERIES_ESP32S3
18 #include "esp32s3/rom/cache.h"
19 #include "soc/extmem_reg.h"
20 #include "soc/ext_mem_defs.h"
21 #elif CONFIG_SOC_SERIES_ESP32C2
22 #include "esp32c2/rom/cache.h"
23 #include "soc/extmem_reg.h"
24 #include "soc/ext_mem_defs.h"
25 #elif CONFIG_SOC_SERIES_ESP32C3
26 #include "esp32c3/rom/cache.h"
27 #include "soc/extmem_reg.h"
28 #include "soc/ext_mem_defs.h"
29 #elif CONFIG_SOC_SERIES_ESP32C6
30 #include "esp32c6/rom/cache.h"
31 #include "soc/extmem_reg.h"
32 #include "soc/ext_mem_defs.h"
33 #endif
34
35 #include "esp_private/spi_flash_os.h"
36 #include "spi_flash_override.h"
37 #include "esp_rom_spiflash.h"
38 #include "hal/cache_hal.h"
39 #include "hal/cache_ll.h"
40 #include "hal/cpu_ll.h"
41 #include <soc/soc.h>
42 #include "esp_log.h"
43
44 static __attribute__((unused)) const char *TAG = "cache";
45
46 static void spi_flash_disable_cache(uint32_t cpuid, uint32_t *saved_state);
47 static void spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_state);
48
49 static uint32_t s_flash_op_cache_state[2];
50 static unsigned int s_intr_saved_state;
51
52 #ifndef CONFIG_MCUBOOT
53
54 K_MUTEX_DEFINE(s_flash_op_mutex);
55
spi_flash_init_lock(void)56 void spi_flash_init_lock(void)
57 {
58
59 }
60
spi_flash_op_lock(void)61 void spi_flash_op_lock(void)
62 {
63 k_mutex_lock(&s_flash_op_mutex, K_FOREVER);
64 }
65
spi_flash_op_unlock(void)66 void spi_flash_op_unlock(void)
67 {
68 k_mutex_unlock(&s_flash_op_mutex);
69 }
70
71 #endif
72
spi_flash_disable_interrupts_caches_and_other_cpu(void)73 void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu(void)
74 {
75 s_intr_saved_state = irq_lock();
76 #if !defined(CONFIG_SOC_SERIES_ESP32C2) && !defined(CONFIG_SOC_SERIES_ESP32C3) && \
77 !defined(CONFIG_SOC_SERIES_ESP32C6)
78 esp_intr_noniram_disable();
79 #endif
80
81 #if !defined(CONFIG_SOC_SERIES_ESP32C2) && !defined(CONFIG_SOC_SERIES_ESP32C3) && \
82 !defined(CONFIG_SOC_SERIES_ESP32C6)
83 int cpu_id = esp_cpu_get_core_id();
84 #else
85 int cpu_id = PRO_CPU_NUM;
86 #endif
87 spi_flash_disable_cache(cpu_id, &s_flash_op_cache_state[cpu_id]);
88
89 #ifdef CONFIG_SMP
90 int other_cpu = (cpu_id == PRO_CPU_NUM) ? APP_CPU_NUM : PRO_CPU_NUM;
91 spi_flash_disable_cache(other_cpu, &s_flash_op_cache_state[other_cpu]);
92 #endif
93 }
94
spi_flash_enable_interrupts_caches_and_other_cpu(void)95 void IRAM_ATTR spi_flash_enable_interrupts_caches_and_other_cpu(void)
96 {
97 #if !defined(CONFIG_SOC_SERIES_ESP32C2) && !defined(CONFIG_SOC_SERIES_ESP32C3) && \
98 !defined(CONFIG_SOC_SERIES_ESP32C6)
99 int cpu_id = esp_cpu_get_core_id();
100 #else
101 int cpu_id = PRO_CPU_NUM;
102 #endif
103 spi_flash_restore_cache(cpu_id, s_flash_op_cache_state[cpu_id]);
104
105 #if defined(CONFIG_SMP) && SOC_IDCACHE_PER_CORE
106 int other_cpu = (cpu_id == PRO_CPU_NUM) ? APP_CPU_NUM : PRO_CPU_NUM;
107 spi_flash_restore_cache(other_cpu, s_flash_op_cache_state[other_cpu]);
108 #endif
109
110 #if !defined(CONFIG_SOC_SERIES_ESP32C2) && !defined(CONFIG_SOC_SERIES_ESP32C3) && \
111 !defined(CONFIG_SOC_SERIES_ESP32C6)
112 esp_intr_noniram_enable();
113 #endif
114 irq_unlock(s_intr_saved_state);
115 }
116
spi_flash_enable_cache(uint32_t cpuid)117 void IRAM_ATTR spi_flash_enable_cache(uint32_t cpuid)
118 {
119 #if CONFIG_IDF_TARGET_ESP32
120 uint32_t cache_value = cache_ll_l1_get_enabled_bus(cpuid);
121
122 // Re-enable cache on this CPU
123 spi_flash_restore_cache(cpuid, cache_value);
124 #else
125 spi_flash_restore_cache(0, 0); // TODO cache_value should be non-zero
126 #endif
127 }
128
129 /**
130 * The following two functions are replacements for Cache_Read_Disable and Cache_Read_Enable
131 * function in ROM. They are used to work around a bug where Cache_Read_Disable requires a call to
132 * Cache_Flush before Cache_Read_Enable, even if cached data was not modified.
133 */
spi_flash_disable_cache(uint32_t cpuid,uint32_t * saved_state)134 static void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t *saved_state)
135 {
136 cache_hal_suspend(CACHE_TYPE_ALL);
137 }
138
spi_flash_restore_cache(uint32_t cpuid,uint32_t saved_state)139 static void IRAM_ATTR spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_state)
140 {
141 cache_hal_resume(CACHE_TYPE_ALL);
142 }
143
spi_flash_cache_enabled(void)144 bool IRAM_ATTR spi_flash_cache_enabled(void)
145 {
146 return cache_hal_is_cache_enabled(CACHE_TYPE_ALL);
147 }
148
149 #if CONFIG_IDF_TARGET_ESP32S2
esp_enable_cache_flash_wrap(bool icache,bool dcache)150 static IRAM_ATTR void esp_enable_cache_flash_wrap(bool icache, bool dcache)
151 {
152 uint32_t i_autoload, d_autoload;
153 if (icache) {
154 i_autoload = Cache_Suspend_ICache();
155 }
156 if (dcache) {
157 d_autoload = Cache_Suspend_DCache();
158 }
159 REG_SET_BIT(EXTMEM_PRO_CACHE_WRAP_AROUND_CTRL_REG, EXTMEM_PRO_CACHE_FLASH_WRAP_AROUND);
160 if (icache) {
161 Cache_Resume_ICache(i_autoload);
162 }
163 if (dcache) {
164 Cache_Resume_DCache(d_autoload);
165 }
166 }
167
168 #if (CONFIG_IDF_TARGET_ESP32S2 && CONFIG_SPIRAM)
esp_enable_cache_spiram_wrap(bool icache,bool dcache)169 static IRAM_ATTR void esp_enable_cache_spiram_wrap(bool icache, bool dcache)
170 {
171 uint32_t i_autoload, d_autoload;
172 if (icache) {
173 i_autoload = Cache_Suspend_ICache();
174 }
175 if (dcache) {
176 d_autoload = Cache_Suspend_DCache();
177 }
178 REG_SET_BIT(EXTMEM_PRO_CACHE_WRAP_AROUND_CTRL_REG, EXTMEM_PRO_CACHE_SRAM_RD_WRAP_AROUND);
179 if (icache) {
180 Cache_Resume_ICache(i_autoload);
181 }
182 if (dcache) {
183 Cache_Resume_DCache(d_autoload);
184 }
185 }
186 #endif
187
esp_enable_cache_wrap(bool icache_wrap_enable,bool dcache_wrap_enable)188 esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable, bool dcache_wrap_enable)
189 {
190 int icache_wrap_size = 0, dcache_wrap_size = 0;
191 int flash_wrap_sizes[2] = {-1, -1}, spiram_wrap_sizes[2] = {-1, -1};
192 int flash_wrap_size = 0, spiram_wrap_size = 0;
193 int flash_count = 0, spiram_count = 0;
194 int i;
195 bool flash_spiram_wrap_together, flash_support_wrap = true, spiram_support_wrap = true;
196 uint32_t drom0_in_icache = 1; // always 1 in esp32s2
197 #if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || \
198 CONFIG_IDF_TARGET_ESP32C6
199 drom0_in_icache = 0;
200 #endif
201
202 if (icache_wrap_enable) {
203 #if CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_16B || CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_16B
204 icache_wrap_size = FLASH_WRAP_SIZE_16B;
205 #else
206 icache_wrap_size = FLASH_WRAP_SIZE_32B;
207 #endif
208 }
209 if (dcache_wrap_enable) {
210 #if CONFIG_ESP32S2_DATA_CACHE_LINE_16B || CONFIG_ESP32S3_DATA_CACHE_LINE_16B
211 dcache_wrap_size = FLASH_WRAP_SIZE_16B;
212 #else
213 dcache_wrap_size = FLASH_WRAP_SIZE_32B;
214 #endif
215 }
216
217 uint32_t instruction_use_spiram = 0;
218 uint32_t rodata_use_spiram = 0;
219 #if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
220 extern uint32_t esp_spiram_instruction_access_enabled(void);
221 instruction_use_spiram = esp_spiram_instruction_access_enabled();
222 #endif
223 #if CONFIG_SPIRAM_RODATA
224 extern uint32_t esp_spiram_rodata_access_enabled(void);
225 rodata_use_spiram = esp_spiram_rodata_access_enabled();
226 #endif
227
228 if (instruction_use_spiram) {
229 spiram_wrap_sizes[0] = icache_wrap_size;
230 } else {
231 flash_wrap_sizes[0] = icache_wrap_size;
232 }
233 if (rodata_use_spiram) {
234 if (drom0_in_icache) {
235 spiram_wrap_sizes[0] = icache_wrap_size;
236 } else {
237 spiram_wrap_sizes[1] = dcache_wrap_size;
238 flash_wrap_sizes[1] = dcache_wrap_size;
239 }
240 } else {
241 if (drom0_in_icache) {
242 flash_wrap_sizes[0] = icache_wrap_size;
243 } else {
244 flash_wrap_sizes[1] = dcache_wrap_size;
245 }
246 }
247 #if (CONFIG_IDF_TARGET_ESP32S2 && CONFIG_SPIRAM)
248 spiram_wrap_sizes[1] = dcache_wrap_size;
249 #endif
250 for (i = 0; i < 2; i++) {
251 if (flash_wrap_sizes[i] != -1) {
252 flash_count++;
253 flash_wrap_size = flash_wrap_sizes[i];
254 }
255 }
256 for (i = 0; i < 2; i++) {
257 if (spiram_wrap_sizes[i] != -1) {
258 spiram_count++;
259 spiram_wrap_size = spiram_wrap_sizes[i];
260 }
261 }
262 if (flash_count + spiram_count <= 2) {
263 flash_spiram_wrap_together = false;
264 } else {
265 flash_spiram_wrap_together = true;
266 }
267 ESP_EARLY_LOGI(TAG, "flash_count=%d, size=%d, spiram_count=%d, size=%d,together=%d",
268 flash_count, flash_wrap_size, spiram_count, spiram_wrap_size,
269 flash_spiram_wrap_together);
270 if (flash_count > 1 && flash_wrap_sizes[0] != flash_wrap_sizes[1]) {
271 ESP_EARLY_LOGW(TAG, "Flash wrap with different length %d and %d, abort wrap.",
272 flash_wrap_sizes[0], flash_wrap_sizes[1]);
273 if (spiram_wrap_size == 0) {
274 return ESP_FAIL;
275 }
276 if (flash_spiram_wrap_together) {
277 ESP_EARLY_LOGE(TAG,
278 "Abort spiram wrap because flash wrap length not fixed.");
279 return ESP_FAIL;
280 }
281 }
282 if (spiram_count > 1 && spiram_wrap_sizes[0] != spiram_wrap_sizes[1]) {
283 ESP_EARLY_LOGW(TAG, "SPIRAM wrap with different length %d and %d, abort wrap.",
284 spiram_wrap_sizes[0], spiram_wrap_sizes[1]);
285 if (flash_wrap_size == 0) {
286 return ESP_FAIL;
287 }
288 if (flash_spiram_wrap_together) {
289 ESP_EARLY_LOGW(TAG,
290 "Abort flash wrap because spiram wrap length not fixed.");
291 return ESP_FAIL;
292 }
293 }
294
295 if (flash_spiram_wrap_together && flash_wrap_size != spiram_wrap_size) {
296 ESP_EARLY_LOGW(
297 TAG, "SPIRAM has different wrap length with flash, %d and %d, abort wrap.",
298 spiram_wrap_size, flash_wrap_size);
299 return ESP_FAIL;
300 }
301
302 #ifdef CONFIG_ESPTOOLPY_FLASHMODE_QIO
303 flash_support_wrap = true;
304 spi_flash_wrap_probe();
305 if (!spi_flash_support_wrap_size(flash_wrap_size)) {
306 flash_support_wrap = false;
307 ESP_EARLY_LOGW(TAG, "Flash do not support wrap size %d.", flash_wrap_size);
308 }
309 #else
310 ESP_EARLY_LOGW(TAG, "Flash is not in QIO mode, do not support wrap.");
311 #endif
312
313 #if (CONFIG_IDF_TARGET_ESP32S2 && CONFIG_SPIRAM)
314 extern bool psram_support_wrap_size(uint32_t wrap_size);
315 if (!psram_support_wrap_size(spiram_wrap_size)) {
316 spiram_support_wrap = false;
317 ESP_EARLY_LOGW(TAG, "SPIRAM do not support wrap size %d.", spiram_wrap_size);
318 }
319 #endif
320
321 if (flash_spiram_wrap_together && !(flash_support_wrap && spiram_support_wrap)) {
322 ESP_EARLY_LOGW(TAG, "Flash and SPIRAM should support wrap together.");
323 return ESP_FAIL;
324 }
325
326 if (flash_support_wrap && flash_wrap_size > 0) {
327 ESP_EARLY_LOGI(TAG, "Flash wrap enabled, size = %d.", flash_wrap_size);
328 spi_flash_wrap_enable(flash_wrap_size);
329 esp_enable_cache_flash_wrap((flash_wrap_sizes[0] > 0), (flash_wrap_sizes[1] > 0));
330 }
331 #if (CONFIG_IDF_TARGET_ESP32S2 && CONFIG_SPIRAM)
332 extern esp_err_t psram_enable_wrap(uint32_t wrap_size);
333 if (spiram_support_wrap && spiram_wrap_size > 0) {
334 ESP_EARLY_LOGI(TAG, "SPIRAM wrap enabled, size = %d.", spiram_wrap_size);
335 psram_enable_wrap(spiram_wrap_size);
336 esp_enable_cache_spiram_wrap((spiram_wrap_sizes[0] > 0),
337 (spiram_wrap_sizes[1] > 0));
338 }
339 #endif
340
341 return ESP_OK;
342 }
343 #endif
344 #if CONFIG_IDF_TARGET_ESP32S3
esp_enable_cache_flash_wrap(bool icache,bool dcache)345 static IRAM_ATTR void esp_enable_cache_flash_wrap(bool icache, bool dcache)
346 {
347 uint32_t i_autoload, d_autoload;
348 if (icache) {
349 i_autoload = Cache_Suspend_ICache();
350 }
351 if (dcache) {
352 d_autoload = Cache_Suspend_DCache();
353 }
354 REG_SET_BIT(EXTMEM_CACHE_WRAP_AROUND_CTRL_REG, EXTMEM_CACHE_FLASH_WRAP_AROUND);
355 if (icache) {
356 Cache_Resume_ICache(i_autoload);
357 }
358 if (dcache) {
359 Cache_Resume_DCache(d_autoload);
360 }
361 }
362
363 #if (CONFIG_IDF_TARGET_ESP32S3 && CONFIG_SPIRAM)
esp_enable_cache_spiram_wrap(bool icache,bool dcache)364 static IRAM_ATTR void esp_enable_cache_spiram_wrap(bool icache, bool dcache)
365 {
366 uint32_t i_autoload, d_autoload;
367 if (icache) {
368 i_autoload = Cache_Suspend_ICache();
369 }
370 if (dcache) {
371 d_autoload = Cache_Suspend_DCache();
372 }
373 REG_SET_BIT(EXTMEM_CACHE_WRAP_AROUND_CTRL_REG, EXTMEM_CACHE_SRAM_RD_WRAP_AROUND);
374 if (icache) {
375 Cache_Resume_ICache(i_autoload);
376 }
377 if (dcache) {
378 Cache_Resume_DCache(d_autoload);
379 }
380 }
381 #endif
382
esp_enable_cache_wrap(bool icache_wrap_enable,bool dcache_wrap_enable)383 esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable, bool dcache_wrap_enable)
384 {
385 int icache_wrap_size = 0, dcache_wrap_size = 0;
386 int flash_wrap_sizes[2] = {-1, -1}, spiram_wrap_sizes[2] = {-1, -1};
387 int flash_wrap_size = 0, spiram_wrap_size = 0;
388 int flash_count = 0, spiram_count = 0;
389 int i;
390 bool flash_spiram_wrap_together, flash_support_wrap = false, spiram_support_wrap = true;
391 uint32_t drom0_in_icache = 0;//always 0 in chip7.2.4
392
393 if (icache_wrap_enable) {
394 #if CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_16B
395 icache_wrap_size = FLASH_WRAP_SIZE_16B;
396 #elif CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_32B
397 icache_wrap_size = FLASH_WRAP_SIZE_32B;
398 #else
399 icache_wrap_size = FLASH_WRAP_SIZE_64B;
400 #endif
401 }
402 if (dcache_wrap_enable) {
403 #if CONFIG_ESP32S3_DATA_CACHE_LINE_16B
404 dcache_wrap_size = FLASH_WRAP_SIZE_16B;
405 #elif CONFIG_ESP32S3_DATA_CACHE_LINE_32B
406 dcache_wrap_size = FLASH_WRAP_SIZE_32B;
407 #else
408 dcache_wrap_size = FLASH_WRAP_SIZE_64B;
409 #endif
410 }
411
412 uint32_t instruction_use_spiram = 0;
413 uint32_t rodata_use_spiram = 0;
414 #if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
415 extern uint32_t esp_spiram_instruction_access_enabled(void);
416 instruction_use_spiram = esp_spiram_instruction_access_enabled();
417 #endif
418 #if CONFIG_SPIRAM_RODATA
419 extern uint32_t esp_spiram_rodata_access_enabled(void);
420 rodata_use_spiram = esp_spiram_rodata_access_enabled();
421 #endif
422
423 if (instruction_use_spiram) {
424 spiram_wrap_sizes[0] = icache_wrap_size;
425 } else {
426 flash_wrap_sizes[0] = icache_wrap_size;
427 }
428 if (rodata_use_spiram) {
429 if (drom0_in_icache) {
430 spiram_wrap_sizes[0] = icache_wrap_size;
431 } else {
432 spiram_wrap_sizes[1] = dcache_wrap_size;
433 }
434 } else {
435 if (drom0_in_icache) {
436 flash_wrap_sizes[0] = icache_wrap_size;
437 } else {
438 flash_wrap_sizes[1] = dcache_wrap_size;
439 }
440 }
441 #if (CONFIG_IDF_TARGET_ESP32S3 && CONFIG_SPIRAM)
442 spiram_wrap_sizes[1] = dcache_wrap_size;
443 #endif
444 for (i = 0; i < 2; i++) {
445 if (flash_wrap_sizes[i] != -1) {
446 flash_count++;
447 flash_wrap_size = flash_wrap_sizes[i];
448 }
449 }
450 for (i = 0; i < 2; i++) {
451 if (spiram_wrap_sizes[i] != -1) {
452 spiram_count++;
453 spiram_wrap_size = spiram_wrap_sizes[i];
454 }
455 }
456 if (flash_count + spiram_count <= 2) {
457 flash_spiram_wrap_together = false;
458 } else {
459 flash_spiram_wrap_together = true;
460 }
461 if (flash_count > 1 && flash_wrap_sizes[0] != flash_wrap_sizes[1]) {
462 ESP_EARLY_LOGW(TAG, "Flash wrap with different length %d and %d, abort wrap.", flash_wrap_sizes[0], flash_wrap_sizes[1]);
463 if (spiram_wrap_size == 0) {
464 return ESP_FAIL;
465 }
466 if (flash_spiram_wrap_together) {
467 ESP_EARLY_LOGE(TAG, "Abort spiram wrap because flash wrap length not fixed.");
468 return ESP_FAIL;
469 }
470 }
471 if (spiram_count > 1 && spiram_wrap_sizes[0] != spiram_wrap_sizes[1]) {
472 ESP_EARLY_LOGW(TAG, "SPIRAM wrap with different length %d and %d, abort wrap.", spiram_wrap_sizes[0], spiram_wrap_sizes[1]);
473 if (flash_wrap_size == 0) {
474 return ESP_FAIL;
475 }
476 if (flash_spiram_wrap_together) {
477 ESP_EARLY_LOGW(TAG, "Abort flash wrap because spiram wrap length not fixed.");
478 return ESP_FAIL;
479 }
480 }
481
482 if (flash_spiram_wrap_together && flash_wrap_size != spiram_wrap_size) {
483 ESP_EARLY_LOGW(TAG, "SPIRAM has different wrap length with flash, %d and %d, abort wrap.", spiram_wrap_size, flash_wrap_size);
484 return ESP_FAIL;
485 }
486
487 #ifdef CONFIG_ESPTOOLPY_FLASHMODE_QIO
488 flash_support_wrap = true;
489 spi_flash_wrap_probe();
490 if (!spi_flash_support_wrap_size(flash_wrap_size)) {
491 flash_support_wrap = false;
492 ESP_EARLY_LOGW(TAG, "Flash do not support wrap size %d.", flash_wrap_size);
493 }
494 #else
495 ESP_EARLY_LOGW(TAG, "Flash is not in QIO mode, do not support wrap.");
496 #endif
497
498
499 #if (CONFIG_IDF_TARGET_ESP32S3 && CONFIG_SPIRAM)
500 extern bool psram_support_wrap_size(uint32_t wrap_size);
501 if (!psram_support_wrap_size(spiram_wrap_size)) {
502 spiram_support_wrap = false;
503 ESP_EARLY_LOGW(TAG, "SPIRAM do not support wrap size %d.", spiram_wrap_size);
504 }
505 #endif
506
507 if (flash_spiram_wrap_together && !(flash_support_wrap && spiram_support_wrap)) {
508 ESP_EARLY_LOGW(TAG, "Flash and SPIRAM should support wrap together.");
509 return ESP_FAIL;
510 }
511
512 if (flash_support_wrap && flash_wrap_size > 0) {
513 ESP_EARLY_LOGI(TAG, "Flash wrap enabled, size = %d.", flash_wrap_size);
514 spi_flash_wrap_enable(flash_wrap_size);
515 esp_enable_cache_flash_wrap((flash_wrap_sizes[0] > 0), (flash_wrap_sizes[1] > 0));
516 }
517 #if (CONFIG_IDF_TARGET_ESP32S3 && CONFIG_SPIRAM)
518 extern esp_err_t psram_enable_wrap(uint32_t wrap_size);
519 if (spiram_support_wrap && spiram_wrap_size > 0) {
520 ESP_EARLY_LOGI(TAG, "SPIRAM wrap enabled, size = %d.", spiram_wrap_size);
521 psram_enable_wrap(spiram_wrap_size);
522 esp_enable_cache_spiram_wrap((spiram_wrap_sizes[0] > 0), (spiram_wrap_sizes[1] > 0));
523 }
524 #endif
525
526 return ESP_OK;
527
528 }
529 #endif
530
531 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2
532
esp_enable_cache_flash_wrap(bool icache)533 static IRAM_ATTR void esp_enable_cache_flash_wrap(bool icache)
534 {
535 uint32_t i_autoload;
536 if (icache) {
537 i_autoload = Cache_Suspend_ICache();
538 }
539 REG_SET_BIT(EXTMEM_CACHE_WRAP_AROUND_CTRL_REG, EXTMEM_CACHE_FLASH_WRAP_AROUND);
540 if (icache) {
541 Cache_Resume_ICache(i_autoload);
542 }
543 }
544
esp_enable_cache_wrap(bool icache_wrap_enable)545 esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable)
546 {
547 int flash_wrap_size = 0;
548 bool flash_support_wrap = false;
549
550 if (icache_wrap_enable) {
551 flash_wrap_size = 32;
552 }
553
554 #ifdef CONFIG_ESPTOOLPY_FLASHMODE_QIO
555 flash_support_wrap = true;
556 spi_flash_wrap_probe();
557 if (!spi_flash_support_wrap_size(flash_wrap_size)) {
558 flash_support_wrap = false;
559 ESP_EARLY_LOGW(TAG, "Flash do not support wrap size %d.", flash_wrap_size);
560 }
561 #else
562 ESP_EARLY_LOGW(TAG, "Flash is not in QIO mode, do not support wrap.");
563 #endif // CONFIG_ESPTOOLPY_FLASHMODE_QIO
564
565 if (flash_support_wrap && flash_wrap_size > 0) {
566 ESP_EARLY_LOGI(TAG, "Flash wrap enabled, size = %d.", flash_wrap_size);
567 spi_flash_wrap_enable(flash_wrap_size);
568 esp_enable_cache_flash_wrap((flash_wrap_size > 0));
569 }
570 return ESP_OK;
571 }
572 #endif // CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2
573