From dc36d0c449161732b3a7481776f0d6dc2c1faabb Mon Sep 17 00:00:00 2001 From: armando Date: Wed, 21 Jan 2026 14:20:35 +0800 Subject: [PATCH 1/2] fix(mmu): no longer stop cache when doing virtual and physical addr conversion --- components/esp_mm/esp_mmu_map.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/components/esp_mm/esp_mmu_map.c b/components/esp_mm/esp_mmu_map.c index 791b55d59d..98830af516 100644 --- a/components/esp_mm/esp_mmu_map.c +++ b/components/esp_mm/esp_mmu_map.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -777,13 +777,11 @@ esp_err_t IRAM_ATTR esp_mmu_map_dump_mapped_blocks_private(void) /*--------------------------------------------------------------- Helper APIs for conversion between vaddr and paddr ---------------------------------------------------------------*/ -static bool NOINLINE_ATTR IRAM_ATTR s_vaddr_to_paddr(uint32_t vaddr, esp_paddr_t *out_paddr, mmu_target_t *out_target) +static bool s_vaddr_to_paddr(uint32_t vaddr, esp_paddr_t *out_paddr, mmu_target_t *out_target) { uint32_t mmu_id = 0; - /** - * Disable Cache, after this function, involved code and data should be placed in internal RAM. - */ - s_stop_cache(); + + _lock_acquire(&s_mmu_ctx.mutex); #if SOC_MMU_PER_EXT_MEM_TARGET mmu_id = mmu_hal_get_id_from_vaddr(vaddr); @@ -795,8 +793,7 @@ static bool NOINLINE_ATTR IRAM_ATTR s_vaddr_to_paddr(uint32_t vaddr, esp_paddr_t } #endif - //enable Cache, after this function, internal RAM access is no longer mandatory - s_start_cache(); + _lock_release(&s_mmu_ctx.mutex); return is_mapped; } @@ -818,12 +815,9 @@ esp_err_t esp_mmu_vaddr_to_paddr(void *vaddr, esp_paddr_t *out_paddr, mmu_target return ESP_OK; } -static bool NOINLINE_ATTR IRAM_ATTR s_paddr_to_vaddr(esp_paddr_t paddr, mmu_target_t target, mmu_vaddr_t type, uint32_t *out_vaddr) +static bool s_paddr_to_vaddr(esp_paddr_t paddr, mmu_target_t target, mmu_vaddr_t type, uint32_t *out_vaddr) { - /** - * Disable Cache, after this function, involved code and data should be placed in internal RAM. - */ - s_stop_cache(); + _lock_acquire(&s_mmu_ctx.mutex); uint32_t mmu_id = 0; #if SOC_MMU_PER_EXT_MEM_TARGET @@ -831,8 +825,7 @@ static bool NOINLINE_ATTR IRAM_ATTR s_paddr_to_vaddr(esp_paddr_t paddr, mmu_targ #endif bool found = mmu_hal_paddr_to_vaddr(mmu_id, paddr, target, type, out_vaddr); - //enable Cache, after this function, internal RAM access is no longer mandatory - s_start_cache(); + _lock_release(&s_mmu_ctx.mutex); return found; } From 58c57da9f807b3b34ac15c77e90a4eb52e03f692 Mon Sep 17 00:00:00 2001 From: armando Date: Wed, 21 Jan 2026 14:49:41 +0800 Subject: [PATCH 2/2] test(mspi): add flash api run on psram stack test for xip_psram case --- .../test_apps/mspi/main/test_flash_psram.c | 54 ++++++++++++++++++- .../test_apps/mspi/pytest_flash_psram.py | 1 + .../sdkconfig.ci.generic_timing_tuning_xip | 4 ++ .../test_apps/psram/main/test_psram.c | 7 ++- 4 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 components/esp_hw_support/test_apps/mspi/sdkconfig.ci.generic_timing_tuning_xip diff --git a/components/esp_hw_support/test_apps/mspi/main/test_flash_psram.c b/components/esp_hw_support/test_apps/mspi/main/test_flash_psram.c index 86df9f4772..b10d017128 100644 --- a/components/esp_hw_support/test_apps/mspi/main/test_flash_psram.c +++ b/components/esp_hw_support/test_apps/mspi/main/test_flash_psram.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,6 +20,7 @@ #include "esp32s3/rom/opi_flash.h" #endif +__attribute__((unused)) const static char *TAG = "MSPI"; //-----------------------------------------SPI0 PSRAM TEST-----------------------------------------------// #if CONFIG_SPIRAM @@ -143,3 +144,54 @@ TEST_CASE("MSPI: Test_SPI0_Flash", "[mspi]") } printf(DRAM_STR("----------SPI0 Flash Test Success----------\n\n")); } + + +/*--------------------------------------------------------------- + XIP + PSRAM Stack + Flash API +---------------------------------------------------------------*/ +#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS && CONFIG_SPIRAM_RODATA +typedef struct { + SemaphoreHandle_t sem; + const esp_partition_t *part; +} test_flash_api_ctx_t; + +static void test_flash_api_on_psram_when_xip(void *arg) +{ + test_flash_api_ctx_t *ctx = (test_flash_api_ctx_t *)arg; + SemaphoreHandle_t test_semphr = ctx->sem; + + TEST_ESP_OK(esp_flash_erase_region(ctx->part->flash_chip, ctx->part->address, ctx->part->size)); + + uint32_t test_val = 0x55; + uint32_t read_val = 0; + TEST_ESP_OK(esp_flash_write(ctx->part->flash_chip, &test_val, ctx->part->address, 4)); + TEST_ESP_OK(esp_flash_read(ctx->part->flash_chip, &read_val, ctx->part->address, 4)); + TEST_ASSERT(test_val == read_val); + + xSemaphoreGive(test_semphr); + vTaskDelete(NULL); +} + +TEST_CASE("test Flash API work with PSRAM stack when XIP_PSRAM", "[psram]") +{ + SemaphoreHandle_t test_semphr = xSemaphoreCreateBinary(); + TEST_ASSERT(test_semphr); + const esp_partition_t *part = get_test_flash_partition(); + ESP_LOGI(TAG, "found partition '%s' at offset 0x%"PRIx32" with size 0x%"PRIx32, part->label, part->address, part->size); + + test_flash_api_ctx_t ctx = { + .sem = test_semphr, + .part = part, + }; + + int size_stack = 1024 * 4; + StackType_t *stack_for_task = (StackType_t *) heap_caps_calloc(1, size_stack, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + printf("init_task: current addr_stack = %p, stack_for_task = %p\n", esp_cpu_get_sp(), stack_for_task); + static StaticTask_t task_buf; + xTaskCreateStaticPinnedToCore(test_flash_api_on_psram_when_xip, "test_flash_api_on_psram_when_xip", size_stack, &ctx, 5, stack_for_task, &task_buf, 0); + + xSemaphoreTake(test_semphr, portMAX_DELAY); + vSemaphoreDelete(test_semphr); + free(stack_for_task); +} +#endif //CONFIG_SPIRAM_FETCH_INSTRUCTIONS && CONFIG_SPIRAM_RODATA diff --git a/components/esp_hw_support/test_apps/mspi/pytest_flash_psram.py b/components/esp_hw_support/test_apps/mspi/pytest_flash_psram.py index 27b826b1f5..142c0e50e8 100644 --- a/components/esp_hw_support/test_apps/mspi/pytest_flash_psram.py +++ b/components/esp_hw_support/test_apps/mspi/pytest_flash_psram.py @@ -68,6 +68,7 @@ def test_flash_psram_esp32p4(dut: IdfDut) -> None: 'config', [ 'generic_timing_tuning_log_safe', + 'generic_timing_tuning_xip', ], indirect=True, ) diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.generic_timing_tuning_xip b/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.generic_timing_tuning_xip new file mode 100644 index 0000000000..1a6b0aeb14 --- /dev/null +++ b/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.generic_timing_tuning_xip @@ -0,0 +1,4 @@ +CONFIG_SPIRAM=y +CONFIG_SPIRAM_SPEED_80M=y +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +CONFIG_SPIRAM_XIP_FROM_PSRAM=y diff --git a/components/esp_psram/test_apps/psram/main/test_psram.c b/components/esp_psram/test_apps/psram/main/test_psram.c index 3ce5bc9c7d..9a292d9757 100644 --- a/components/esp_psram/test_apps/psram/main/test_psram.c +++ b/components/esp_psram/test_apps/psram/main/test_psram.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -58,7 +58,10 @@ TEST_CASE("stress test psram heap allocable", "[psram][manual][ignore]") } } -#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS && CONFIG_SPIRAM_RODATA +#if CONFIG_SPIRAM_XIP_FROM_PSRAM +/*--------------------------------------------------------------- + SPI1 with XIP +---------------------------------------------------------------*/ #include "esp_partition.h" #include "driver/gptimer.h" #include "esp_rom_spiflash.h"