Skip to content

Commit

Permalink
Add linker script for external ram for esp32s3
Browse files Browse the repository at this point in the history
  • Loading branch information
Volkalex28 committed Jan 17, 2024
1 parent bb58446 commit fca600f
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 18 deletions.
2 changes: 2 additions & 0 deletions esp-hal-common/ld/esp32s3/esp32s3.x
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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);
Expand Down
5 changes: 4 additions & 1 deletion esp-hal-common/ld/esp32s3/memory.x
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
36 changes: 36 additions & 0 deletions esp-hal-common/ld/sections/external.x
Original file line number Diff line number Diff line change
@@ -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));
17 changes: 17 additions & 0 deletions esp-hal-common/ld/sections/fixups/external_ram_dummy.x
Original file line number Diff line number Diff line change
@@ -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;
1 change: 1 addition & 0 deletions esp-hal-common/ld/sections/fixups/rodata_dummy.x
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
1 change: 1 addition & 0 deletions esp-hal-common/ld/sections/rodata.x
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ SECTIONS {
{
. = ALIGN(4);
*( .rodata_wlog_*.* )
_rodata_reserved_end = ABSOLUTE(.);
. = ALIGN(4);
} > RODATA
}
50 changes: 33 additions & 17 deletions esp-hal-common/src/soc/esp32s3/psram.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<P = crate::peripherals::PSRAM>) {
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;
Expand All @@ -67,6 +80,11 @@ pub fn init_psram(_peripheral: impl crate::peripheral::Peripheral<P = crate::per
const START_PAGE: u32 = 0;

extern "C" {
static mut _external_no_heap_start: u32;

static mut _external_bss_start: u32;
static mut _external_bss_end: u32;

fn rom_config_instruction_cache_mode(
cfg_cache_size: u32,
cfg_cache_ways: u8,
Expand Down Expand Up @@ -101,24 +119,9 @@ pub fn init_psram(_peripheral: impl crate::peripheral::Peripheral<P = crate::per
) -> 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::<u32>();
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(
Expand Down Expand Up @@ -161,6 +164,19 @@ pub fn init_psram(_peripheral: impl crate::peripheral::Peripheral<P = crate::per
}

utils::psram_init();
zero_bss();

#[ram]
fn zero_bss() {
extern "Rust" {
fn __zero_bss() -> 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"))]
Expand Down

0 comments on commit fca600f

Please sign in to comment.