axruntime/
mp.rs

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