From 299d8115ed42670ed8574c73a5c49e4cbae25e19 Mon Sep 17 00:00:00 2001 From: Armando Date: Fri, 14 Feb 2025 11:53:58 +0800 Subject: [PATCH 1/3] fix(mmu): fixed esp_mmu_vaddr_to_paddr cannot figure out psram vaddr issue on esp32p4 --- components/esp_mm/esp_mmu_map.c | 21 ++++++++--------- components/hal/esp32p4/include/hal/mmu_ll.h | 24 +++++++++++++++++++- components/hal/include/hal/mmu_hal.h | 25 ++++++++++++++++++++- components/hal/mmu_hal.c | 14 +++++++++++- 4 files changed, 69 insertions(+), 15 deletions(-) diff --git a/components/esp_mm/esp_mmu_map.c b/components/esp_mm/esp_mmu_map.c index dc209d8ae9..80b99772df 100644 --- a/components/esp_mm/esp_mmu_map.c +++ b/components/esp_mm/esp_mmu_map.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -186,13 +186,6 @@ static void s_reserve_drom_region(mem_region_t *hw_mem_regions, int region_nums) } #endif //#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS -#if SOC_MMU_PER_EXT_MEM_TARGET -FORCE_INLINE_ATTR uint32_t s_get_mmu_id_from_target(mmu_target_t target) -{ - return (target == MMU_TARGET_FLASH0) ? MMU_LL_FLASH_MMU_ID : MMU_LL_PSRAM_MMU_ID; -} -#endif - void esp_mmu_map_init(void) { mem_region_t hw_mem_regions[SOC_MMU_LINEAR_ADDRESS_REGION_NUM] = {}; @@ -393,7 +386,7 @@ static void IRAM_ATTR NOINLINE_ATTR s_do_cache_invalidate(uint32_t vaddr_start, FORCE_INLINE_ATTR uint32_t s_mapping_operation(mmu_target_t target, uint32_t vaddr_start, esp_paddr_t paddr_start, uint32_t size) { uint32_t actual_mapped_len = 0; - uint32_t mmu_id = s_get_mmu_id_from_target(target); + uint32_t mmu_id = mmu_hal_get_id_from_target(target); mmu_hal_map_region(mmu_id, target, vaddr_start, paddr_start, size, &actual_mapped_len); return actual_mapped_len; @@ -599,7 +592,7 @@ err: FORCE_INLINE_ATTR void s_unmapping_operation(uint32_t vaddr_start, uint32_t size) { mmu_target_t target = mmu_ll_vaddr_to_target(vaddr_start); - uint32_t mmu_id = s_get_mmu_id_from_target(target); + uint32_t mmu_id = mmu_hal_get_id_from_target(target); mmu_hal_unmap_region(mmu_id, vaddr_start, size); } #else @@ -753,10 +746,14 @@ esp_err_t IRAM_ATTR esp_mmu_map_dump_mapped_blocks_private(void) ---------------------------------------------------------------*/ static bool NOINLINE_ATTR IRAM_ATTR s_vaddr_to_paddr(uint32_t vaddr, esp_paddr_t *out_paddr, mmu_target_t *out_target) { + uint32_t mmu_id = 0; //we call this for now, but this will be refactored to move out of `spi_flash` spi_flash_disable_interrupts_caches_and_other_cpu(); - bool is_mapped = mmu_hal_vaddr_to_paddr(0, vaddr, out_paddr, out_target); #if SOC_MMU_PER_EXT_MEM_TARGET + mmu_id = mmu_hal_get_id_from_vaddr(vaddr); +#endif + bool is_mapped = mmu_hal_vaddr_to_paddr(mmu_id, vaddr, out_paddr, out_target); +#if SPIRAM_FLASH_LOAD_TO_PSRAM if (!is_mapped) { is_mapped = mmu_hal_vaddr_to_paddr(1, vaddr, out_paddr, out_target); } @@ -789,7 +786,7 @@ static bool NOINLINE_ATTR IRAM_ATTR s_paddr_to_vaddr(esp_paddr_t paddr, mmu_targ spi_flash_disable_interrupts_caches_and_other_cpu(); uint32_t mmu_id = 0; #if SOC_MMU_PER_EXT_MEM_TARGET - mmu_id = s_get_mmu_id_from_target(target); + mmu_id = mmu_hal_get_id_from_target(target); #endif bool found = mmu_hal_paddr_to_vaddr(mmu_id, paddr, target, type, out_vaddr); spi_flash_enable_interrupts_caches_and_other_cpu(); diff --git a/components/hal/esp32p4/include/hal/mmu_ll.h b/components/hal/esp32p4/include/hal/mmu_ll.h index bca29735a6..ce47295354 100644 --- a/components/hal/esp32p4/include/hal/mmu_ll.h +++ b/components/hal/esp32p4/include/hal/mmu_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -84,6 +84,28 @@ static inline mmu_target_t mmu_ll_vaddr_to_target(uint32_t vaddr) return target; } +/** + * Convert MMU virtual address to MMU ID + * + * @param vaddr virtual address + * + * @return MMU ID + */ +__attribute__((always_inline)) +static inline uint32_t mmu_ll_vaddr_to_id(uint32_t vaddr) +{ + uint32_t id = 0; + if (vaddr >= SOC_DRAM_FLASH_ADDRESS_LOW && vaddr < SOC_DRAM_FLASH_ADDRESS_HIGH) { + id = MMU_LL_FLASH_MMU_ID; + } else if (vaddr >= SOC_DRAM_PSRAM_ADDRESS_LOW && vaddr < SOC_DRAM_PSRAM_ADDRESS_HIGH) { + id = MMU_LL_PSRAM_MMU_ID; + } else { + HAL_ASSERT(0); + } + + return id; +} + __attribute__((always_inline)) static inline bool mmu_ll_cache_encryption_enabled(void) { unsigned cnt = efuse_ll_get_flash_crypt_cnt(); diff --git a/components/hal/include/hal/mmu_hal.h b/components/hal/include/hal/mmu_hal.h index 8bb629640f..5033102d34 100644 --- a/components/hal/include/hal/mmu_hal.h +++ b/components/hal/include/hal/mmu_hal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,6 +7,7 @@ #pragma once #include +#include "soc/soc_caps.h" #include "hal/mmu_types.h" #ifdef __cplusplus @@ -118,6 +119,28 @@ bool mmu_hal_paddr_to_vaddr(uint32_t mmu_id, uint32_t paddr, mmu_target_t target */ bool mmu_hal_check_valid_ext_vaddr_region(uint32_t mmu_id, uint32_t vaddr_start, uint32_t len, mmu_vaddr_t type); +#if SOC_MMU_PER_EXT_MEM_TARGET +/** + * Get MMU ID from MMU target + * + * @param target MMU target + * + * @return + * MMU ID + */ +uint32_t mmu_hal_get_id_from_target(mmu_target_t target); + +/** + * Get MMU ID from vaddr + * + * @param vaddr Virtual address + * + * @return + * MMU ID + */ +uint32_t mmu_hal_get_id_from_vaddr(uint32_t vaddr); +#endif + #ifdef __cplusplus } #endif diff --git a/components/hal/mmu_hal.c b/components/hal/mmu_hal.c index e3c9c87c4e..06d8a65e42 100644 --- a/components/hal/mmu_hal.c +++ b/components/hal/mmu_hal.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -161,3 +161,15 @@ bool mmu_hal_check_valid_ext_vaddr_region(uint32_t mmu_id, uint32_t vaddr_start, { return mmu_ll_check_valid_ext_vaddr_region(mmu_id, vaddr_start, len, type); } + +#if SOC_MMU_PER_EXT_MEM_TARGET +uint32_t mmu_hal_get_id_from_target(mmu_target_t target) +{ + return (target == MMU_TARGET_FLASH0) ? MMU_LL_FLASH_MMU_ID : MMU_LL_PSRAM_MMU_ID; +} + +uint32_t mmu_hal_get_id_from_vaddr(uint32_t vaddr) +{ + return mmu_ll_vaddr_to_id(vaddr); +} +#endif From fd09700aab4a56eeaecd1324f5cd8de5b0616efb Mon Sep 17 00:00:00 2001 From: Armando Date: Fri, 14 Feb 2025 11:56:14 +0800 Subject: [PATCH 2/3] test(mmu): added test for checking esp_mmu_vaddr_to_paddr with psram vaddrs --- components/esp_mm/test_apps/mm/CMakeLists.txt | 11 ++++++++ .../esp_mm/test_apps/mm/main/test_mmap.c | 25 ++++++++++++++++++- components/esp_mm/test_apps/mm/pytest_mmap.py | 2 +- .../mm/sdkconfig.ci.psram_release_esp32p4 | 6 +++++ .../mm/sdkconfig.ci.xip_psram_esp32p4 | 7 ++++++ 5 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 components/esp_mm/test_apps/mm/sdkconfig.ci.psram_release_esp32p4 create mode 100644 components/esp_mm/test_apps/mm/sdkconfig.ci.xip_psram_esp32p4 diff --git a/components/esp_mm/test_apps/mm/CMakeLists.txt b/components/esp_mm/test_apps/mm/CMakeLists.txt index 3e976ca666..cf0f0e0182 100644 --- a/components/esp_mm/test_apps/mm/CMakeLists.txt +++ b/components/esp_mm/test_apps/mm/CMakeLists.txt @@ -10,6 +10,16 @@ set(COMPONENTS main esp_psram) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(mm_test) +string(JOIN "," ignore_refs) + +if(CONFIG_SOC_MMU_PER_EXT_MEM_TARGET AND CONFIG_SPIRAM_FLASH_LOAD_TO_PSRAM) + # On SOC_MMU_PER_EXT_MEM_TARGET chips, when xip_psram, we need + # - _instruction_reserved_start, _instruction_reserved_end + # - _rodata_reserved_start, _rodata_reserved_end + # to do some calculation. As we don't access the addresses, so we disable this check + list(APPEND ignore_refs esp_mmu_map_init/*) +endif() + if(CONFIG_COMPILER_DUMP_RTL_FILES) add_custom_target(check_test_app_sections ALL COMMAND ${PYTHON} $ENV{IDF_PATH}/tools/ci/check_callgraph.py @@ -18,6 +28,7 @@ if(CONFIG_COMPILER_DUMP_RTL_FILES) find-refs --from-sections=.iram0.text --to-sections=.flash.text,.flash.rodata + --ignore-refs=${ignore_refs} --exit-code DEPENDS ${elf} ) diff --git a/components/esp_mm/test_apps/mm/main/test_mmap.c b/components/esp_mm/test_apps/mm/main/test_mmap.c index 2fd0f1a2c3..e0ee721d1b 100644 --- a/components/esp_mm/test_apps/mm/main/test_mmap.c +++ b/components/esp_mm/test_apps/mm/main/test_mmap.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -70,3 +70,26 @@ TEST_CASE("Can find paddr caps by any paddr offset", "[mmu]") TEST_ESP_OK(esp_mmu_unmap(ptr0)); } + +#if CONFIG_SPIRAM +#if !CONFIG_IDF_TARGET_ESP32 //ESP32 doesn't support using `esp_mmu_map` to map to PSRAM +TEST_CASE("Can find paddr when mapping to psram", "[mmu]") +{ + esp_paddr_t paddr = 0; + mmu_target_t target = MMU_TARGET_FLASH0; + + void *vaddr = NULL; + esp_err_t err = ESP_FAIL; + + vaddr = heap_caps_malloc(10, MALLOC_CAP_SPIRAM); + err = esp_mmu_vaddr_to_paddr(vaddr, &paddr, &target); + if (err == ESP_OK) { + ESP_LOGI("MMU", "Virtual Address: %p, Physical Address: 0x%lx, Target: %d", vaddr, paddr, target); + } else { + ESP_LOGE("MMU", "Failed to convert virtual address to physical address: %s", esp_err_to_name(err)); + } + + TEST_ASSERT(target == MMU_TARGET_PSRAM0); +} +#endif //#if !CONFIG_IDF_TARGET_ESP32 +#endif //#if CONFIG_SPIRAM diff --git a/components/esp_mm/test_apps/mm/pytest_mmap.py b/components/esp_mm/test_apps/mm/pytest_mmap.py index 5282a7f581..04accedf06 100644 --- a/components/esp_mm/test_apps/mm/pytest_mmap.py +++ b/components/esp_mm/test_apps/mm/pytest_mmap.py @@ -1,6 +1,5 @@ # SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut @@ -24,6 +23,7 @@ PSRAM_RELEASE_CONFIGS = [ pytest.param('psram_release_esp32', marks=[pytest.mark.esp32]), pytest.param('psram_release_esp32s2', marks=[pytest.mark.esp32s2]), pytest.param('psram_release_esp32s3', marks=[pytest.mark.esp32s3]), + pytest.param('psram_release_esp32p4', marks=[pytest.mark.esp32p4]), ] diff --git a/components/esp_mm/test_apps/mm/sdkconfig.ci.psram_release_esp32p4 b/components/esp_mm/test_apps/mm/sdkconfig.ci.psram_release_esp32p4 new file mode 100644 index 0000000000..460e79b5db --- /dev/null +++ b/components/esp_mm/test_apps/mm/sdkconfig.ci.psram_release_esp32p4 @@ -0,0 +1,6 @@ +CONFIG_IDF_TARGET="esp32p4" +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y + +CONFIG_SPIRAM=y diff --git a/components/esp_mm/test_apps/mm/sdkconfig.ci.xip_psram_esp32p4 b/components/esp_mm/test_apps/mm/sdkconfig.ci.xip_psram_esp32p4 new file mode 100644 index 0000000000..c7d28cedd0 --- /dev/null +++ b/components/esp_mm/test_apps/mm/sdkconfig.ci.xip_psram_esp32p4 @@ -0,0 +1,7 @@ +CONFIG_IDF_TARGET="esp32p4" +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y + +CONFIG_SPIRAM=y +CONFIG_SPIRAM_XIP_FROM_PSRAM=y From 43121c0d47ec94a7531c30b6c3083e6ecf1ecc4d Mon Sep 17 00:00:00 2001 From: Armando Date: Fri, 14 Feb 2025 11:58:06 +0800 Subject: [PATCH 3/3] test(flash_mmap): added psram enabled test for esp32p4 as mmu is per target --- .../spi_flash/test_apps/.build-test-rules.yml | 1 + .../test_apps/flash_mmap/pytest_flash_mmap.py | 15 ++++++++++++++- .../test_apps/flash_mmap/sdkconfig.ci.psram | 1 + 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 components/spi_flash/test_apps/flash_mmap/sdkconfig.ci.psram diff --git a/components/spi_flash/test_apps/.build-test-rules.yml b/components/spi_flash/test_apps/.build-test-rules.yml index 74c9c0eb7a..c308a5e549 100644 --- a/components/spi_flash/test_apps/.build-test-rules.yml +++ b/components/spi_flash/test_apps/.build-test-rules.yml @@ -36,6 +36,7 @@ components/spi_flash/test_apps/flash_mmap: - spi_flash enable: - if: CONFIG_NAME in ["release", "rom_impl"] and IDF_TARGET in ["esp32", "esp32c2", "esp32c3", "esp32c5", "esp32c6", "esp32c61", "esp32h2", "esp32p4", "esp32s2", "esp32s3"] + - if: CONFIG_NAME == "psram" and SOC_MMU_PER_EXT_MEM_TARGET == 1 # MMU per target needs test. On unified MMU chips, the entry ID is unique - if: CONFIG_NAME == "xip_psram" and IDF_TARGET in ["esp32s2", "esp32s3", "esp32p4"] # S2 doesn't have ROM for flash - if: CONFIG_NAME == "xip_psram_with_rom_impl" and IDF_TARGET in ["esp32s3", "esp32p4"] 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 de8fd80f44..0e5a8078b0 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,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 import pytest from pytest_embedded import Dut @@ -47,6 +47,19 @@ def test_flash_mmap_xip_psram(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=30) +@pytest.mark.supported_targets +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'psram', + ], + indirect=True, +) +def test_flash_mmap_psram(dut: Dut) -> None: + dut.run_all_single_board_cases(timeout=30) + + @pytest.mark.supported_targets @pytest.mark.generic @pytest.mark.parametrize( diff --git a/components/spi_flash/test_apps/flash_mmap/sdkconfig.ci.psram b/components/spi_flash/test_apps/flash_mmap/sdkconfig.ci.psram new file mode 100644 index 0000000000..cc641ea603 --- /dev/null +++ b/components/spi_flash/test_apps/flash_mmap/sdkconfig.ci.psram @@ -0,0 +1 @@ +CONFIG_SPIRAM=y