axruntime/
mp.rs

1use core::sync::atomic::{AtomicUsize, Ordering};
2
3use axconfig::{SMP, TASK_STACK_SIZE};
4use axhal::mem::{VirtAddr, virt_to_phys};
5
6#[unsafe(link_section = ".bss.stack")]
7static mut SECONDARY_BOOT_STACK: [[u8; TASK_STACK_SIZE]; SMP - 1] = [[0; TASK_STACK_SIZE]; SMP - 1];
8
9static ENTERED_CPUS: AtomicUsize = AtomicUsize::new(1);
10
11#[allow(clippy::absurd_extreme_comparisons)]
12pub fn start_secondary_cpus(primary_cpu_id: usize) {
13    let mut logic_cpu_id = 0;
14    for i in 0..SMP {
15        if i != primary_cpu_id && logic_cpu_id < SMP - 1 {
16            let stack_top = virt_to_phys(VirtAddr::from(unsafe {
17                SECONDARY_BOOT_STACK[logic_cpu_id].as_ptr_range().end as usize
18            }));
19
20            debug!("starting CPU {}...", i);
21            axhal::mp::start_secondary_cpu(i, stack_top);
22            logic_cpu_id += 1;
23
24            while ENTERED_CPUS.load(Ordering::Acquire) <= logic_cpu_id {
25                core::hint::spin_loop();
26            }
27        }
28    }
29}
30
31/// The main entry point of the ArceOS runtime for secondary CPUs.
32///
33/// It is called from the bootstrapping code in [axhal].
34#[unsafe(no_mangle)]
35pub extern "C" fn rust_main_secondary(cpu_id: usize) -> ! {
36    ENTERED_CPUS.fetch_add(1, Ordering::Relaxed);
37    info!("Secondary CPU {:x} started.", cpu_id);
38
39    #[cfg(feature = "paging")]
40    axmm::init_memory_management_secondary();
41
42    axhal::platform_init_secondary();
43
44    #[cfg(feature = "multitask")]
45    axtask::init_scheduler_secondary();
46
47    info!("Secondary CPU {:x} init OK.", cpu_id);
48    super::INITED_CPUS.fetch_add(1, Ordering::Relaxed);
49
50    while !super::is_init_ok() {
51        core::hint::spin_loop();
52    }
53
54    #[cfg(feature = "irq")]
55    axhal::arch::enable_irqs();
56
57    #[cfg(all(feature = "tls", not(feature = "multitask")))]
58    super::init_tls();
59
60    #[cfg(feature = "multitask")]
61    axtask::run_idle();
62    #[cfg(not(feature = "multitask"))]
63    loop {
64        axhal::arch::wait_for_irqs();
65    }
66}