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