Remove static muts from multicore control code (#4143)

This commit is contained in:
Dániel Buga 2025-09-19 09:47:32 +02:00 committed by GitHub
parent f0d029b29d
commit 5e938322f4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 34 additions and 39 deletions

View File

@ -8,6 +8,7 @@
use core::{ use core::{
marker::PhantomData, marker::PhantomData,
mem::{ManuallyDrop, MaybeUninit}, mem::{ManuallyDrop, MaybeUninit},
sync::atomic::{AtomicPtr, Ordering},
}; };
use crate::{ use crate::{
@ -74,8 +75,8 @@ impl<const SIZE: usize> Stack<SIZE> {
// Pointer to the closure that will be executed on the second core. The closure // Pointer to the closure that will be executed on the second core. The closure
// is copied to the core's stack. // is copied to the core's stack.
static mut START_CORE1_FUNCTION: Option<*mut ()> = None; static START_CORE1_FUNCTION: AtomicPtr<()> = AtomicPtr::new(core::ptr::null_mut());
static mut APP_CORE_STACK_TOP: Option<*mut u32> = None; static APP_CORE_STACK_TOP: AtomicPtr<u32> = AtomicPtr::new(core::ptr::null_mut());
/// Will park the APP (second) core when dropped /// Will park the APP (second) core when dropped
#[must_use = "Dropping this guard will park the APP core"] #[must_use = "Dropping this guard will park the APP core"]
@ -283,13 +284,10 @@ impl<'d> CpuControl<'d> {
static mut _init_start: u32; static mut _init_start: u32;
} }
// move vec table // set vector table and stack pointer
let base = core::ptr::addr_of!(_init_start);
unsafe { unsafe {
core::arch::asm!("wsr.vecbase {0}", in(reg) base, options(nostack)); core::arch::asm!("wsr.vecbase {0}", in(reg) &raw const _init_start, options(nostack));
// switch to new stack xtensa_lx::set_stack_pointer(APP_CORE_STACK_TOP.load(Ordering::Acquire));
xtensa_lx::set_stack_pointer(unwrap!(APP_CORE_STACK_TOP));
} }
// Trampoline to run from the new stack. // Trampoline to run from the new stack.
@ -305,16 +303,15 @@ impl<'d> CpuControl<'d> {
where where
F: FnOnce(), F: FnOnce(),
{ {
#[allow(static_mut_refs)] // FIXME let entry = START_CORE1_FUNCTION.load(Ordering::Acquire);
match unsafe { START_CORE1_FUNCTION.take() } { debug_assert!(!entry.is_null());
Some(entry) => unsafe {
let entry = ManuallyDrop::take(&mut *entry.cast::<ManuallyDrop<F>>()); unsafe {
entry(); let entry = ManuallyDrop::take(&mut *entry.cast::<ManuallyDrop<F>>());
loop { entry();
internal_park_core(Cpu::current(), true); loop {
} internal_park_core(Cpu::current(), true);
}, }
None => panic!("No start function set"),
} }
} }
@ -363,8 +360,8 @@ impl<'d> CpuControl<'d> {
entry_dst.write(entry); entry_dst.write(entry);
let entry_fn = entry_dst.cast::<()>(); let entry_fn = entry_dst.cast::<()>();
START_CORE1_FUNCTION = Some(entry_fn); START_CORE1_FUNCTION.store(entry_fn, Ordering::Release);
APP_CORE_STACK_TOP = Some(stack.top()); APP_CORE_STACK_TOP.store(stack.top(), Ordering::Release);
} }
dport_control.appcpu_ctrl_d().write(|w| unsafe { dport_control.appcpu_ctrl_d().write(|w| unsafe {

View File

@ -9,6 +9,7 @@
use core::{ use core::{
marker::PhantomData, marker::PhantomData,
mem::{ManuallyDrop, MaybeUninit}, mem::{ManuallyDrop, MaybeUninit},
sync::atomic::{AtomicPtr, Ordering},
}; };
use crate::{ use crate::{
@ -75,8 +76,8 @@ impl<const SIZE: usize> Stack<SIZE> {
// Pointer to the closure that will be executed on the second core. The closure // Pointer to the closure that will be executed on the second core. The closure
// is copied to the core's stack. // is copied to the core's stack.
static mut START_CORE1_FUNCTION: Option<*mut ()> = None; static START_CORE1_FUNCTION: AtomicPtr<()> = AtomicPtr::new(core::ptr::null_mut());
static mut APP_CORE_STACK_TOP: Option<*mut u32> = None; static APP_CORE_STACK_TOP: AtomicPtr<u32> = AtomicPtr::new(core::ptr::null_mut());
/// Will park the APP (second) core when dropped /// Will park the APP (second) core when dropped
#[must_use = "Dropping this guard will park the APP core"] #[must_use = "Dropping this guard will park the APP core"]
@ -222,12 +223,10 @@ impl<'d> CpuControl<'d> {
static mut _init_start: u32; static mut _init_start: u32;
} }
// move vec table // set vector table and stack pointer
let base = core::ptr::addr_of!(_init_start);
unsafe { unsafe {
core::arch::asm!("wsr.vecbase {0}", in(reg) base, options(nostack)); core::arch::asm!("wsr.vecbase {0}", in(reg) &raw const _init_start, options(nostack));
// switch to new stack xtensa_lx::set_stack_pointer(APP_CORE_STACK_TOP.load(Ordering::Acquire));
xtensa_lx::set_stack_pointer(unwrap!(APP_CORE_STACK_TOP));
} }
// Trampoline to run from the new stack. // Trampoline to run from the new stack.
@ -243,16 +242,15 @@ impl<'d> CpuControl<'d> {
where where
F: FnOnce(), F: FnOnce(),
{ {
#[allow(static_mut_refs)] // FIXME let entry = START_CORE1_FUNCTION.load(Ordering::Acquire);
match unsafe { START_CORE1_FUNCTION.take() } { debug_assert!(!entry.is_null());
Some(entry) => unsafe {
let entry = ManuallyDrop::take(&mut *entry.cast::<ManuallyDrop<F>>()); unsafe {
entry(); let entry = ManuallyDrop::take(&mut *entry.cast::<ManuallyDrop<F>>());
loop { entry();
internal_park_core(Cpu::current(), true); loop {
} internal_park_core(Cpu::current(), true);
}, }
None => panic!("No start function set"),
} }
} }
@ -298,8 +296,8 @@ impl<'d> CpuControl<'d> {
entry_dst.write(entry); entry_dst.write(entry);
let entry_fn = entry_dst.cast::<()>(); let entry_fn = entry_dst.cast::<()>();
START_CORE1_FUNCTION = Some(entry_fn); START_CORE1_FUNCTION.store(entry_fn, Ordering::Release);
APP_CORE_STACK_TOP = Some(stack.top()); APP_CORE_STACK_TOP.store(stack.top(), Ordering::Release);
} }
crate::rom::ets_set_appcpu_boot_addr(Self::start_core1_init::<F> as *const u32 as u32); crate::rom::ets_set_appcpu_boot_addr(Self::start_core1_init::<F> as *const u32 as u32);