diff --git a/components/soc/esp32/include/soc/soc.h b/components/soc/esp32/include/soc/soc.h index 8121e33b0..007a69c90 100644 --- a/components/soc/esp32/include/soc/soc.h +++ b/components/soc/esp32/include/soc/soc.h @@ -75,7 +75,9 @@ #define DR_REG_AES_BASE 0x3ff01000 #define DR_REG_RSA_BASE 0x3ff02000 #define DR_REG_SHA_BASE 0x3ff03000 -#define DR_REG_DPORT_END 0x3ff03FFC +#define DR_REG_FLASH_MMU_TABLE_PRO 0x3ff10000 +#define DR_REG_FLASH_MMU_TABLE_APP 0x3ff12000 +#define DR_REG_DPORT_END 0x3ff13FFC #define DR_REG_UART_BASE 0x3ff40000 #define DR_REG_SPI1_BASE 0x3ff42000 #define DR_REG_SPI0_BASE 0x3ff43000 diff --git a/components/spi_flash/flash_mmap.c b/components/spi_flash/flash_mmap.c index 52e64c11a..d6b884d33 100644 --- a/components/spi_flash/flash_mmap.c +++ b/components/spi_flash/flash_mmap.c @@ -57,6 +57,7 @@ Returns true if cache was flushed. */ + static bool spi_flash_ensure_unmodified_region(size_t start_addr, size_t length); typedef struct mmap_entry_{ @@ -78,10 +79,12 @@ static void IRAM_ATTR spi_flash_mmap_init() if (s_mmap_page_refcnt[0] != 0) { return; /* mmap data already initialised */ } - + + DPORT_STALL_OTHER_CPU_START(); for (int i = 0; i < REGIONS_COUNT * PAGES_PER_REGION; ++i) { uint32_t entry_pro = DPORT_PRO_FLASH_MMU_TABLE[i]; uint32_t entry_app = DPORT_APP_FLASH_MMU_TABLE[i]; + if (entry_pro != entry_app) { // clean up entries used by boot loader entry_pro = DPORT_FLASH_MMU_TABLE_INVALID_VAL; @@ -94,6 +97,7 @@ static void IRAM_ATTR spi_flash_mmap_init() DPORT_APP_FLASH_MMU_TABLE[i] = DPORT_FLASH_MMU_TABLE_INVALID_VAL; } } + DPORT_STALL_OTHER_CPU_END(); } esp_err_t IRAM_ATTR spi_flash_mmap(size_t src_addr, size_t size, spi_flash_mmap_memory_t memory, @@ -175,6 +179,7 @@ esp_err_t IRAM_ATTR spi_flash_mmap_pages(int *pages, size_t page_count, spi_flas for (start = region_begin; start < end; ++start) { int pageno = 0; int pos; + DPORT_STALL_OTHER_CPU_START(); for (pos = start; pos < start + page_count; ++pos, ++pageno) { int table_val = (int) DPORT_PRO_FLASH_MMU_TABLE[pos]; uint8_t refcnt = s_mmap_page_refcnt[pos]; @@ -182,6 +187,7 @@ esp_err_t IRAM_ATTR spi_flash_mmap_pages(int *pages, size_t page_count, spi_flas break; } } + DPORT_STALL_OTHER_CPU_END(); // whole mapping range matched, bail out if (pos - start == page_count) { break; @@ -195,6 +201,7 @@ esp_err_t IRAM_ATTR spi_flash_mmap_pages(int *pages, size_t page_count, spi_flas } else { // set up mapping using pages uint32_t pageno = 0; + DPORT_STALL_OTHER_CPU_START(); for (int i = start; i != start + page_count; ++i, ++pageno) { // sanity check: we won't reconfigure entries with non-zero reference count assert(s_mmap_page_refcnt[i] == 0 || @@ -209,7 +216,7 @@ esp_err_t IRAM_ATTR spi_flash_mmap_pages(int *pages, size_t page_count, spi_flas } ++s_mmap_page_refcnt[i]; } - + DPORT_STALL_OTHER_CPU_END(); LIST_INSERT_HEAD(&s_mmap_entries_head, new_entry, entries); new_entry->page = start; new_entry->count = page_count; @@ -250,6 +257,7 @@ void IRAM_ATTR spi_flash_munmap(spi_flash_mmap_handle_t handle) // for each page, decrement reference counter // if reference count is zero, disable MMU table entry to // facilitate debugging of use-after-free conditions + DPORT_STALL_OTHER_CPU_START(); for (int i = it->page; i < it->page + it->count; ++i) { assert(s_mmap_page_refcnt[i] > 0); if (--s_mmap_page_refcnt[i] == 0) { @@ -257,6 +265,7 @@ void IRAM_ATTR spi_flash_munmap(spi_flash_mmap_handle_t handle) DPORT_APP_FLASH_MMU_TABLE[i] = INVALID_ENTRY_VAL; } } + DPORT_STALL_OTHER_CPU_END(); LIST_REMOVE(it, entries); break; } @@ -369,7 +378,9 @@ uint32_t spi_flash_cache2phys(const void *cached) /* cached address was not in IROM or DROM */ return SPI_FLASH_CACHE2PHYS_FAIL; } + DPORT_STALL_OTHER_CPU_START(); uint32_t phys_page = DPORT_PRO_FLASH_MMU_TABLE[cache_page]; + DPORT_STALL_OTHER_CPU_END(); if (phys_page == INVALID_ENTRY_VAL) { /* page is not mapped */ return SPI_FLASH_CACHE2PHYS_FAIL; @@ -396,13 +407,16 @@ const void *spi_flash_phys2cache(uint32_t phys_offs, spi_flash_mmap_memory_t mem base = VADDR1_START_ADDR; page_delta = 64; } - + + DPORT_STALL_OTHER_CPU_START(); for (int i = start; i < end; i++) { if (DPORT_PRO_FLASH_MMU_TABLE[i] == phys_page) { i -= page_delta; intptr_t cache_page = base + (SPI_FLASH_MMU_PAGE_SIZE * i); + DPORT_STALL_OTHER_CPU_END(); return (const void *) (cache_page | (phys_offs & (SPI_FLASH_MMU_PAGE_SIZE-1))); } } + DPORT_STALL_OTHER_CPU_END(); return NULL; }