diff --git a/.gitlab/ci/target-test.yml b/.gitlab/ci/target-test.yml index 11a1934083..917c5831a3 100644 --- a/.gitlab/ci/target-test.yml +++ b/.gitlab/ci/target-test.yml @@ -1012,7 +1012,7 @@ UT_S2_SDSPI: UT_C2: extends: .unit_test_esp32c2_template - parallel: 23 + parallel: 24 tags: - ESP32C2_IDF - UT_T1_1 diff --git a/components/app_update/test/test_ota_ops.c b/components/app_update/test/test_ota_ops.c index b72142d6e1..0dbfabb76c 100644 --- a/components/app_update/test/test_ota_ops.c +++ b/components/app_update/test/test_ota_ops.c @@ -6,6 +6,7 @@ #include #include #include +#include "esp_log.h" #include #include #include @@ -113,3 +114,11 @@ TEST_CASE("esp_ota_get_partition_description", "[ota]") }; TEST_ESP_ERR(ESP_ERR_NOT_FOUND, bootloader_common_get_partition_description(¬_app_pos, &app_desc1)); } + +TEST_CASE("esp_ota_get_running_partition points to correct address", "[spi_flash]") +{ + const esp_partition_t *factory = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_ANY, "factory"); + const esp_partition_t* part = esp_ota_get_running_partition(); + ESP_LOGI("running bin", "0x%p", (void*)part->address); + TEST_ASSERT_EQUAL_HEX32(factory->address, part->address); +} diff --git a/components/esp_psram/mmu_psram_flash.c b/components/esp_psram/mmu_psram_flash.c index bfa3daec3b..165589afcf 100644 --- a/components/esp_psram/mmu_psram_flash.c +++ b/components/esp_psram/mmu_psram_flash.c @@ -166,7 +166,8 @@ void instruction_flash_page_info_init(uint32_t psram_start_physical_page) instr_start_page = ((volatile uint32_t *)(DR_REG_MMU_TABLE + PRO_CACHE_IBUS0_MMU_START))[instr_mmu_offset]; #elif CONFIG_IDF_TARGET_ESP32S3 uint32_t instr_page_cnt = ((uint32_t)&_instruction_reserved_end - SOC_IROM_LOW + MMU_PAGE_SIZE - 1) / MMU_PAGE_SIZE; - instr_start_page = *((volatile uint32_t *)(DR_REG_MMU_TABLE + CACHE_IROM_MMU_START)); + uint32_t instr_mmu_offset = ((uint32_t)&_instruction_reserved_start & MMU_VADDR_MASK) / MMU_PAGE_SIZE; + instr_start_page = *((volatile uint32_t *)(DR_REG_MMU_TABLE + instr_mmu_offset * 4)); #endif instr_start_page &= MMU_VALID_VAL_MASK; instr_end_page = instr_start_page + instr_page_cnt - 1; @@ -219,7 +220,8 @@ void rodata_flash_page_info_init(uint32_t psram_start_physical_page) rodata_start_page = ((volatile uint32_t *)(DR_REG_MMU_TABLE + PRO_CACHE_IBUS2_MMU_START))[rodata_mmu_offset]; #elif CONFIG_IDF_TARGET_ESP32S3 uint32_t rodata_page_cnt = ((uint32_t)&_rodata_reserved_end - ((uint32_t)&_rodata_reserved_start & ~ (MMU_PAGE_SIZE - 1)) + MMU_PAGE_SIZE - 1) / MMU_PAGE_SIZE; - rodata_start_page = *(volatile uint32_t *)(DR_REG_MMU_TABLE + CACHE_DROM_MMU_START); + uint32_t rodata_mmu_offset = ((uint32_t)&_rodata_reserved_start & MMU_VADDR_MASK) / MMU_PAGE_SIZE; + rodata_start_page = *(volatile uint32_t *)(DR_REG_MMU_TABLE + rodata_mmu_offset * 4); #endif rodata_start_page &= MMU_VALID_VAL_MASK; rodata_end_page = rodata_start_page + rodata_page_cnt - 1; diff --git a/components/spi_flash/flash_mmap.c b/components/spi_flash/flash_mmap.c index 7950be40fb..2a469ac7fd 100644 --- a/components/spi_flash/flash_mmap.c +++ b/components/spi_flash/flash_mmap.c @@ -81,6 +81,8 @@ static LIST_HEAD(mmap_entries_head, mmap_entry_) s_mmap_entries_head = static uint8_t s_mmap_page_refcnt[SOC_MMU_REGIONS_COUNT * SOC_MMU_PAGES_PER_REGION] = {0}; static uint32_t s_mmap_last_handle = 0; +static uint32_t spi_flash_protected_read_mmu_entry(int index); + static void IRAM_ATTR spi_flash_mmap_init(void) { @@ -330,15 +332,6 @@ static void IRAM_ATTR NOINLINE_ATTR spi_flash_protected_mmap_init(void) spi_flash_enable_interrupts_caches_and_other_cpu(); } -static uint32_t IRAM_ATTR NOINLINE_ATTR spi_flash_protected_read_mmu_entry(int index) -{ - uint32_t value; - spi_flash_disable_interrupts_caches_and_other_cpu(); - value = mmu_ll_read_entry(MMU_TABLE_CORE0, index); - spi_flash_enable_interrupts_caches_and_other_cpu(); - return value; -} - void spi_flash_mmap_dump(void) { spi_flash_protected_mmap_init(); @@ -374,6 +367,89 @@ uint32_t IRAM_ATTR spi_flash_mmap_get_free_pages(spi_flash_mmap_memory_t memory) return count; } +static bool IRAM_ATTR is_page_mapped_in_cache(uint32_t phys_page, const void **out_ptr) +{ + int start[2], end[2]; + + *out_ptr = NULL; + + /* SPI_FLASH_MMAP_DATA */ + start[0] = SOC_MMU_DROM0_PAGES_START; + end[0] = SOC_MMU_DROM0_PAGES_END; + + /* SPI_FLASH_MMAP_INST */ + start[1] = SOC_MMU_PRO_IRAM0_FIRST_USABLE_PAGE; + end[1] = SOC_MMU_IROM0_PAGES_END; + + for (int j = 0; j < 2; j++) { + for (int i = start[j]; i < end[j]; i++) { + uint32_t entry_pro = mmu_ll_read_entry(MMU_TABLE_CORE0, i); + if (entry_pro == SOC_MMU_PAGE_IN_FLASH(phys_page)) { +#if !CONFIG_IDF_TARGET_ESP32 + if (j == 0) { /* SPI_FLASH_MMAP_DATA */ + *out_ptr = (const void *)(SOC_MMU_VADDR0_START_ADDR + SPI_FLASH_MMU_PAGE_SIZE * (i - start[0])); + } else { /* SPI_FLASH_MMAP_INST */ + *out_ptr = (const void *)(SOC_MMU_VADDR1_FIRST_USABLE_ADDR + SPI_FLASH_MMU_PAGE_SIZE * (i - start[1])); + } +#endif + return true; + } + } + } + return false; +} + +/* Validates if given flash address has corresponding cache mapping, if yes, flushes cache memories */ +IRAM_ATTR bool spi_flash_check_and_flush_cache(size_t start_addr, size_t length) +{ + bool ret = false; + /* align start_addr & length to full MMU pages */ + uint32_t page_start_addr = start_addr & ~(SPI_FLASH_MMU_PAGE_SIZE-1); + length += (start_addr - page_start_addr); + length = (length + SPI_FLASH_MMU_PAGE_SIZE - 1) & ~(SPI_FLASH_MMU_PAGE_SIZE-1); + for (uint32_t addr = page_start_addr; addr < page_start_addr + length; addr += SPI_FLASH_MMU_PAGE_SIZE) { + uint32_t page = addr / SPI_FLASH_MMU_PAGE_SIZE; + // TODO: IDF-4969 + if (page >= 256) { + return false; /* invalid address */ + } + + const void *vaddr = NULL; + if (is_page_mapped_in_cache(page, &vaddr)) { +#if CONFIG_IDF_TARGET_ESP32 +#if CONFIG_SPIRAM + esp_psram_extram_writeback_cache(); +#endif + Cache_Flush(0); +#ifndef CONFIG_FREERTOS_UNICORE + Cache_Flush(1); +#endif + return true; +#else // CONFIG_IDF_TARGET_ESP32 + if (vaddr != NULL) { + Cache_Invalidate_Addr((uint32_t)vaddr, SPI_FLASH_MMU_PAGE_SIZE); + ret = true; + } +#endif // CONFIG_IDF_TARGET_ESP32 + + } + } + return ret; +} +#endif //!CONFIG_SPI_FLASH_ROM_IMPL + +#if !CONFIG_SPI_FLASH_ROM_IMPL || CONFIG_SPIRAM_FETCH_INSTRUCTIONS || CONFIG_SPIRAM_RODATA +static uint32_t IRAM_ATTR NOINLINE_ATTR spi_flash_protected_read_mmu_entry(int index) +{ + uint32_t value; + spi_flash_disable_interrupts_caches_and_other_cpu(); + value = mmu_ll_read_entry(MMU_TABLE_CORE0, index); + spi_flash_enable_interrupts_caches_and_other_cpu(); + return value; +} + +//The ROM implementation returns physical address of the PSRAM when the .text or .rodata is in the PSRAM. +//Always patch it when SPIRAM_FETCH_INSTRUCTIONS or SPIRAM_RODATA is set. size_t spi_flash_cache2phys(const void *cached) { intptr_t c = (intptr_t)cached; @@ -461,74 +537,4 @@ const void *IRAM_ATTR spi_flash_phys2cache(size_t phys_offs, spi_flash_mmap_memo spi_flash_enable_interrupts_caches_and_other_cpu(); return NULL; } - -static bool IRAM_ATTR is_page_mapped_in_cache(uint32_t phys_page, const void **out_ptr) -{ - int start[2], end[2]; - - *out_ptr = NULL; - - /* SPI_FLASH_MMAP_DATA */ - start[0] = SOC_MMU_DROM0_PAGES_START; - end[0] = SOC_MMU_DROM0_PAGES_END; - - /* SPI_FLASH_MMAP_INST */ - start[1] = SOC_MMU_PRO_IRAM0_FIRST_USABLE_PAGE; - end[1] = SOC_MMU_IROM0_PAGES_END; - - for (int j = 0; j < 2; j++) { - for (int i = start[j]; i < end[j]; i++) { - uint32_t entry_pro = mmu_ll_read_entry(MMU_TABLE_CORE0, i); - if (entry_pro == SOC_MMU_PAGE_IN_FLASH(phys_page)) { -#if !CONFIG_IDF_TARGET_ESP32 - if (j == 0) { /* SPI_FLASH_MMAP_DATA */ - *out_ptr = (const void *)(SOC_MMU_VADDR0_START_ADDR + SPI_FLASH_MMU_PAGE_SIZE * (i - start[0])); - } else { /* SPI_FLASH_MMAP_INST */ - *out_ptr = (const void *)(SOC_MMU_VADDR1_FIRST_USABLE_ADDR + SPI_FLASH_MMU_PAGE_SIZE * (i - start[1])); - } -#endif - return true; - } - } - } - return false; -} - -/* Validates if given flash address has corresponding cache mapping, if yes, flushes cache memories */ -IRAM_ATTR bool spi_flash_check_and_flush_cache(size_t start_addr, size_t length) -{ - bool ret = false; - /* align start_addr & length to full MMU pages */ - uint32_t page_start_addr = start_addr & ~(SPI_FLASH_MMU_PAGE_SIZE-1); - length += (start_addr - page_start_addr); - length = (length + SPI_FLASH_MMU_PAGE_SIZE - 1) & ~(SPI_FLASH_MMU_PAGE_SIZE-1); - for (uint32_t addr = page_start_addr; addr < page_start_addr + length; addr += SPI_FLASH_MMU_PAGE_SIZE) { - uint32_t page = addr / SPI_FLASH_MMU_PAGE_SIZE; - // TODO: IDF-4969 - if (page >= 256) { - return false; /* invalid address */ - } - - const void *vaddr = NULL; - if (is_page_mapped_in_cache(page, &vaddr)) { -#if CONFIG_IDF_TARGET_ESP32 -#if CONFIG_SPIRAM - esp_psram_extram_writeback_cache(); -#endif - Cache_Flush(0); -#ifndef CONFIG_FREERTOS_UNICORE - Cache_Flush(1); -#endif - return true; -#else // CONFIG_IDF_TARGET_ESP32 - if (vaddr != NULL) { - Cache_Invalidate_Addr((uint32_t)vaddr, SPI_FLASH_MMU_PAGE_SIZE); - ret = true; - } -#endif // CONFIG_IDF_TARGET_ESP32 - - } - } - return ret; -} -#endif //!CONFIG_SPI_FLASH_ROM_IMPL +#endif //!CONFIG_SPI_FLASH_ROM_IMPL || CONFIG_SPIRAM_FETCH_INSTRUCTIONS || CONFIG_SPIRAM_RODATA diff --git a/components/spi_flash/test/test_mmap.c b/components/spi_flash/test/test_mmap.c index 7dc3e8d104..be28feac28 100644 --- a/components/spi_flash/test/test_mmap.c +++ b/components/spi_flash/test/test_mmap.c @@ -1,6 +1,7 @@ #include #include #include +#include "esp_log.h" #include #include #include @@ -475,4 +476,15 @@ TEST_CASE("no stale data read post mmap and write partition", "[spi_flash][mmap] esp_partition_munmap(handle); TEST_ASSERT_EQUAL(0, memcmp(buf, read_data, sizeof(buf))); } + +TEST_CASE("spi_flash_cache2phys points to correct address", "[spi_flash]") +{ + //_rodata_start, which begins with appdesc, is always the first segment of the bin. + extern int _rodata_start; + size_t addr = spi_flash_cache2phys(&_rodata_start); + + const esp_partition_t *factory = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_ANY, "factory"); + ESP_LOGI("running bin", "0x%p", (void*)addr); + TEST_ASSERT_HEX32_WITHIN(CONFIG_MMU_PAGE_SIZE/2, factory->address + CONFIG_MMU_PAGE_SIZE/2, addr); +} #endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)