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 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)]` 29 fn prepare_cpus() -> Result<(), SystemError>; 30 31 /// 在smp初始化结束后,执行一些必要的操作 32 /// 33 /// 该函数需要标记为 `#[inline(never)]` 34 fn post_init() -> Result<(), SystemError> { 35 return Ok(()); 36 } 37 38 /// 向目标CPU发送启动信号 39 /// 40 /// 如果目标CPU已经启动,返回Ok。 41 fn start_cpu(cpu_id: ProcessorId, hp_state: &CpuHpCpuState) -> Result<(), SystemError>; 42 } 43 44 /// 早期SMP初始化 45 #[inline(never)] 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)] 53 pub fn smp_init() { 54 smp_cpu_manager().bringup_nonboot_cpus(); 55 56 CurrentSMPArch::post_init().expect("SMP post init failed"); 57 } 58