mod.rs 1.4 KB

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