#[cfg(feature = "unstable")]
use crate::system::multi_core;
use crate::{
peripherals::{HP_SYS, HP_SYS_CLKRST, LP_AON_CLKRST, PMU},
system::Cpu,
};
pub(crate) unsafe fn internal_park_core(core: Cpu, park: bool) {
let code: u8 = if park { 0x86 } else { 0xFF };
PMU::regs().cpu_sw_stall().modify(|_, w| unsafe {
match core {
Cpu::ProCpu => w.hpcore0_sw_stall_code().bits(code),
Cpu::AppCpu => w.hpcore1_sw_stall_code().bits(code),
}
});
if !park {
let st = HP_SYS::regs().cpu_corestalled_st();
match core {
Cpu::ProCpu => while st.read().reg_core0_corestalled_st().bit_is_set() {},
Cpu::AppCpu => while st.read().reg_core1_corestalled_st().bit_is_set() {},
}
}
}
#[instability::unstable]
pub fn is_running(core: Cpu) -> bool {
let stall_reg = PMU::regs().cpu_sw_stall().read();
let code = match core {
Cpu::ProCpu => stall_reg.hpcore0_sw_stall_code().bits(),
Cpu::AppCpu => stall_reg.hpcore1_sw_stall_code().bits(),
};
code != 0x86
}
pub(crate) fn pre_system_reset() {
LP_AON_CLKRST::regs()
.lp_aonclkrst_hpcpu_reset_ctrl0()
.modify(|_, w| w.lp_aonclkrst_hpcore1_sw_reset().set_bit());
unsafe { internal_park_core(Cpu::AppCpu, true) };
crate::rom::ets_set_appcpu_boot_addr(0);
}
pub(crate) fn disable_core1() {
HP_SYS_CLKRST::regs()
.soc_clk_ctrl0()
.modify(|_, w| w.core1_cpu_clk_en().clear_bit());
HP_SYS_CLKRST::regs()
.hp_rst_en0()
.modify(|_, w| w.rst_en_core1_global().set_bit());
}
#[cfg(feature = "unstable")]
pub(crate) fn start_core1(entry_point: *const u32) {
HP_SYS_CLKRST::regs()
.soc_clk_ctrl0()
.modify(|_, w| w.core1_cpu_clk_en().set_bit());
HP_SYS_CLKRST::regs()
.hp_rst_en0()
.modify(|_, w| w.rst_en_core1_global().clear_bit());
crate::rom::ets_set_appcpu_boot_addr(entry_point as u32);
}
#[unsafe(naked)]
#[cfg(feature = "unstable")]
pub(crate) extern "C" fn start_core1_init<F>() -> !
where
F: FnOnce(),
{
core::arch::naked_asm!(
".option push",
".option norelax",
"la gp, __global_pointer$",
".option pop",
"li t0, 0x6000",
"csrrs x0, mstatus, t0",
"fscsr x0",
"la t0, {stack_top}",
"lw sp, 0(t0)",
"j {init}",
stack_top = sym multi_core::APP_CORE_STACK_TOP,
init = sym start_core1_init_impl::<F>,
)
}
#[cfg(feature = "unstable")]
fn start_core1_init_impl<F>() -> !
where
F: FnOnce(),
{
crate::soc::enable_branch_predictor();
crate::rom::ets_set_appcpu_boot_addr(0);
unsafe {
#[cfg(all(feature = "rt", stack_guard_monitoring))]
{
let guard =
multi_core::APP_CORE_STACK_GUARD.load(core::sync::atomic::Ordering::Acquire);
guard.write_volatile(esp_config::esp_config_int!(
u32,
"ESP_HAL_CONFIG_STACK_GUARD_VALUE"
));
crate::debugger::set_stack_watchpoint(guard as usize);
}
crate::interrupt::init_vectoring();
}
unsafe { multi_core::CpuControl::start_core1_run::<F>() }
}