esp_hal/soc/esp32s31/
cpu_control.rs1#[cfg(feature = "unstable")]
2use crate::system::multi_core;
3use crate::{
4 peripherals::{HP_SYS, HP_SYS_CLKRST, LP_AON_CLK_RST, PMU},
5 system::Cpu,
6};
7
8pub(crate) unsafe fn internal_park_core(core: Cpu, park: bool) {
9 let code: u8 = if park { 0x86 } else { 0xFF };
11 PMU::regs().cpu_stall_sw().modify(|_, w| unsafe {
12 match core {
13 Cpu::ProCpu => w.hpcore0_sw_stall_code().bits(code),
14 Cpu::AppCpu => w.hpcore1_sw_stall_code().bits(code),
15 }
16 });
17
18 if !park {
20 let status = HP_SYS::regs().cpu_corestalled_st();
21 match core {
22 Cpu::ProCpu => while status.read().reg_core0_corestalled_st().bit_is_set() {},
23 Cpu::AppCpu => while status.read().reg_core1_corestalled_st().bit_is_set() {},
24 }
25 }
26}
27
28#[instability::unstable]
29pub fn is_running(core: Cpu) -> bool {
30 let stall = PMU::regs().cpu_stall_sw().read();
31 let code = match core {
32 Cpu::ProCpu => stall.hpcore0_sw_stall_code().bits(),
33 Cpu::AppCpu => stall.hpcore1_sw_stall_code().bits(),
34 };
35 if code == 0x86 {
36 return false;
37 }
38
39 match core {
40 Cpu::ProCpu => true,
41 Cpu::AppCpu => {
42 let control = HP_SYS_CLKRST::regs().hpcore1_ctrl0().read();
43 control.core1_cpu_clk_en().bit_is_set() && control.core1_global_rst_en().bit_is_clear()
44 }
45 }
46}
47
48pub(crate) fn pre_system_reset() {
49 let other_core = match Cpu::current() {
52 Cpu::ProCpu => Cpu::AppCpu,
53 Cpu::AppCpu => Cpu::ProCpu,
54 };
55 match other_core {
56 Cpu::ProCpu => LP_AON_CLK_RST::regs()
57 .hpcore0_reset_ctrl()
58 .modify(|_, w| w.hpcore0_sw_reset().set_bit()),
59 Cpu::AppCpu => LP_AON_CLK_RST::regs()
60 .hpcore1_reset_ctrl()
61 .modify(|_, w| w.hpcore1_sw_reset().set_bit()),
62 };
63 unsafe { internal_park_core(other_core, true) };
64
65 crate::rom::ets_set_appcpu_boot_addr(0);
67}
68
69pub(crate) fn disable_core1() {
70 HP_SYS_CLKRST::regs().hpcore1_ctrl0().modify(|_, w| {
73 w.core1_cpu_clk_en()
74 .clear_bit()
75 .core1_clic_clk_en()
76 .clear_bit()
77 .core1_global_rst_en()
78 .set_bit()
79 });
80}
81
82#[cfg(feature = "unstable")]
83pub(crate) fn start_core1(entry_point: *const u32) {
84 HP_SYS_CLKRST::regs().hpcore1_ctrl0().modify(|_, w| {
86 w.core1_cpu_clk_en()
87 .set_bit()
88 .core1_clic_clk_en()
89 .set_bit()
90 .core1_global_rst_en()
91 .clear_bit()
92 });
93
94 crate::rom::ets_set_appcpu_boot_addr(entry_point as u32);
96}
97
98#[unsafe(naked)]
103#[cfg(feature = "unstable")]
104pub(crate) extern "C" fn start_core1_init<F>() -> !
105where
106 F: FnOnce(),
107{
108 core::arch::naked_asm!(
109 ".option push",
110 ".option norelax",
111 "la gp, __global_pointer$",
112 ".option pop",
113 "li t0, 0x2000",
117 "csrs mstatus, t0",
118 "li t0, 1",
119 "csrw fcsr, t0",
120 "li t0, 0x2000",
121 "csrc mstatus, t0",
122 "la t0, {stack_top}",
123 "lw sp, 0(t0)",
124 "j {init}",
125 stack_top = sym multi_core::APP_CORE_STACK_TOP,
126 init = sym start_core1_init_impl::<F>,
127 )
128}
129
130#[cfg(feature = "unstable")]
131fn start_core1_init_impl<F>() -> !
132where
133 F: FnOnce(),
134{
135 crate::soc::enable_branch_predictor();
136 crate::rom::ets_set_appcpu_boot_addr(0);
137
138 unsafe {
139 #[cfg(all(feature = "rt", stack_guard_monitoring))]
140 {
141 let guard =
142 multi_core::APP_CORE_STACK_GUARD.load(core::sync::atomic::Ordering::Acquire);
143 guard.write_volatile(esp_config::esp_config_int!(
144 u32,
145 "ESP_HAL_CONFIG_STACK_GUARD_VALUE"
146 ));
147 crate::debugger::set_stack_watchpoint(guard as usize);
148 }
149 crate::interrupt::init_vectoring();
150 }
151
152 unsafe { multi_core::CpuControl::start_core1_run::<F>() }
153}