diff --git a/esp-hal/src/lib.rs b/esp-hal/src/lib.rs index 3019f6bd9..133394834 100644 --- a/esp-hal/src/lib.rs +++ b/esp-hal/src/lib.rs @@ -532,36 +532,6 @@ pub mod __macro_implementation { pub use xtensa_lx_rt::entry as __entry; } -#[cfg(riscv)] -#[unsafe(export_name = "hal_main")] -fn hal_main(a0: usize, a1: usize, a2: usize) -> ! { - unsafe extern "Rust" { - // This symbol will be provided by the user via `#[entry]` - fn main(a0: usize, a1: usize, a2: usize) -> !; - } - - unsafe extern "C" { - static mut __stack_chk_guard: u32; - } - - unsafe { - let stack_chk_guard = core::ptr::addr_of_mut!(__stack_chk_guard); - // we _should_ use a random value but we don't have a good source for random - // numbers here - stack_chk_guard.write_volatile(esp_config::esp_config_int!( - u32, - "ESP_HAL_CONFIG_STACK_GUARD_VALUE" - )); - - main(a0, a1, a2); - } -} - -#[unsafe(export_name = "__stack_chk_fail")] -unsafe extern "C" fn stack_chk_fail() { - panic!("Stack corruption detected"); -} - #[cfg(feature = "unstable")] use crate::config::{WatchdogConfig, WatchdogStatus}; use crate::{ diff --git a/esp-hal/src/soc/esp32/mod.rs b/esp-hal/src/soc/esp32/mod.rs index 2eefada42..6f7e5642b 100644 --- a/esp-hal/src/soc/esp32/mod.rs +++ b/esp-hal/src/soc/esp32/mod.rs @@ -5,10 +5,6 @@ //! The `SOC` module provides access, functions and structures that are useful //! for interacting with various system-related peripherals on `ESP32` chip. -use core::ptr::addr_of_mut; - -use crate::rtc_cntl::SocResetReason; - crate::unstable_module! { pub mod efuse; #[cfg(feature = "psram")] @@ -32,90 +28,6 @@ pub(crate) mod constants { pub const REF_TICK: Rate = Rate::from_mhz(1); } -/// Function initializes ESP32 specific memories (RTC slow and fast) and -/// then calls original Reset function -/// -/// ENTRY point is defined in memory.x -/// *Note: the pre_init function is called in the original reset handler -/// after the initializations done in this function* -#[doc(hidden)] -#[unsafe(no_mangle)] -pub unsafe extern "C" fn ESP32Reset() -> ! { - // These symbols come from `memory.x` - unsafe extern "C" { - static mut _rtc_fast_bss_start: u32; - static mut _rtc_fast_bss_end: u32; - static mut _rtc_fast_persistent_start: u32; - static mut _rtc_fast_persistent_end: u32; - - static mut _rtc_slow_bss_start: u32; - static mut _rtc_slow_bss_end: u32; - static mut _rtc_slow_persistent_start: u32; - static mut _rtc_slow_persistent_end: u32; - - static mut _stack_start_cpu0: u32; - - static mut __stack_chk_guard: u32; - } - - // set stack pointer to end of memory: no need to retain stack up to this point - unsafe { - xtensa_lx::set_stack_pointer(addr_of_mut!(_stack_start_cpu0)); - } - - // copying data from flash to various data segments is done by the bootloader - // initialization to zero needs to be done by the application - - // Initialize RTC RAM - unsafe { - xtensa_lx_rt::zero_bss( - addr_of_mut!(_rtc_fast_bss_start), - addr_of_mut!(_rtc_fast_bss_end), - ); - xtensa_lx_rt::zero_bss( - addr_of_mut!(_rtc_slow_bss_start), - addr_of_mut!(_rtc_slow_bss_end), - ); - } - if matches!( - crate::system::reset_reason(), - None | Some(SocResetReason::ChipPowerOn) - ) { - unsafe { - xtensa_lx_rt::zero_bss( - addr_of_mut!(_rtc_fast_persistent_start), - addr_of_mut!(_rtc_fast_persistent_end), - ); - xtensa_lx_rt::zero_bss( - addr_of_mut!(_rtc_slow_persistent_start), - addr_of_mut!(_rtc_slow_persistent_end), - ); - } - } - - let stack_chk_guard = core::ptr::addr_of_mut!(__stack_chk_guard); - // we _should_ use a random value but we don't have a good source for random - // numbers here - unsafe { - stack_chk_guard.write_volatile(esp_config::esp_config_int!( - u32, - "ESP_HAL_CONFIG_STACK_GUARD_VALUE" - )); - } - - crate::interrupt::setup_interrupts(); - - // continue with default reset handler - unsafe { xtensa_lx_rt::Reset() } -} - -/// The ESP32 has a first stage bootloader that handles loading program data -/// into the right place therefore we skip loading it again. -#[doc(hidden)] -#[unsafe(no_mangle)] -#[rustfmt::skip] -pub extern "Rust" fn __init_data() -> bool { - false -} +pub(crate) unsafe fn configure_cpu_caches() {} pub(crate) fn pre_init() {} diff --git a/esp-hal/src/soc/esp32s2/mod.rs b/esp-hal/src/soc/esp32s2/mod.rs index c3bc1b322..d5ea24078 100644 --- a/esp-hal/src/soc/esp32s2/mod.rs +++ b/esp-hal/src/soc/esp32s2/mod.rs @@ -9,10 +9,6 @@ //! * I2S_SCLK: 160_000_000 - I2S clock frequency //! * I2S_DEFAULT_CLK_SRC: 2 - I2S clock source -use core::ptr::addr_of_mut; - -use crate::rtc_cntl::SocResetReason; - crate::unstable_module! { pub mod efuse; #[cfg(feature = "psram")] @@ -36,92 +32,6 @@ pub(crate) mod constants { pub const REF_TICK: Rate = Rate::from_mhz(1); } -/// Function initializes ESP32 specific memories (RTC slow and fast) and -/// then calls original Reset function -/// -/// ENTRY point is defined in memory.x -/// *Note: the pre_init function is called in the original reset handler -/// after the initializations done in this function* -#[doc(hidden)] -#[unsafe(no_mangle)] -pub unsafe extern "C" fn ESP32Reset() -> ! { - // These symbols come from `memory.x` - unsafe extern "C" { - static mut _rtc_fast_bss_start: u32; - static mut _rtc_fast_bss_end: u32; - static mut _rtc_fast_persistent_start: u32; - static mut _rtc_fast_persistent_end: u32; - - static mut _rtc_slow_bss_start: u32; - static mut _rtc_slow_bss_end: u32; - static mut _rtc_slow_persistent_start: u32; - static mut _rtc_slow_persistent_end: u32; - - static mut _stack_start_cpu0: u32; - - static mut __stack_chk_guard: u32; - } - - // set stack pointer to end of memory: no need to retain stack up to this point - unsafe { - xtensa_lx::set_stack_pointer(addr_of_mut!(_stack_start_cpu0)); - } - - // copying data from flash to various data segments is done by the bootloader - // initialization to zero needs to be done by the application - - // Initialize RTC RAM - unsafe { - xtensa_lx_rt::zero_bss( - addr_of_mut!(_rtc_fast_bss_start), - addr_of_mut!(_rtc_fast_bss_end), - ); - xtensa_lx_rt::zero_bss( - addr_of_mut!(_rtc_slow_bss_start), - addr_of_mut!(_rtc_slow_bss_end), - ); - } - if matches!( - crate::system::reset_reason(), - None | Some(SocResetReason::ChipPowerOn) - ) { - unsafe { - xtensa_lx_rt::zero_bss( - addr_of_mut!(_rtc_fast_persistent_start), - addr_of_mut!(_rtc_fast_persistent_end), - ); - xtensa_lx_rt::zero_bss( - addr_of_mut!(_rtc_slow_persistent_start), - addr_of_mut!(_rtc_slow_persistent_end), - ); - } - } - - let stack_chk_guard = core::ptr::addr_of_mut!(__stack_chk_guard); - // we _should_ use a random value but we don't have a good source for random - // numbers here - unsafe { - stack_chk_guard.write_volatile(esp_config::esp_config_int!( - u32, - "ESP_HAL_CONFIG_STACK_GUARD_VALUE" - )); - } - - crate::interrupt::setup_interrupts(); - - // continue with default reset handler - unsafe { xtensa_lx_rt::Reset() } -} - -/// The ESP32 has a first stage bootloader that handles loading program data -/// into the right place therefore we skip loading it again. -#[doc(hidden)] -#[unsafe(no_mangle)] -#[rustfmt::skip] -pub extern "Rust" fn __init_data() -> bool { - false -} - /// Write back a specific range of data in the cache. #[doc(hidden)] #[unsafe(link_section = ".rwtext")] @@ -156,4 +66,6 @@ pub unsafe fn cache_get_dcache_line_size() -> u32 { unsafe { Cache_Get_DCache_Line_Size() } } +pub(crate) unsafe fn configure_cpu_caches() {} + pub(crate) fn pre_init() {} diff --git a/esp-hal/src/soc/esp32s3/mod.rs b/esp-hal/src/soc/esp32s3/mod.rs index fa854b849..1d85c1202 100644 --- a/esp-hal/src/soc/esp32s3/mod.rs +++ b/esp-hal/src/soc/esp32s3/mod.rs @@ -9,10 +9,6 @@ //! * I2S_SCLK: 160_000_000 - I2S clock frequency //! * I2S_DEFAULT_CLK_SRC: 2 - I2S clock source -use core::ptr::addr_of_mut; - -use crate::rtc_cntl::SocResetReason; - crate::unstable_module! { pub mod efuse; #[cfg(feature = "psram")] @@ -43,9 +39,8 @@ pub(crate) mod constants { pub const RC_FAST_CLK: Rate = Rate::from_khz(17500); } -#[doc(hidden)] #[unsafe(link_section = ".rwtext")] -pub unsafe fn configure_cpu_caches() { +pub(crate) unsafe fn configure_cpu_caches() { // this is just the bare minimum we need to run code from flash // consider implementing more advanced configurations // see https://github.com/apache/incubator-nuttx/blob/master/arch/xtensa/src/esp32s3/esp32s3_start.c @@ -73,97 +68,6 @@ pub unsafe fn configure_cpu_caches() { } } -/// Function initializes ESP32S3 specific memories (RTC slow and fast) and -/// then calls original Reset function -/// -/// ENTRY point is defined in memory.x -/// *Note: the pre_init function is called in the original reset handler -/// after the initializations done in this function* -#[doc(hidden)] -#[unsafe(no_mangle)] -#[unsafe(link_section = ".rwtext")] -pub unsafe extern "C" fn ESP32Reset() -> ! { - unsafe { - configure_cpu_caches(); - } - - // These symbols come from `memory.x` - unsafe extern "C" { - static mut _rtc_fast_bss_start: u32; - static mut _rtc_fast_bss_end: u32; - static mut _rtc_fast_persistent_start: u32; - static mut _rtc_fast_persistent_end: u32; - - static mut _rtc_slow_bss_start: u32; - static mut _rtc_slow_bss_end: u32; - static mut _rtc_slow_persistent_start: u32; - static mut _rtc_slow_persistent_end: u32; - - static mut _stack_start_cpu0: u32; - - static mut __stack_chk_guard: u32; - } - - // set stack pointer to end of memory: no need to retain stack up to this point - unsafe { - xtensa_lx::set_stack_pointer(addr_of_mut!(_stack_start_cpu0)); - } - - // copying data from flash to various data segments is done by the bootloader - // initialization to zero needs to be done by the application - - // Initialize RTC RAM - unsafe { - xtensa_lx_rt::zero_bss( - addr_of_mut!(_rtc_fast_bss_start), - addr_of_mut!(_rtc_fast_bss_end), - ); - xtensa_lx_rt::zero_bss( - addr_of_mut!(_rtc_slow_bss_start), - addr_of_mut!(_rtc_slow_bss_end), - ); - } - if matches!( - crate::system::reset_reason(), - None | Some(SocResetReason::ChipPowerOn) - ) { - unsafe { - xtensa_lx_rt::zero_bss( - addr_of_mut!(_rtc_fast_persistent_start), - addr_of_mut!(_rtc_fast_persistent_end), - ); - xtensa_lx_rt::zero_bss( - addr_of_mut!(_rtc_slow_persistent_start), - addr_of_mut!(_rtc_slow_persistent_end), - ); - } - } - - let stack_chk_guard = core::ptr::addr_of_mut!(__stack_chk_guard); - // we _should_ use a random value but we don't have a good source for random - // numbers here - unsafe { - stack_chk_guard.write_volatile(esp_config::esp_config_int!( - u32, - "ESP_HAL_CONFIG_STACK_GUARD_VALUE" - )); - } - - crate::interrupt::setup_interrupts(); - - // continue with default reset handler - unsafe { xtensa_lx_rt::Reset() } -} - -/// The ESP32 has a first stage bootloader that handles loading program data -/// into the right place therefore we skip loading it again. -#[doc(hidden)] -#[unsafe(no_mangle)] -#[rustfmt::skip] -pub extern "Rust" fn __init_data() -> bool { - false -} - /// Write back a specific range of data in the cache. #[doc(hidden)] #[unsafe(link_section = ".rwtext")] diff --git a/esp-hal/src/soc/mod.rs b/esp-hal/src/soc/mod.rs index d656b08a4..25e310399 100644 --- a/esp-hal/src/soc/mod.rs +++ b/esp-hal/src/soc/mod.rs @@ -141,3 +141,116 @@ fn slice_in_range(slice: &[T], range: Range) -> bool { pub(crate) fn addr_in_range(addr: usize, range: Range) -> bool { range.contains(&addr) } + +#[cfg(riscv)] +#[unsafe(export_name = "hal_main")] +fn hal_main(a0: usize, a1: usize, a2: usize) -> ! { + unsafe extern "Rust" { + // This symbol will be provided by the user via `#[entry]` + fn main(a0: usize, a1: usize, a2: usize) -> !; + } + + setup_stack_guard(); + + unsafe { + main(a0, a1, a2); + } +} + +#[cfg(xtensa)] +#[unsafe(no_mangle)] +#[cfg_attr(esp32s3, unsafe(link_section = ".rwtext"))] +unsafe extern "C" fn ESP32Reset() -> ! { + unsafe { + configure_cpu_caches(); + } + + /// The ESP32 has a first stage bootloader that handles loading program data + /// into the right place therefore we skip loading it again. This function + /// is called by xtensa-lx-rt in Reset. + #[doc(hidden)] + #[unsafe(no_mangle)] + pub extern "Rust" fn __init_data() -> bool { + false + } + + // These symbols come from `memory.x` + unsafe extern "C" { + static mut _rtc_fast_bss_start: u32; + static mut _rtc_fast_bss_end: u32; + static mut _rtc_fast_persistent_start: u32; + static mut _rtc_fast_persistent_end: u32; + + static mut _rtc_slow_bss_start: u32; + static mut _rtc_slow_bss_end: u32; + static mut _rtc_slow_persistent_start: u32; + static mut _rtc_slow_persistent_end: u32; + + static mut _stack_start_cpu0: u32; + + static mut __stack_chk_guard: u32; + } + + // set stack pointer to end of memory: no need to retain stack up to this point + unsafe { + xtensa_lx::set_stack_pointer(core::ptr::addr_of_mut!(_stack_start_cpu0)); + } + + // copying data from flash to various data segments is done by the bootloader + // initialization to zero needs to be done by the application + + // Initialize RTC RAM + unsafe { + xtensa_lx_rt::zero_bss( + core::ptr::addr_of_mut!(_rtc_fast_bss_start), + core::ptr::addr_of_mut!(_rtc_fast_bss_end), + ); + xtensa_lx_rt::zero_bss( + core::ptr::addr_of_mut!(_rtc_slow_bss_start), + core::ptr::addr_of_mut!(_rtc_slow_bss_end), + ); + } + if matches!( + crate::system::reset_reason(), + None | Some(crate::rtc_cntl::SocResetReason::ChipPowerOn) + ) { + unsafe { + xtensa_lx_rt::zero_bss( + core::ptr::addr_of_mut!(_rtc_fast_persistent_start), + core::ptr::addr_of_mut!(_rtc_fast_persistent_end), + ); + xtensa_lx_rt::zero_bss( + core::ptr::addr_of_mut!(_rtc_slow_persistent_start), + core::ptr::addr_of_mut!(_rtc_slow_persistent_end), + ); + } + } + + setup_stack_guard(); + + crate::interrupt::setup_interrupts(); + + // continue with default reset handler + unsafe { xtensa_lx_rt::Reset() } +} + +#[unsafe(export_name = "__stack_chk_fail")] +unsafe extern "C" fn stack_chk_fail() { + panic!("Stack corruption detected"); +} + +fn setup_stack_guard() { + unsafe extern "C" { + static mut __stack_chk_guard: u32; + } + + unsafe { + let stack_chk_guard = core::ptr::addr_of_mut!(__stack_chk_guard); + // we _should_ use a random value but we don't have a good source for random + // numbers here + stack_chk_guard.write_volatile(esp_config::esp_config_int!( + u32, + "ESP_HAL_CONFIG_STACK_GUARD_VALUE" + )); + } +}