From 7911e997ffa73156cd1c57c7aaadadb2c8a36139 Mon Sep 17 00:00:00 2001 From: Armando Date: Mon, 3 Jul 2023 16:08:41 +0800 Subject: [PATCH 1/3] fix(flash_mmap): fixed limited free I/D pages on ESP32S3, C3 --- components/esp_rom/CMakeLists.txt | 7 +++- components/esp_rom/component.mk | 2 ++ components/esp_rom/linker.lf | 6 ++++ components/esp_rom/patches/esp_rom_mmap.c | 34 +++++++++++++++++++ .../soc/esp32/include/soc/cache_memory.h | 17 ++++++++++ .../soc/esp32c3/include/soc/cache_memory.h | 2 +- .../soc/esp32h2/include/soc/cache_memory.h | 2 +- components/soc/esp32s2/include/soc/mmu.h | 1 + .../soc/esp32s3/include/soc/cache_memory.h | 2 +- components/soc/esp32s3/include/soc/mmu.h | 1 + components/spi_flash/flash_mmap.c | 16 ++++++--- 11 files changed, 82 insertions(+), 8 deletions(-) create mode 100644 components/esp_rom/linker.lf create mode 100644 components/esp_rom/patches/esp_rom_mmap.c create mode 100644 components/soc/esp32/include/soc/cache_memory.h diff --git a/components/esp_rom/CMakeLists.txt b/components/esp_rom/CMakeLists.txt index 36cd409550..b748253c86 100644 --- a/components/esp_rom/CMakeLists.txt +++ b/components/esp_rom/CMakeLists.txt @@ -34,9 +34,14 @@ if(target STREQUAL "esp32s3") list(APPEND sources "patches/esp_rom_cache_writeback_esp32s3.S") endif() +if(target STREQUAL "esp32s3" OR target STREQUAL "esp32c3" OR target STREQUAL "esp32h2") + list(APPEND sources "patches/esp_rom_mmap.c") +endif() + idf_component_register(SRCS ${sources} INCLUDE_DIRS ${include_dirs} - PRIV_REQUIRES ${private_required_comp}) + PRIV_REQUIRES ${private_required_comp} + LDFRAGMENTS linker.lf) # Append a target linker script at the target-specific path, # only the 'name' part is different for each script diff --git a/components/esp_rom/component.mk b/components/esp_rom/component.mk index 161c8ef480..7607cd4a60 100644 --- a/components/esp_rom/component.mk +++ b/components/esp_rom/component.mk @@ -7,6 +7,8 @@ ifdef IS_BOOTLOADER_BUILD COMPONENT_OBJEXCLUDE += patches/esp_rom_longjmp.o endif +COMPONENT_OBJEXCLUDE := patches/esp_rom_mmap.o + #Linker scripts used to link the final application. #Warning: These linker scripts are only used when the normal app is compiled; the bootloader #specifies its own scripts. diff --git a/components/esp_rom/linker.lf b/components/esp_rom/linker.lf new file mode 100644 index 0000000000..5ee1b9adaf --- /dev/null +++ b/components/esp_rom/linker.lf @@ -0,0 +1,6 @@ +[mapping:esp_rom] +archive: libesp_rom.a +entries: + if IDF_TARGET_ESP32S3 = y || IDF_TARGET_ESP32C3 = y + || IDF_TARGET_ESP32H2 = y: + esp_rom_mmap (noflash) diff --git a/components/esp_rom/patches/esp_rom_mmap.c b/components/esp_rom/patches/esp_rom_mmap.c new file mode 100644 index 0000000000..a8cd91e353 --- /dev/null +++ b/components/esp_rom/patches/esp_rom_mmap.c @@ -0,0 +1,34 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "sdkconfig.h" +#include "esp_rom_sys.h" +#include "assert.h" + +uint32_t Cache_Get_IROM_MMU_End(void) +{ +#if CONFIG_IDF_TARGET_ESP32S3 + esp_rom_printf("0x800\n"); + return 0x800; +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 + return 0x200; +#else + assert(false); +#endif +} + +uint32_t Cache_Get_DROM_MMU_End(void) +{ +#if CONFIG_IDF_TARGET_ESP32S3 + return 0x800; +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 + return 0x200; +#else + assert(false); +#endif +} diff --git a/components/soc/esp32/include/soc/cache_memory.h b/components/soc/esp32/include/soc/cache_memory.h new file mode 100644 index 0000000000..aade7c799b --- /dev/null +++ b/components/soc/esp32/include/soc/cache_memory.h @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#define MMU_INVALID BIT(8) + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c3/include/soc/cache_memory.h b/components/soc/esp32c3/include/soc/cache_memory.h index 350cc8dec9..aeb7365be9 100644 --- a/components/soc/esp32c3/include/soc/cache_memory.h +++ b/components/soc/esp32c3/include/soc/cache_memory.h @@ -54,7 +54,7 @@ extern "C" { #define CACHE_IROM_MMU_END Cache_Get_IROM_MMU_End() #define CACHE_IROM_MMU_SIZE (CACHE_IROM_MMU_END - CACHE_IROM_MMU_START) -#define CACHE_DROM_MMU_START CACHE_IROM_MMU_END +#define CACHE_DROM_MMU_START 0 #define CACHE_DROM_MMU_END Cache_Get_DROM_MMU_End() #define CACHE_DROM_MMU_SIZE (CACHE_DROM_MMU_END - CACHE_DROM_MMU_START) diff --git a/components/soc/esp32h2/include/soc/cache_memory.h b/components/soc/esp32h2/include/soc/cache_memory.h index db558c4e50..b146eeb218 100644 --- a/components/soc/esp32h2/include/soc/cache_memory.h +++ b/components/soc/esp32h2/include/soc/cache_memory.h @@ -55,7 +55,7 @@ extern "C" { #define CACHE_IROM_MMU_END Cache_Get_IROM_MMU_End() #define CACHE_IROM_MMU_SIZE (CACHE_IROM_MMU_END - CACHE_IROM_MMU_START) -#define CACHE_DROM_MMU_START CACHE_IROM_MMU_END +#define CACHE_DROM_MMU_START 0 #define CACHE_DROM_MMU_END Cache_Get_DROM_MMU_End() #define CACHE_DROM_MMU_SIZE (CACHE_DROM_MMU_END - CACHE_DROM_MMU_START) diff --git a/components/soc/esp32s2/include/soc/mmu.h b/components/soc/esp32s2/include/soc/mmu.h index 44f716f217..8d702a4812 100644 --- a/components/soc/esp32s2/include/soc/mmu.h +++ b/components/soc/esp32s2/include/soc/mmu.h @@ -31,6 +31,7 @@ extern "C" { #define SOC_MMU_INVALID_ENTRY_VAL MMU_TABLE_INVALID_VAL #define SOC_MMU_ADDR_MASK MMU_ADDRESS_MASK #define SOC_MMU_PAGE_IN_FLASH(page) ((page) | MMU_ACCESS_FLASH) +#define SOC_MMU_PAGE_IN_PSRAM(page) ((page) | MMU_ACCESS_SPIRAM) #define SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE FLASH_MMU_TABLE #define SOC_MMU_VADDR1_START_ADDR SOC_IROM_MASK_LOW #define SOC_MMU_PRO_IRAM0_FIRST_USABLE_PAGE ((SOC_MMU_VADDR1_FIRST_USABLE_ADDR - SOC_MMU_VADDR1_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE + SOC_MMU_IROM0_PAGES_START) diff --git a/components/soc/esp32s3/include/soc/cache_memory.h b/components/soc/esp32s3/include/soc/cache_memory.h index 221a77b503..6d4bee8b56 100644 --- a/components/soc/esp32s3/include/soc/cache_memory.h +++ b/components/soc/esp32s3/include/soc/cache_memory.h @@ -53,7 +53,7 @@ extern "C" { #define CACHE_IROM_MMU_END Cache_Get_IROM_MMU_End() #define CACHE_IROM_MMU_SIZE (CACHE_IROM_MMU_END - CACHE_IROM_MMU_START) -#define CACHE_DROM_MMU_START CACHE_IROM_MMU_END +#define CACHE_DROM_MMU_START 0 #define CACHE_DROM_MMU_END Cache_Get_DROM_MMU_End() #define CACHE_DROM_MMU_SIZE (CACHE_DROM_MMU_END - CACHE_DROM_MMU_START) diff --git a/components/soc/esp32s3/include/soc/mmu.h b/components/soc/esp32s3/include/soc/mmu.h index a38cb9eb42..a0d62b2a76 100644 --- a/components/soc/esp32s3/include/soc/mmu.h +++ b/components/soc/esp32s3/include/soc/mmu.h @@ -31,6 +31,7 @@ extern "C" { #define SOC_MMU_INVALID_ENTRY_VAL MMU_TABLE_INVALID_VAL #define SOC_MMU_ADDR_MASK MMU_ADDRESS_MASK #define SOC_MMU_PAGE_IN_FLASH(page) ((page) | MMU_ACCESS_FLASH) +#define SOC_MMU_PAGE_IN_PSRAM(page) ((page) | MMU_ACCESS_SPIRAM) #define SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE FLASH_MMU_TABLE #define SOC_MMU_VADDR1_START_ADDR IRAM0_CACHE_ADDRESS_LOW #define SOC_MMU_PRO_IRAM0_FIRST_USABLE_PAGE SOC_MMU_IROM0_PAGES_START diff --git a/components/spi_flash/flash_mmap.c b/components/spi_flash/flash_mmap.c index 9523bc7959..90bf074d9c 100644 --- a/components/spi_flash/flash_mmap.c +++ b/components/spi_flash/flash_mmap.c @@ -29,6 +29,7 @@ #include "esp_flash_encrypt.h" #include "esp_log.h" #include "cache_utils.h" +#include "soc/cache_memory.h" #if CONFIG_IDF_TARGET_ESP32 #include "soc/dport_reg.h" @@ -41,24 +42,20 @@ #include "esp32s2/rom/spi_flash.h" #include "esp32s2/spiram.h" #include "soc/extmem_reg.h" -#include "soc/cache_memory.h" #include "soc/mmu.h" #elif CONFIG_IDF_TARGET_ESP32S3 #include "esp32s3/rom/spi_flash.h" #include "esp32s3/rom/cache.h" #include "esp32s3/spiram.h" #include "soc/extmem_reg.h" -#include "soc/cache_memory.h" #include "soc/mmu.h" #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/rom/cache.h" #include "esp32c3/rom/spi_flash.h" -#include "soc/cache_memory.h" #include "soc/mmu.h" #elif CONFIG_IDF_TARGET_ESP32H2 #include "esp32h2/rom/cache.h" #include "esp32h2/rom/spi_flash.h" -#include "soc/cache_memory.h" #include "soc/mmu.h" #endif @@ -207,6 +204,13 @@ esp_err_t IRAM_ATTR spi_flash_mmap_pages(const int *pages, size_t page_count, sp for (pos = start; pos < start + page_count; ++pos, ++pageno) { int table_val = (int) DPORT_SEQUENCE_REG_READ((uint32_t)&SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[pos]); uint8_t refcnt = s_mmap_page_refcnt[pos]; + +#if !CONFIG_IDF_TARGET_ESP32 && SOC_SPIRAM_SUPPORTED + if (table_val & MMU_ACCESS_SPIRAM) { + break; + } +#endif //#if !CONFIG_IDF_TARGET_ESP32 + if (refcnt != 0 && table_val != SOC_MMU_PAGE_IN_FLASH(pages[pageno])) { break; } @@ -237,6 +241,10 @@ esp_err_t IRAM_ATTR spi_flash_mmap_pages(const int *pages, size_t page_count, sp #endif )); if (s_mmap_page_refcnt[i] == 0) { + assert(DPORT_SEQUENCE_REG_READ((uint32_t)&SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[i]) & MMU_INVALID); +#if !CONFIG_FREERTOS_UNICORE && CONFIG_IDF_TARGET_ESP32 + assert(DPORT_SEQUENCE_REG_READ((uint32_t)&DPORT_APP_FLASH_MMU_TABLE[i]) & MMU_INVALID); +#endif if (entry_pro != SOC_MMU_PAGE_IN_FLASH(pages[pageno]) #if !CONFIG_FREERTOS_UNICORE && CONFIG_IDF_TARGET_ESP32 || entry_app != SOC_MMU_PAGE_IN_FLASH(pages[pageno]) From 45877f317699e164a226e1ac6d9d2c1167fbd20d Mon Sep 17 00:00:00 2001 From: Armando Date: Mon, 3 Jul 2023 16:08:59 +0800 Subject: [PATCH 2/3] test(flash_mmap): test flash mmap pages --- .gitlab/ci/target-test.yml | 15 +- components/esp_rom/component.mk | 3 +- .../system/flash_mmap/CMakeLists.txt | 4 + tools/test_apps/system/flash_mmap/README.md | 4 + tools/test_apps/system/flash_mmap/app_test.py | 56 ++++++ .../system/flash_mmap/main/CMakeLists.txt | 5 + .../system/flash_mmap/main/test_flash_mmap.c | 163 ++++++++++++++++++ .../system/flash_mmap/partitions.csv | 6 + .../flash_mmap/sdkconfig.ci.esp32_psram | 3 + .../flash_mmap/sdkconfig.ci.esp32s2_psram | 5 + .../system/flash_mmap/sdkconfig.ci.f4r8 | 10 ++ .../system/flash_mmap/sdkconfig.defaults | 5 + 12 files changed, 267 insertions(+), 12 deletions(-) create mode 100644 tools/test_apps/system/flash_mmap/CMakeLists.txt create mode 100644 tools/test_apps/system/flash_mmap/README.md create mode 100644 tools/test_apps/system/flash_mmap/app_test.py create mode 100644 tools/test_apps/system/flash_mmap/main/CMakeLists.txt create mode 100644 tools/test_apps/system/flash_mmap/main/test_flash_mmap.c create mode 100644 tools/test_apps/system/flash_mmap/partitions.csv create mode 100644 tools/test_apps/system/flash_mmap/sdkconfig.ci.esp32_psram create mode 100644 tools/test_apps/system/flash_mmap/sdkconfig.ci.esp32s2_psram create mode 100644 tools/test_apps/system/flash_mmap/sdkconfig.ci.f4r8 create mode 100644 tools/test_apps/system/flash_mmap/sdkconfig.defaults diff --git a/.gitlab/ci/target-test.yml b/.gitlab/ci/target-test.yml index 6bd24dcf71..ed4fe24f3f 100644 --- a/.gitlab/ci/target-test.yml +++ b/.gitlab/ci/target-test.yml @@ -363,7 +363,6 @@ test_app_test_003: test_app_test_004: extends: .test_app_esp32s2_template - parallel: 2 tags: - ESP32S2 - Example_GENERIC @@ -407,17 +406,11 @@ test_app_test_flash_psram_f8r8: - ESP32S3 - MSPI_F8R8 -test_app_test_xip_psram_esp32s2: - extends: .test_app_esp32s2_template +test_app_test_flash_psram_esp32: + extends: .test_app_esp32_template tags: - - ESP32S2 - - Example_GENERIC - -test_app_test_xip_psram_esp32s3: - extends: .test_app_esp32s3_template - tags: - - ESP32S3 - - MSPI_F4R8 + - ESP32 + - psram .component_ut_template: extends: .target_test_job_template diff --git a/components/esp_rom/component.mk b/components/esp_rom/component.mk index 7607cd4a60..5799bb7986 100644 --- a/components/esp_rom/component.mk +++ b/components/esp_rom/component.mk @@ -3,11 +3,12 @@ COMPONENT_SRCDIRS := patches . COMPONENT_OBJEXCLUDE := patches/esp_rom_cache_writeback_esp32s3.o +COMPONENT_OBJEXCLUDE += patches/esp_rom_mmap.o + ifdef IS_BOOTLOADER_BUILD COMPONENT_OBJEXCLUDE += patches/esp_rom_longjmp.o endif -COMPONENT_OBJEXCLUDE := patches/esp_rom_mmap.o #Linker scripts used to link the final application. #Warning: These linker scripts are only used when the normal app is compiled; the bootloader diff --git a/tools/test_apps/system/flash_mmap/CMakeLists.txt b/tools/test_apps/system/flash_mmap/CMakeLists.txt new file mode 100644 index 0000000000..9d03acb035 --- /dev/null +++ b/tools/test_apps/system/flash_mmap/CMakeLists.txt @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(flash_mmap_test) diff --git a/tools/test_apps/system/flash_mmap/README.md b/tools/test_apps/system/flash_mmap/README.md new file mode 100644 index 0000000000..8675926e21 --- /dev/null +++ b/tools/test_apps/system/flash_mmap/README.md @@ -0,0 +1,4 @@ +| Supported Targets | ESP32 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | + +This test app is used to test flash mmap with PSRAM diff --git a/tools/test_apps/system/flash_mmap/app_test.py b/tools/test_apps/system/flash_mmap/app_test.py new file mode 100644 index 0000000000..6f54f2a709 --- /dev/null +++ b/tools/test_apps/system/flash_mmap/app_test.py @@ -0,0 +1,56 @@ +# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 + + +import glob +import os +from typing import Any + +import ttfw_idf +from tiny_test_fw import Utility + + +def test_func(env, dut): # type: (Any, Any) -> None + + dut.start_app() + dut.expect('success', timeout=60) + env.close_dut(dut.name) + + +def test_loop(env, config_names): # type: (Any, Any) -> None + + for name in config_names: + Utility.console_log("Checking config \"{}\"... ".format(name), end='') + dut = env.get_dut('flash_mmap', 'tools/test_apps/system/flash_mmap', app_config_name=name) + test_func(env, dut) + Utility.console_log('done') + + +@ttfw_idf.idf_custom_test(env_tag='MSPI_F4R8', target=['esp32s3']) +def test_mmap_esp32s3(env, _): # type: (Any, Any) -> None + + config_files = glob.glob(os.path.join(os.path.dirname(__file__), 'sdkconfig.ci.esp32s3_f4r8*')) + config_names = [os.path.basename(s).replace('sdkconfig.ci.', '') for s in config_files] + test_loop(env, config_names) + + +@ttfw_idf.idf_custom_test(env_tag='Example_GENERIC', target=['esp32s2']) +def test_mmap_esp32s2(env, _): # type: (Any, Any) -> None + + config_files = glob.glob(os.path.join(os.path.dirname(__file__), 'sdkconfig.ci.esp32s2_*')) + config_names = [os.path.basename(s).replace('sdkconfig.ci.', '') for s in config_files] + test_loop(env, config_names) + + +@ttfw_idf.idf_custom_test(env_tag='psram', target=['esp32']) +def test_mmap_esp32(env, _): # type: (Any, Any) -> None + + config_files = glob.glob(os.path.join(os.path.dirname(__file__), 'sdkconfig.ci.esp32_*')) + config_names = [os.path.basename(s).replace('sdkconfig.ci.', '') for s in config_files] + test_loop(env, config_names) + + +if __name__ == '__main__': + test_mmap_esp32s3() + test_mmap_esp32s2() + test_mmap_esp32() diff --git a/tools/test_apps/system/flash_mmap/main/CMakeLists.txt b/tools/test_apps/system/flash_mmap/main/CMakeLists.txt new file mode 100644 index 0000000000..c5785e8e1b --- /dev/null +++ b/tools/test_apps/system/flash_mmap/main/CMakeLists.txt @@ -0,0 +1,5 @@ +idf_build_get_property(target IDF_TARGET) + +set(srcs "test_flash_mmap.c") + +idf_component_register(SRCS ${srcs}) diff --git a/tools/test_apps/system/flash_mmap/main/test_flash_mmap.c b/tools/test_apps/system/flash_mmap/main/test_flash_mmap.c new file mode 100644 index 0000000000..178a600479 --- /dev/null +++ b/tools/test_apps/system/flash_mmap/main/test_flash_mmap.c @@ -0,0 +1,163 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include "sdkconfig.h" +#include "unity.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "esp_check.h" +#include "esp_attr.h" +#include "esp_flash.h" +#include "esp_partition.h" +#include "esp_spi_flash.h" + +const static char *TAG = "MMAP_TEST"; + +#define TEST_BLOCK_SIZE 0x10000 + +typedef struct test_block_info_ { + uint32_t vaddr; + spi_flash_mmap_handle_t handle; + LIST_ENTRY(test_block_info_) entries; +} test_block_info_t; + +static LIST_HEAD(test_block_list_head_, test_block_info_) test_block_head; +static DRAM_ATTR uint8_t sector_buf[TEST_BLOCK_SIZE]; + +static const esp_partition_t *s_get_partition(void) +{ + //Find the "storage1" partition defined in `partitions.csv` + const esp_partition_t *result = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, "storage1"); + if (!result) { + ESP_LOGE(TAG, "Can't find the partition, please define it correctly in `partitions.csv`"); + abort(); + } + return result; +} + + +static void s_fill_random_data(uint8_t *buffer, size_t size, int random_seed) +{ + srand(random_seed); + for (int i = 0 ; i < size; i++) { + buffer[i] = rand() % 0xff; + } +} + +static bool s_test_mmap_data_by_random(uint8_t *mblock_ptr, size_t size, int random_seed) +{ + srand(random_seed); + uint8_t *test_ptr = mblock_ptr; + + for (int i = 0; i < size; i++) { + uint8_t test_data = rand() % 0xff; + if(test_data != test_ptr[i]) { + printf("i: %d\n", i); + printf("test_data: %d\n", test_data); + printf("test_ptr[%d]: %d\n", i, test_ptr[i]); + printf("sector_buf[%d]: %d\n", i, sector_buf[i]); + ESP_EARLY_LOGE(TAG, "FAIL!!!!!!"); + return false; + } + } + return true; +} + +static void s_print_free_pages(void) +{ + uint32_t free_i_pages = spi_flash_mmap_get_free_pages(SPI_FLASH_MMAP_INST); + uint32_t free_d_pages = spi_flash_mmap_get_free_pages(SPI_FLASH_MMAP_DATA); + printf("free_i_pages: 0d%"PRId32"\n", free_i_pages); + printf("free_d_pages: 0d%"PRId32"\n", free_d_pages); +} + +void app_main(void) +{ + //Get the partition used for SPI1 erase operation + const esp_partition_t *part = s_get_partition(); + ESP_LOGI(TAG, "found partition '%s' at offset 0x%"PRIx32" with size 0x%"PRIx32, part->label, part->address, part->size); + + //Erase whole region + TEST_ESP_OK(esp_flash_erase_region(part->flash_chip, part->address, part->size)); + + ESP_LOGI(TAG, "TEST_BLOCK_SIZE: 0x%x", TEST_BLOCK_SIZE); + s_print_free_pages(); + + uint32_t offset = 0; + int test_seed = 299; + while (1) { + s_fill_random_data(sector_buf, sizeof(sector_buf), test_seed); + ESP_LOGI(TAG, "rand seed: %d, write flash addr: %p...", test_seed, (void *)(part->address + offset)); + TEST_ESP_OK(esp_flash_write(part->flash_chip, sector_buf, (part->address + offset), sizeof(sector_buf))); + + test_seed++; + offset += TEST_BLOCK_SIZE; + + if (offset == part->size) { + break; + } + } + + esp_err_t ret = ESP_FAIL; + int count = 0; + LIST_INIT(&test_block_head); + + offset = 0; + test_seed = 299; + + while (1) { + test_block_info_t *block_info = heap_caps_calloc(1, sizeof(test_block_info_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); + TEST_ASSERT(block_info && "no mem"); + + spi_flash_mmap_handle_t handle; + const void *ptr = NULL; + ret = spi_flash_mmap(part->address + offset, TEST_BLOCK_SIZE, SPI_FLASH_MMAP_DATA, &ptr, &handle); + if (ret == ESP_OK) { + ESP_LOGI(TAG, "ptr is %p", ptr); + + s_fill_random_data(sector_buf, sizeof(sector_buf), test_seed); + bool success = s_test_mmap_data_by_random((uint8_t *)ptr, sizeof(sector_buf), test_seed); + TEST_ASSERT(success); + } else if (ret == ESP_ERR_NOT_FOUND) { + free(block_info); + break; + } else { + ESP_LOGE(TAG, "ret: 0x%x", ret); + TEST_ASSERT(false); + } + + block_info->vaddr = (uint32_t)ptr; + block_info->handle = handle; + LIST_INSERT_HEAD(&test_block_head, block_info, entries); + count++; + test_seed++; + offset += TEST_BLOCK_SIZE; + + if (offset == part->size) { + break; + } + } + + ESP_LOGI(TAG, "no more free block / free flash size, finish test, test block size: 0x%x, count: 0d%d", TEST_BLOCK_SIZE, count); + s_print_free_pages(); + + test_block_info_t *block_to_free = LIST_FIRST(&test_block_head); + test_block_info_t *temp = NULL; + while (block_to_free) { + temp = block_to_free; + spi_flash_munmap(block_to_free->handle); + block_to_free = LIST_NEXT(block_to_free, entries); + free(temp); + } + s_print_free_pages(); + + printf("flash mmap test success\n"); +} diff --git a/tools/test_apps/system/flash_mmap/partitions.csv b/tools/test_apps/system/flash_mmap/partitions.csv new file mode 100644 index 0000000000..488c92b9f4 --- /dev/null +++ b/tools/test_apps/system/flash_mmap/partitions.csv @@ -0,0 +1,6 @@ +# Name, Type, SubType, Offset, Size, Flags +# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap +nvs, data, nvs, 0x9000, 0x6000, +phy_init, data, phy, 0xf000, 0x1000, +factory, app, factory, 0x10000, 1M, +storage1, data, fat, , 896K, diff --git a/tools/test_apps/system/flash_mmap/sdkconfig.ci.esp32_psram b/tools/test_apps/system/flash_mmap/sdkconfig.ci.esp32_psram new file mode 100644 index 0000000000..1181f79cdf --- /dev/null +++ b/tools/test_apps/system/flash_mmap/sdkconfig.ci.esp32_psram @@ -0,0 +1,3 @@ +CONFIG_IDF_TARGET="esp32" + +CONFIG_ESP32_SPIRAM_SUPPORT=y diff --git a/tools/test_apps/system/flash_mmap/sdkconfig.ci.esp32s2_psram b/tools/test_apps/system/flash_mmap/sdkconfig.ci.esp32s2_psram new file mode 100644 index 0000000000..1df1aaeb29 --- /dev/null +++ b/tools/test_apps/system/flash_mmap/sdkconfig.ci.esp32s2_psram @@ -0,0 +1,5 @@ +CONFIG_IDF_TARGET="esp32s2" + +CONFIG_ESP32S2_SPIRAM_SUPPORT=y +CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y +CONFIG_SPIRAM_RODATA=y diff --git a/tools/test_apps/system/flash_mmap/sdkconfig.ci.f4r8 b/tools/test_apps/system/flash_mmap/sdkconfig.ci.f4r8 new file mode 100644 index 0000000000..6899e49de0 --- /dev/null +++ b/tools/test_apps/system/flash_mmap/sdkconfig.ci.f4r8 @@ -0,0 +1,10 @@ +# F4R8, Flash 80M SDR, PSRAM 80M DDR +CONFIG_IDF_TARGET="esp32s3" + +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_SPIRAM=y +CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIRAM_SPEED_80M=y +CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y +CONFIG_SPIRAM_RODATA=y diff --git a/tools/test_apps/system/flash_mmap/sdkconfig.defaults b/tools/test_apps/system/flash_mmap/sdkconfig.defaults new file mode 100644 index 0000000000..ad42538001 --- /dev/null +++ b/tools/test_apps/system/flash_mmap/sdkconfig.defaults @@ -0,0 +1,5 @@ +CONFIG_ESP_TASK_WDT_EN=n + +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" From 69563f06c9fec2ae7f27da1754c5cf67ae8d471c Mon Sep 17 00:00:00 2001 From: Armando Date: Mon, 3 Jul 2023 16:49:38 +0800 Subject: [PATCH 3/3] fix(memory): no enough memory for rodata --- .../esp_hw_support/port/esp32s3/spiram.c | 26 +++++++++++++++---- components/esp_rom/patches/esp_rom_mmap.c | 1 - components/esp_system/ld/esp32s3/memory.ld.in | 2 +- .../esp_system/ld/esp32s3/sections.ld.in | 6 ++++- 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/components/esp_hw_support/port/esp32s3/spiram.c b/components/esp_hw_support/port/esp32s3/spiram.c index 0b508e9a18..2e06a80135 100644 --- a/components/esp_hw_support/port/esp32s3/spiram.c +++ b/components/esp_hw_support/port/esp32s3/spiram.c @@ -30,6 +30,9 @@ we add more types of external RAM memory, this can be made into a more intellige #define PSRAM_MODE PSRAM_VADDR_MODE_NORMAL +//This is for size align +#define ALIGN_UP_BY(num, align) (((num) + ((align) - 1)) & ~((align) - 1)) + #if CONFIG_SPIRAM static const char *TAG = "spiram"; @@ -41,6 +44,7 @@ static const char *TAG = "spiram"; #endif static bool s_spiram_inited = false; +extern int _rodata_reserved_end; /* @@ -87,13 +91,25 @@ bool esp_spiram_test(void) void IRAM_ATTR esp_spiram_init_cache(void) { + + uint32_t rodata_end_aligned = ALIGN_UP_BY((uint32_t)&_rodata_reserved_end, 0x10000); + ESP_EARLY_LOGD(TAG, "rodata_end_aligned addr: 0x%x (page size: 0x%x)", rodata_end_aligned, 0x10000); + size_t spiram_size = esp_spiram_get_size(); - Cache_Suspend_DCache(); - if ((SOC_EXTRAM_DATA_HIGH - SOC_EXTRAM_DATA_LOW) >= spiram_size) { - Cache_Dbus_MMU_Set(MMU_ACCESS_SPIRAM, SOC_EXTRAM_DATA_HIGH - spiram_size, 0, 64, spiram_size >> 16, 0); - } else { - Cache_Dbus_MMU_Set(MMU_ACCESS_SPIRAM, SOC_EXTRAM_DATA_HIGH - spiram_size, 0, 64, (SOC_EXTRAM_DATA_HIGH - SOC_EXTRAM_DATA_LOW) >> 16, 0); + if ((SOC_EXTRAM_DATA_HIGH - SOC_EXTRAM_DATA_LOW) < spiram_size) { + spiram_size = SOC_EXTRAM_DATA_HIGH - SOC_EXTRAM_DATA_LOW; } + uint32_t vaddr_start = SOC_EXTRAM_DATA_HIGH - spiram_size; + ESP_EARLY_LOGD(TAG, "psram vaddr_start addr: 0x%x", vaddr_start); + + if (vaddr_start < rodata_end_aligned) { + ESP_EARLY_LOGE(TAG, "bin size too big, no enough page to map psram"); + abort(); + } + + Cache_Suspend_DCache(); + Cache_Dbus_MMU_Set(MMU_ACCESS_SPIRAM, SOC_EXTRAM_DATA_HIGH - spiram_size, 0, 64, spiram_size >> 16, 0); + REG_CLR_BIT(EXTMEM_DCACHE_CTRL1_REG, EXTMEM_DCACHE_SHUT_CORE0_BUS); #if !CONFIG_FREERTOS_UNICORE REG_CLR_BIT(EXTMEM_DCACHE_CTRL1_REG, EXTMEM_DCACHE_SHUT_CORE1_BUS); diff --git a/components/esp_rom/patches/esp_rom_mmap.c b/components/esp_rom/patches/esp_rom_mmap.c index a8cd91e353..40f9280cf8 100644 --- a/components/esp_rom/patches/esp_rom_mmap.c +++ b/components/esp_rom/patches/esp_rom_mmap.c @@ -13,7 +13,6 @@ uint32_t Cache_Get_IROM_MMU_End(void) { #if CONFIG_IDF_TARGET_ESP32S3 - esp_rom_printf("0x800\n"); return 0x800; #elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 return 0x200; diff --git a/components/esp_system/ld/esp32s3/memory.ld.in b/components/esp_system/ld/esp32s3/memory.ld.in index c745e8c8d8..503f238ac3 100644 --- a/components/esp_system/ld/esp32s3/memory.ld.in +++ b/components/esp_system/ld/esp32s3/memory.ld.in @@ -90,7 +90,7 @@ MEMORY #if CONFIG_APP_BUILD_USE_FLASH_SECTIONS /* Flash mapped constant data */ - drom0_0_seg (R) : org = 0x3C000020, len = 0x800000-0x20 + drom0_0_seg (R) : org = 0x3C000020, len = 0x2000000-0x20 /* (See iram0_2_seg for meaning of 0x20 offset in the above.) */ #endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS diff --git a/components/esp_system/ld/esp32s3/sections.ld.in b/components/esp_system/ld/esp32s3/sections.ld.in index f40473dfca..72f8a69cf8 100644 --- a/components/esp_system/ld/esp32s3/sections.ld.in +++ b/components/esp_system/ld/esp32s3/sections.ld.in @@ -367,7 +367,6 @@ SECTIONS *(.tbss) *(.tbss.*) _thread_local_end = ABSOLUTE(.); - _rodata_reserved_end = ABSOLUTE(.); . = ALIGN(4); } > default_rodata_seg @@ -375,6 +374,11 @@ SECTIONS .flash.rodata_noload (NOLOAD) : { + /* + This is a symbol marking the flash.rodata end, this can be used for mmu driver to maintain virtual address + We don't need to include the noload rodata in this section + */ + _rodata_reserved_end = ABSOLUTE(.); . = ALIGN (4); mapping[rodata_noload] } > default_rodata_seg