1 use core::hint::spin_loop; 2 3 use crate::{exception::InterruptArch, sched::SchedArch, smp::core::smp_get_processor_id}; 4 5 use super::{driver::apic::apic_timer::apic_timer_init, CurrentIrqArch}; 6 7 // /// @brief 若内核代码不处在中断上下文中,那么将可以使用本函数,发起一个sys_sched系统调用,然后运行调度器。 8 // /// 由于只能在中断上下文中进行进程切换,因此需要发起一个系统调用SYS_SCHED。 9 // #[no_mangle] 10 // pub extern "C" fn sched() { 11 // let _guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 12 // __schedule(SchedMode::SM_NONE); 13 // // unsafe { 14 // // enter_syscall_int(SYS_SCHED as u64, 0, 0, 0, 0, 0, 0); 15 // // } 16 // } 17 18 static mut BSP_INIT_OK: bool = false; 19 20 pub struct X86_64SchedArch; 21 22 impl SchedArch for X86_64SchedArch { 23 fn enable_sched_local() { 24 // fixme: 这里将来可能需要更改,毕竟这个直接开关中断有点暴力。 25 unsafe { CurrentIrqArch::interrupt_enable() }; 26 } 27 28 fn disable_sched_local() { 29 unsafe { 30 CurrentIrqArch::interrupt_disable(); 31 } 32 } 33 34 fn initial_setup_sched_local() { 35 let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 36 37 let cpu_id = smp_get_processor_id(); 38 39 if cpu_id.data() != 0 { 40 while !unsafe { BSP_INIT_OK } { 41 spin_loop(); 42 } 43 } 44 45 apic_timer_init(); 46 if smp_get_processor_id().data() == 0 { 47 unsafe { 48 BSP_INIT_OK = true; 49 } 50 } 51 52 drop(irq_guard); 53 } 54 } 55