From fce2680e9171d0104bcd9f43a12dce643b61b394 Mon Sep 17 00:00:00 2001 From: Armando Date: Tue, 3 Sep 2024 14:10:24 +0800 Subject: [PATCH] feat(psram): xip psram c61 --- components/esp_psram/esp32c61/Kconfig.spiram | 34 +++++++++++++++++++ .../include/esp_private/mmu_psram_flash.h | 2 +- components/esp_psram/mmu_psram_flash_v2.c | 6 ++-- .../esp_psram/test_apps/psram/pytest_psram.py | 1 + .../psram/sdkconfig.ci.esp32c61_advanced | 15 ++++++++ components/hal/esp32c61/include/hal/mmu_ll.h | 3 +- .../soc/esp32c61/include/soc/ext_mem_defs.h | 2 +- components/spi_flash/flash_mmap.c | 8 ++--- .../test_apps/flash_mmap/pytest_flash_mmap.py | 3 +- .../sdkconfig.ci.xip_psram_esp32c61 | 2 ++ 10 files changed, 66 insertions(+), 10 deletions(-) create mode 100644 components/esp_psram/test_apps/psram/sdkconfig.ci.esp32c61_advanced create mode 100644 components/spi_flash/test_apps/flash_mmap/sdkconfig.ci.xip_psram_esp32c61 diff --git a/components/esp_psram/esp32c61/Kconfig.spiram b/components/esp_psram/esp32c61/Kconfig.spiram index 725b456a3c..0ef577983f 100644 --- a/components/esp_psram/esp32c61/Kconfig.spiram +++ b/components/esp_psram/esp32c61/Kconfig.spiram @@ -44,5 +44,39 @@ menu "SPI RAM config" default 80 if SPIRAM_SPEED_80M default 40 if SPIRAM_SPEED_40M + config SPIRAM_FETCH_INSTRUCTIONS + bool + help + Enable this option allows moving application's instruction segment from the SPI Flash to PSRAM + + config SPIRAM_RODATA + bool + help + Enable this option allows moving application's rodata segment from the SPI Flash to + PSRAM + + config SPIRAM_XIP_FROM_PSRAM + bool "Enable Executable in place from (XiP) from PSRAM feature (READ HELP)" + default n + select SPIRAM_FETCH_INSTRUCTIONS + select SPIRAM_RODATA + select SPIRAM_FLASH_LOAD_TO_PSRAM + help + If enabled, firmware in flash including instructions and data will be moved into PSRAM on startup, + firmware code will execute directly from PSRAM. + + With this option enabled, code that requires execution during an MSPI1 Flash operation + does not have to be placed in IRAM. Therefore codes that need to be executing during Flash + operations can continue working normally. + + This feature is useful for high throughput peripheral involved applications to improve + the performance during MSPI1 flash operations. + + config SPIRAM_FLASH_LOAD_TO_PSRAM + bool + help + This is a helper indicating this condition: + `CONFIG_SPIRAM_XIP_FROM_PSRAM && CONFIG_IDF_TARGET_ESP32C61` + source "$IDF_PATH/components/esp_psram/Kconfig.spiram.common" # insert non-chip-specific items here endmenu diff --git a/components/esp_psram/include/esp_private/mmu_psram_flash.h b/components/esp_psram/include/esp_private/mmu_psram_flash.h index 554ab77d16..e95845a0f4 100644 --- a/components/esp_psram/include/esp_private/mmu_psram_flash.h +++ b/components/esp_psram/include/esp_private/mmu_psram_flash.h @@ -30,7 +30,7 @@ extern "C" { #if CONFIG_IDF_TARGET_ESP32 #define MMU_PAGE_SIZE 0x8000 #else -#define MMU_PAGE_SIZE 0x10000 +#define MMU_PAGE_SIZE CONFIG_MMU_PAGE_SIZE #define MMU_PAGE_TO_BYTES(page_id) ((page_id) * MMU_PAGE_SIZE) #define BYTES_TO_MMU_PAGE(bytes) ((bytes) / MMU_PAGE_SIZE) #endif diff --git a/components/esp_psram/mmu_psram_flash_v2.c b/components/esp_psram/mmu_psram_flash_v2.c index 0ae669c838..be78092322 100644 --- a/components/esp_psram/mmu_psram_flash_v2.c +++ b/components/esp_psram/mmu_psram_flash_v2.c @@ -85,7 +85,7 @@ esp_err_t mmu_config_psram_text_segment(uint32_t start_page, uint32_t psram_size uint32_t flash_irom_paddr_start = 0; image_process_get_flash_segments_info(&flash_drom_paddr_start, &flash_irom_paddr_start); flash_irom_paddr_start = ALIGN_DOWN_BY(flash_irom_paddr_start, CONFIG_MMU_PAGE_SIZE); - ESP_EARLY_LOGI(TAG, "flash_irom_paddr_start: 0x%x", flash_irom_paddr_start); + ESP_EARLY_LOGV(TAG, "flash_irom_paddr_start: 0x%x", flash_irom_paddr_start); if ((MMU_PAGE_TO_BYTES(start_page) + irom_size) > psram_size) { ESP_EARLY_LOGE(TAG, "PSRAM space not enough for the Flash instructions, need %"PRId32" B, from %"PRId32" B to %"PRId32" B", irom_size, MMU_PAGE_TO_BYTES(start_page), MMU_PAGE_TO_BYTES(start_page) + irom_size); @@ -106,6 +106,7 @@ esp_err_t mmu_config_psram_text_segment(uint32_t start_page, uint32_t psram_size start_page += BYTES_TO_MMU_PAGE(irom_size); *out_page = start_page; + ESP_EARLY_LOGI(TAG, ".text xip on psram"); return ESP_OK; } #endif //#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS @@ -120,7 +121,7 @@ esp_err_t mmu_config_psram_rodata_segment(uint32_t start_page, uint32_t psram_si uint32_t flash_irom_paddr_start = 0; image_process_get_flash_segments_info(&flash_drom_paddr_start, &flash_irom_paddr_start); flash_drom_paddr_start = ALIGN_DOWN_BY(flash_drom_paddr_start, CONFIG_MMU_PAGE_SIZE); - ESP_EARLY_LOGI(TAG, "flash_drom_paddr_start: 0x%x", flash_drom_paddr_start); + ESP_EARLY_LOGV(TAG, "flash_drom_paddr_start: 0x%x", flash_drom_paddr_start); if ((MMU_PAGE_TO_BYTES(start_page) + drom_size) > psram_size) { ESP_EARLY_LOGE(TAG, "PSRAM space not enough for the Flash rodata, need %"PRId32" B, from %"PRId32" B to %"PRId32" B", drom_size, MMU_PAGE_TO_BYTES(start_page), MMU_PAGE_TO_BYTES(start_page) + drom_size); @@ -141,6 +142,7 @@ esp_err_t mmu_config_psram_rodata_segment(uint32_t start_page, uint32_t psram_si start_page += BYTES_TO_MMU_PAGE(drom_size); *out_page = start_page; + ESP_EARLY_LOGI(TAG, ".rodata xip on psram"); return ESP_OK; } #endif //#if CONFIG_SPIRAM_RODATA diff --git a/components/esp_psram/test_apps/psram/pytest_psram.py b/components/esp_psram/test_apps/psram/pytest_psram.py index 04dd2807b8..e13d48e803 100644 --- a/components/esp_psram/test_apps/psram/pytest_psram.py +++ b/components/esp_psram/test_apps/psram/pytest_psram.py @@ -108,6 +108,7 @@ def test_psram_esp32c5(dut: Dut) -> None: 'config', [ 'esp32c61_release', + 'esp32c61_advanced', ], indirect=True, ) diff --git a/components/esp_psram/test_apps/psram/sdkconfig.ci.esp32c61_advanced b/components/esp_psram/test_apps/psram/sdkconfig.ci.esp32c61_advanced new file mode 100644 index 0000000000..aa1bcea9c7 --- /dev/null +++ b/components/esp_psram/test_apps/psram/sdkconfig.ci.esp32c61_advanced @@ -0,0 +1,15 @@ +CONFIG_IDF_TARGET="esp32c61" + +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y + +CONFIG_SPIRAM=y +CONFIG_SPIRAM_SPEED_80M=y +CONFIG_SPIRAM_XIP_FROM_PSRAM=y +CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y +CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY=y + +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" diff --git a/components/hal/esp32c61/include/hal/mmu_ll.h b/components/hal/esp32c61/include/hal/mmu_ll.h index f944c3ecbc..b0e7c75309 100644 --- a/components/hal/esp32c61/include/hal/mmu_ll.h +++ b/components/hal/esp32c61/include/hal/mmu_ll.h @@ -20,6 +20,8 @@ extern "C" { #endif +#define MMU_LL_FLASH_MMU_ID 0 +#define MMU_LL_PSRAM_MMU_ID 0 #define MMU_LL_END_DROM_ENTRY_VADDR (SOC_DRAM_FLASH_ADDRESS_HIGH - SOC_MMU_PAGE_SIZE) #define MMU_LL_END_DROM_ENTRY_ID (SOC_MMU_ENTRY_NUM - 1) @@ -212,7 +214,6 @@ static inline uint32_t mmu_ll_format_paddr(uint32_t mmu_id, uint32_t paddr, mmu_ __attribute__((always_inline)) static inline void mmu_ll_write_entry(uint32_t mmu_id, uint32_t entry_id, uint32_t mmu_val, mmu_target_t target) { (void)mmu_id; - (void)target; uint32_t mmu_raw_value; if (mmu_ll_cache_encryption_enabled()) { mmu_val |= SOC_MMU_SENSITIVE; diff --git a/components/soc/esp32c61/include/soc/ext_mem_defs.h b/components/soc/esp32c61/include/soc/ext_mem_defs.h index 6dcda1059c..85ce7cf8d7 100644 --- a/components/soc/esp32c61/include/soc/ext_mem_defs.h +++ b/components/soc/esp32c61/include/soc/ext_mem_defs.h @@ -58,7 +58,7 @@ extern "C" { * valid bit + value bits * valid bit is BIT(9), so value bits are 0x1ff */ -#define SOC_MMU_VALID_VAL_MASK 0x3ff +#define SOC_MMU_VALID_VAL_MASK (SOC_MMU_ACCESS_SPIRAM - 1) /** * Max MMU available paddr page num. * `SOC_MMU_MAX_PADDR_PAGE_NUM * SOC_MMU_PAGE_SIZE` means the max paddr address supported by the MMU. e.g.: diff --git a/components/spi_flash/flash_mmap.c b/components/spi_flash/flash_mmap.c index bfc6b10179..28e3f40959 100644 --- a/components/spi_flash/flash_mmap.c +++ b/components/spi_flash/flash_mmap.c @@ -277,7 +277,7 @@ const void * spi_flash_phys2cache(size_t phys_offs, spi_flash_mmap_memory_t memo mmu_target_t target = MMU_TARGET_FLASH0; __attribute__((unused)) uint32_t phys_page = phys_offs / CONFIG_MMU_PAGE_SIZE; -#if !SOC_MMU_PER_EXT_MEM_TARGET +#if !CONFIG_SPIRAM_FLASH_LOAD_TO_PSRAM #if CONFIG_SPIRAM_FETCH_INSTRUCTIONS if (phys_page >= instruction_flash_start_page_get() && phys_page <= instruction_flash_end_page_get()) { target = MMU_TARGET_PSRAM0; @@ -291,7 +291,7 @@ const void * spi_flash_phys2cache(size_t phys_offs, spi_flash_mmap_memory_t memo phys_offs -= rodata_flash2spiram_offset() * CONFIG_MMU_PAGE_SIZE; } #endif -#endif //#if !SOC_MMU_PER_EXT_MEM_TARGET +#endif //#if !CONFIG_SPIRAM_FLASH_LOAD_TO_PSRAM mmu_vaddr_t type = (memory == SPI_FLASH_MMAP_DATA) ? MMU_VADDR_DATA : MMU_VADDR_INSTRUCTION; ret = esp_mmu_paddr_to_vaddr(phys_offs, target, type, &ptr); @@ -383,7 +383,7 @@ size_t spi_flash_cache2phys(const void *cached) int offset = 0; -#if !SOC_MMU_PER_EXT_MEM_TARGET //TODO: IDF-9049 +#if !CONFIG_SPIRAM_FLASH_LOAD_TO_PSRAM #if CONFIG_SPIRAM_RODATA if ((uint32_t)cached >= (uint32_t)&_rodata_reserved_start && (uint32_t)cached <= (uint32_t)&_rodata_reserved_end) { offset = rodata_flash2spiram_offset(); @@ -394,7 +394,7 @@ size_t spi_flash_cache2phys(const void *cached) offset = instruction_flash2spiram_offset(); } #endif -#endif //#if !SOC_MMU_PER_EXT_MEM_TARGET +#endif //#if !CONFIG_SPIRAM_FLASH_LOAD_TO_PSRAM return paddr + offset * CONFIG_MMU_PAGE_SIZE; } diff --git a/components/spi_flash/test_apps/flash_mmap/pytest_flash_mmap.py b/components/spi_flash/test_apps/flash_mmap/pytest_flash_mmap.py index 782d0091b2..65dc1c57c2 100644 --- a/components/spi_flash/test_apps/flash_mmap/pytest_flash_mmap.py +++ b/components/spi_flash/test_apps/flash_mmap/pytest_flash_mmap.py @@ -1,6 +1,5 @@ # SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 - import pytest from pytest_embedded import Dut @@ -38,6 +37,8 @@ def test_flash_mmap_rom_impl(dut: Dut) -> None: XIP_CONFIGS = [ pytest.param('xip_psram_esp32s2', marks=[pytest.mark.esp32s2]), pytest.param('xip_psram_esp32s3', marks=[pytest.mark.esp32s3]), + pytest.param('xip_psram_esp32c5', marks=[pytest.mark.esp32c5]), + pytest.param('xip_psram_esp32c61', marks=[pytest.mark.esp32c61]), ] diff --git a/components/spi_flash/test_apps/flash_mmap/sdkconfig.ci.xip_psram_esp32c61 b/components/spi_flash/test_apps/flash_mmap/sdkconfig.ci.xip_psram_esp32c61 new file mode 100644 index 0000000000..656c4d8f2c --- /dev/null +++ b/components/spi_flash/test_apps/flash_mmap/sdkconfig.ci.xip_psram_esp32c61 @@ -0,0 +1,2 @@ +CONFIG_IDF_TARGET="esp32c61" +CONFIG_SPIRAM_XIP_FROM_PSRAM=y