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