diff --git a/components/esp32/test/test_psram_cache_flush.c b/components/esp32/test/test_psram_cache_flush.c index 4c743ca6f..2e7792875 100644 --- a/components/esp32/test/test_psram_cache_flush.c +++ b/components/esp32/test/test_psram_cache_flush.c @@ -1,5 +1,5 @@ /* -This code triggers a psram-related silicon bug in rev0 silicon. The bug is fixed in rev1 silicon. +This code tests the interaction between PSRAM and SPI flash routines. */ #include @@ -29,47 +29,47 @@ This code triggers a psram-related silicon bug in rev0 silicon. The bug is fixed volatile static int res[2]; void tstMem(void *arg) { - volatile unsigned char *mem=(volatile unsigned char*)arg; - int p=0; - while(1) { - for (int i=0; ixTag != tag ) || ( pxBlock->xBlockSize < xWantedSize ) ) && ( pxBlock->pxNextFreeBlock != NULL ) ) { -// ets_printf("Block %x -> %x\n", (uint32_t)pxBlock, (uint32_t)pxBlock->pxNextFreeBlock); + ets_printf("Block %x -> %x\n", (uint32_t)pxBlock, (uint32_t)pxBlock->pxNextFreeBlock); #if (configENABLE_MEMORY_DEBUG == 1) { @@ -419,6 +419,9 @@ uint8_t *puc; than the block being inserted. */ for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) { + ets_printf("i %p\n", pxIterator); + ets_printf("n %p\n", pxIterator->pxNextFreeBlock); + /* Nothing to do here, just iterate to the right position. */ } diff --git a/components/spi_flash/cache_utils.c b/components/spi_flash/cache_utils.c index 3f87069aa..f57708314 100644 --- a/components/spi_flash/cache_utils.c +++ b/components/spi_flash/cache_utils.c @@ -30,6 +30,7 @@ #include "esp_intr_alloc.h" #include "esp_spi_flash.h" #include "esp_log.h" +#include "esp_psram.h" static void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t* saved_state); static void IRAM_ATTR spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_state); @@ -59,6 +60,13 @@ void spi_flash_op_unlock() xSemaphoreGive(s_flash_op_mutex); } +/* + If you're going to modify this, keep in mind that while the flash caches of the pro and app + cpu are separate, the psram cache is *not*. If one of the CPUs returns from a flash routine + with its cache enabled but the other CPUs cache is not enabled yet, you will have problems + when accessing psram from the former CPU. +*/ + void IRAM_ATTR spi_flash_op_block_func(void* arg) { // Disable scheduler on this CPU @@ -76,8 +84,6 @@ void IRAM_ATTR spi_flash_op_block_func(void* arg) while (!s_flash_op_complete) { // busy loop here and wait for the other CPU to finish flash operation } - // Flash operation is complete, re-enable cache - spi_flash_restore_cache(cpuid, s_flash_op_cache_state[cpuid]); // Restore interrupts that aren't located in IRAM esp_intr_noniram_enable(); // Re-enable scheduler @@ -110,8 +116,8 @@ void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu() esp_err_t ret = esp_ipc_call(other_cpuid, &spi_flash_op_block_func, (void*) other_cpuid); assert(ret == ESP_OK); while (!s_flash_op_can_start) { - // Busy loop and wait for spi_flash_op_block_func to disable cache - // on the other CPU + // Busy loop and wait for spi_flash_op_block_func to run so we can + // disable cache of the other CPU } // Disable scheduler on the current CPU vTaskSuspendAll(); @@ -121,8 +127,9 @@ void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu() } // Kill interrupts that aren't located in IRAM esp_intr_noniram_disable(); - // Disable cache on this CPU as well + // Disable cache on both CPUs as well spi_flash_disable_cache(cpuid, &s_flash_op_cache_state[cpuid]); + spi_flash_disable_cache(other_cpuid, &s_flash_op_cache_state[other_cpuid]); } void IRAM_ATTR spi_flash_enable_interrupts_caches_and_other_cpu() @@ -135,8 +142,9 @@ void IRAM_ATTR spi_flash_enable_interrupts_caches_and_other_cpu() s_flash_op_cpu = -1; #endif - // Re-enable cache on this CPU + // Re-enable cache on both CPUs spi_flash_restore_cache(cpuid, s_flash_op_cache_state[cpuid]); + spi_flash_restore_cache(other_cpuid, s_flash_op_cache_state[other_cpuid]); if (xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED) { // Scheduler is not running yet — this means we are running on PRO CPU.