From fca600f685be03af6fdfa94c1bf5f07948f973a7 Mon Sep 17 00:00:00 2001 From: Volkalex28 Date: Wed, 17 Jan 2024 16:08:20 +0200 Subject: [PATCH] Add linker script for external ram for esp32s3 --- esp-hal-common/ld/esp32s3/esp32s3.x | 2 + esp-hal-common/ld/esp32s3/memory.x | 5 +- esp-hal-common/ld/sections/external.x | 36 +++++++++++++ .../ld/sections/fixups/external_ram_dummy.x | 17 +++++++ .../ld/sections/fixups/rodata_dummy.x | 1 + esp-hal-common/ld/sections/rodata.x | 1 + esp-hal-common/src/soc/esp32s3/psram.rs | 50 ++++++++++++------- 7 files changed, 94 insertions(+), 18 deletions(-) create mode 100644 esp-hal-common/ld/sections/external.x create mode 100644 esp-hal-common/ld/sections/fixups/external_ram_dummy.x diff --git a/esp-hal-common/ld/esp32s3/esp32s3.x b/esp-hal-common/ld/esp32s3/esp32s3.x index 731d279cc3e..bae052ad0be 100644 --- a/esp-hal-common/ld/esp32s3/esp32s3.x +++ b/esp-hal-common/ld/esp32s3/esp32s3.x @@ -34,6 +34,7 @@ SECTIONS { INSERT BEFORE .data; INCLUDE "fixups/rodata_dummy.x" +INCLUDE "fixups/external_ram_dummy.x" /* End of ESP32S3 fixups */ /* Shared sections - ordering matters */ @@ -44,6 +45,7 @@ INCLUDE "rwdata.x" INCLUDE "rtc_fast.x" INCLUDE "rtc_slow.x" INCLUDE "stack.x" +INCLUDE "external.x" /* End of Shared sections */ EXTERN(DefaultHandler); diff --git a/esp-hal-common/ld/esp32s3/memory.x b/esp-hal-common/ld/esp32s3/memory.x index 3b493fbcfee..1d2d3f96ef9 100644 --- a/esp-hal-common/ld/esp32s3/memory.x +++ b/esp-hal-common/ld/esp32s3/memory.x @@ -36,8 +36,11 @@ MEMORY /* RTC fast memory (executable). Persists over deep sleep. Only for core 0 (PRO_CPU) */ - rtc_fast_seg(RWX) : ORIGIN = 0x600fe000, len = 8k + rtc_fast_seg(RWX) : ORIGIN = 0x600fe000, len = 8k /* RTC slow memory (data accessible). Persists over deep sleep. */ rtc_slow_seg(RW) : ORIGIN = 0x50000000, len = 8k + + /* external memory, including data and text */ + psram_seg(RWX) : ORIGIN = 0x3C000020, len = 32M - 0x20 } diff --git a/esp-hal-common/ld/sections/external.x b/esp-hal-common/ld/sections/external.x new file mode 100644 index 00000000000..0ae2ac784ee --- /dev/null +++ b/esp-hal-common/ld/sections/external.x @@ -0,0 +1,36 @@ + + +SECTIONS { + .external.data : + { + _external_data_start = ABSOLUTE(.); + _external_no_heap_start = ABSOLUTE(.); + . = ALIGN(4); + *(.external.data .external.data.*) + _external_data_end = ABSOLUTE(.); + } > psram_seg AT > RODATA + + .external.bss (NOLOAD) : + { + _external_bss_start = ABSOLUTE(.); + . = ALIGN(4); + *(.external.bss .external.bss.*) + _external_bss_end = ABSOLUTE(.); + } > psram_seg + + .external.noinit (NOLOAD) : + { + . = ALIGN(4); + *(.external.noinit .external.noinit.*) + } > psram_seg + + /* must be last segment using psram_seg */ + .external_heap_start (NOLOAD) : + { + . = ALIGN (4); + _external_heap_start = ABSOLUTE(.); + } > psram_seg +} + +_external_ram_start = ABSOLUTE(ORIGIN(psram_seg)); +_external_ram_end = ABSOLUTE(ORIGIN(psram_seg)+LENGTH(psram_seg)); \ No newline at end of file diff --git a/esp-hal-common/ld/sections/fixups/external_ram_dummy.x b/esp-hal-common/ld/sections/fixups/external_ram_dummy.x new file mode 100644 index 00000000000..d87edf8ccc1 --- /dev/null +++ b/esp-hal-common/ld/sections/fixups/external_ram_dummy.x @@ -0,0 +1,17 @@ +/* + * This section is required to skip flash rodata sections, because `psram_seg` + * and `drom_seg` are on the same bus + */ + +SECTIONS { + .ext_ram_dummy (NOLOAD) : + { + . = ORIGIN(psram_seg) + (_rodata_reserved_end - _rodata_dummy_start); + + /* Prepare the alignment of the section above + */ + + . = ALIGN(0x10000); + } > psram_seg +} +INSERT BEFORE .external.data; \ No newline at end of file diff --git a/esp-hal-common/ld/sections/fixups/rodata_dummy.x b/esp-hal-common/ld/sections/fixups/rodata_dummy.x index 4b2573e9d6b..78b51c845dc 100644 --- a/esp-hal-common/ld/sections/fixups/rodata_dummy.x +++ b/esp-hal-common/ld/sections/fixups/rodata_dummy.x @@ -8,6 +8,7 @@ SECTIONS { * Thus, it must have its alignment and (at least) its size. */ + _rodata_dummy_start = ABSOLUTE(.); /* Start at the same alignment constraint than .flash.text */ . = ALIGN(ALIGNOF(.text)); diff --git a/esp-hal-common/ld/sections/rodata.x b/esp-hal-common/ld/sections/rodata.x index 4d1832a864e..272902183ba 100644 --- a/esp-hal-common/ld/sections/rodata.x +++ b/esp-hal-common/ld/sections/rodata.x @@ -15,6 +15,7 @@ SECTIONS { { . = ALIGN(4); *( .rodata_wlog_*.* ) + _rodata_reserved_end = ABSOLUTE(.); . = ALIGN(4); } > RODATA } \ No newline at end of file diff --git a/esp-hal-common/src/soc/esp32s3/psram.rs b/esp-hal-common/src/soc/esp32s3/psram.rs index 36eee7a9078..b716c4be66f 100644 --- a/esp-hal-common/src/soc/esp32s3/psram.rs +++ b/esp-hal-common/src/soc/esp32s3/psram.rs @@ -22,6 +22,17 @@ pub fn psram_vaddr_start() -> usize { unsafe { PSRAM_VADDR as usize } } +pub fn psram_vaddr_heap_start() -> usize { + extern "C" { + static mut _external_heap_start: u32; + } + unsafe { (&_external_heap_start as *const u32) as usize } +} + +pub fn psram_heap_size() -> usize { + PSRAM_BYTES - (psram_vaddr_heap_start() - psram_vaddr_start()) +} + cfg_if::cfg_if! { if #[cfg(feature = "psram-2m")] { const PSRAM_SIZE: u32 = 2; @@ -57,6 +68,8 @@ pub const PSRAM_BYTES: usize = PSRAM_SIZE as usize * 1024 * 1024; feature = "opsram-16m" ))] pub fn init_psram(_peripheral: impl crate::peripheral::Peripheral

) { + use procmacros::ram; + const CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE: u32 = 0x4000; const CONFIG_ESP32S3_ICACHE_ASSOCIATED_WAYS: u8 = 8; const CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_SIZE: u8 = 32; @@ -67,6 +80,11 @@ pub fn init_psram(_peripheral: impl crate::peripheral::Peripheral

i32; } unsafe { - const MMU_PAGE_SIZE: u32 = 0x10000; - const ICACHE_MMU_SIZE: usize = 0x800; - const FLASH_MMU_TABLE_SIZE: usize = ICACHE_MMU_SIZE / core::mem::size_of::(); - const MMU_INVALID: u32 = 1 << 14; - const DR_REG_MMU_TABLE: u32 = 0x600C5000; - // calculate the PSRAM start address to map - let mut start = PSRAM_VADDR; - let mmu_table_ptr = DR_REG_MMU_TABLE as *const u32; - for i in 0..FLASH_MMU_TABLE_SIZE { - if mmu_table_ptr.add(i).read_volatile() != MMU_INVALID { - start += MMU_PAGE_SIZE; - } else { - break; - } - } - debug!("PSRAM start address = {:x}", start); - PSRAM_VADDR = start; + PSRAM_VADDR = (&_external_no_heap_start as *const u32) as u32; + debug!("PSRAM start address = {:x}", PSRAM_VADDR); // Configure the mode of instruction cache : cache size, cache line size. rom_config_instruction_cache_mode( @@ -161,6 +164,19 @@ pub fn init_psram(_peripheral: impl crate::peripheral::Peripheral

bool; + } + unsafe { + if __zero_bss() { + crate::xtensa_lx_rt::zero_bss(&mut _external_bss_start, &mut _external_bss_end); + } + } + } } #[cfg(any(feature = "psram-2m", feature = "psram-4m", feature = "psram-8m"))]