From 69563f06c9fec2ae7f27da1754c5cf67ae8d471c Mon Sep 17 00:00:00 2001 From: Armando Date: Mon, 3 Jul 2023 16:49:38 +0800 Subject: [PATCH] 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