Просмотр исходного кода

Merge branch 'bugfix/mmap_instr' into 'master'

spi_flash: fix mmap not working for SPI_FLASH_MMAP_INST

Fixes https://github.com/espressif/esp-idf/issues/378

See merge request !528

Ivan Grokhotkov 9 лет назад
Родитель
Сommit
c025dfbfa7
2 измененных файлов с 52 добавлено и 6 удалено
  1. 6 6
      components/spi_flash/flash_mmap.c
  2. 46 0
      components/spi_flash/test/test_mmap.c

+ 6 - 6
components/spi_flash/flash_mmap.c

@@ -93,16 +93,16 @@ esp_err_t IRAM_ATTR spi_flash_mmap(size_t src_addr, size_t size, spi_flash_mmap_
 {
     esp_err_t ret;
     bool did_flush, need_flush = false;
-    mmap_entry_t* new_entry = (mmap_entry_t*) malloc(sizeof(mmap_entry_t));
-    if (new_entry == 0) {
-        return ESP_ERR_NO_MEM;
-    }
     if (src_addr & 0xffff) {
         return ESP_ERR_INVALID_ARG;
     }
     if (src_addr + size > g_rom_flashchip.chip_size) {
         return ESP_ERR_INVALID_ARG;
     }
+    mmap_entry_t* new_entry = (mmap_entry_t*) malloc(sizeof(mmap_entry_t));
+    if (new_entry == 0) {
+        return ESP_ERR_NO_MEM;
+    }
 
     spi_flash_disable_interrupts_caches_and_other_cpu();
 
@@ -122,7 +122,7 @@ esp_err_t IRAM_ATTR spi_flash_mmap(size_t src_addr, size_t size, spi_flash_mmap_
         region_addr = VADDR0_START_ADDR;
     } else {
         // only part of VAddr1 is usable, so adjust for that
-        region_begin = VADDR1_FIRST_USABLE_ADDR;
+        region_begin = PRO_IRAM0_FIRST_USABLE_PAGE;
         region_size = 3 * 64 - region_begin;
         region_addr = VADDR1_FIRST_USABLE_ADDR;
     }
@@ -177,7 +177,7 @@ esp_err_t IRAM_ATTR spi_flash_mmap(size_t src_addr, size_t size, spi_flash_mmap_
         new_entry->count = page_count;
         new_entry->handle = ++s_mmap_last_handle;
         *out_handle = new_entry->handle;
-        *out_ptr = (void*) (region_addr + start * SPI_FLASH_MMU_PAGE_SIZE);
+        *out_ptr = (void*) (region_addr + (start - region_begin) * SPI_FLASH_MMU_PAGE_SIZE);
         ret = ESP_OK;
     }
 

+ 46 - 0
components/spi_flash/test/test_mmap.c

@@ -86,6 +86,52 @@ TEST_CASE("Can mmap into data address space", "[mmap]")
     spi_flash_munmap(handle3);
 }
 
+TEST_CASE("Can mmap into instruction address space", "[mmap]")
+{
+    printf("Mapping %x (+%x)\n", start, end - start);
+    spi_flash_mmap_handle_t handle1;
+    const void *ptr1;
+    ESP_ERROR_CHECK( spi_flash_mmap(start, end - start, SPI_FLASH_MMAP_INST, &ptr1, &handle1) );
+    printf("mmap_res: handle=%d ptr=%p\n", handle1, ptr1);
+
+    spi_flash_mmap_dump();
+
+    srand(0);
+    const uint32_t *data = (const uint32_t *) ptr1;
+    for (int block = 0; block < (end - start) / 0x10000; ++block) {
+        for (int sector = 0; sector < 16; ++sector) {
+            for (uint32_t word = 0; word < 1024; ++word) {
+                TEST_ASSERT_EQUAL_UINT32(rand(), data[(block * 16 + sector) * 1024 + word]);
+            }
+        }
+    }
+    printf("Mapping %x (+%x)\n", start - 0x10000, 0x20000);
+    spi_flash_mmap_handle_t handle2;
+    const void *ptr2;
+    ESP_ERROR_CHECK( spi_flash_mmap(start - 0x10000, 0x20000, SPI_FLASH_MMAP_DATA, &ptr2, &handle2) );
+    printf("mmap_res: handle=%d ptr=%p\n", handle2, ptr2);
+    spi_flash_mmap_dump();
+
+    printf("Mapping %x (+%x)\n", start, 0x10000);
+    spi_flash_mmap_handle_t handle3;
+    const void *ptr3;
+    ESP_ERROR_CHECK( spi_flash_mmap(start, 0x10000, SPI_FLASH_MMAP_DATA, &ptr3, &handle3) );
+    printf("mmap_res: handle=%d ptr=%p\n", handle3, ptr3);
+    spi_flash_mmap_dump();
+
+    printf("Unmapping handle1\n");
+    spi_flash_munmap(handle1);
+    spi_flash_mmap_dump();
+
+    printf("Unmapping handle2\n");
+    spi_flash_munmap(handle2);
+    spi_flash_mmap_dump();
+
+    printf("Unmapping handle3\n");
+    spi_flash_munmap(handle3);
+
+}
+
 TEST_CASE("flash_mmap invalidates just-written data", "[spi_flash]")
 {
     spi_flash_mmap_handle_t handle1;