Deduplicate ESP32Reset (#3651)

This commit is contained in:
Dániel Buga 2025-06-17 18:43:39 +02:00 committed by GitHub
parent 0f343a26e8
commit 6e74add2a0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 117 additions and 306 deletions

View File

@ -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::{

View File

@ -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() {}

View File

@ -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() {}

View File

@ -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")]

View File

@ -141,3 +141,116 @@ fn slice_in_range<T>(slice: &[T], range: Range<usize>) -> bool {
pub(crate) fn addr_in_range(addr: usize, range: Range<usize>) -> 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"
));
}
}