xref: /DragonOS/kernel/src/smp/mod.rs (revision b5b571e02693d91eb6918d3b7561e088c3e7ee81)
1 use system_error::SystemError;
2 
3 use crate::{
4     arch::{interrupt::ipi::send_ipi, CurrentSMPArch},
5     exception::ipi::{IpiKind, IpiTarget},
6 };
7 
8 use self::{
9     core::smp_get_processor_id,
10     cpu::{smp_cpu_manager, smp_cpu_manager_init, CpuHpCpuState, ProcessorId},
11 };
12 
13 pub mod core;
14 pub mod cpu;
15 pub mod init;
16 
17 pub fn kick_cpu(cpu_id: ProcessorId) -> Result<(), SystemError> {
18     // todo: 增加对cpu_id的有效性检查
19 
20     send_ipi(IpiKind::KickCpu, IpiTarget::Specified(cpu_id));
21     return Ok(());
22 }
23 
24 pub trait SMPArch {
25     /// 准备SMP初始化所需的cpu拓扑数据。
26     ///
27     /// 该函数需要标记为 `#[inline(never)]`
28     fn prepare_cpus() -> Result<(), SystemError>;
29 
30     /// 在smp初始化结束后,执行一些必要的操作
31     ///
32     /// 该函数需要标记为 `#[inline(never)]`
33     fn post_init() -> Result<(), SystemError> {
34         return Ok(());
35     }
36 
37     /// 向目标CPU发送启动信号
38     ///
39     /// 如果目标CPU已经启动,返回Ok。
40     fn start_cpu(cpu_id: ProcessorId, hp_state: &CpuHpCpuState) -> Result<(), SystemError>;
41 }
42 
43 /// 早期SMP初始化
44 #[inline(never)]
45 pub fn early_smp_init() -> Result<(), SystemError> {
46     smp_cpu_manager_init(smp_get_processor_id());
47 
48     return Ok(());
49 }
50 
51 #[inline(never)]
52 pub fn smp_init() {
53     smp_cpu_manager().bringup_nonboot_cpus();
54 
55     CurrentSMPArch::post_init().expect("SMP post init failed");
56 }
57