xref: /DragonOS/kernel/src/process/idle.rs (revision f0c87a897fe813b7f06bf5a9e93c43ad9519dafd)
11496ba7bSLoGin use core::{
21496ba7bSLoGin     intrinsics::unlikely,
31496ba7bSLoGin     sync::atomic::{AtomicBool, Ordering},
41496ba7bSLoGin };
51496ba7bSLoGin 
61496ba7bSLoGin use alloc::{sync::Arc, vec::Vec};
71496ba7bSLoGin 
81496ba7bSLoGin use crate::{
98cb2e9b3SLoGin     mm::{percpu::PerCpu, VirtAddr, IDLE_PROCESS_ADDRESS_SPACE},
101496ba7bSLoGin     process::KernelStack,
11*f0c87a89SGnoCiYeH     sched::{cpu_rq, OnRq},
12e2841179SLoGin     smp::{core::smp_get_processor_id, cpu::ProcessorId},
131496ba7bSLoGin };
141496ba7bSLoGin 
151496ba7bSLoGin use super::{ProcessControlBlock, ProcessManager};
161496ba7bSLoGin 
171496ba7bSLoGin static mut __IDLE_PCB: Option<Vec<Arc<ProcessControlBlock>>> = None;
181496ba7bSLoGin 
191496ba7bSLoGin impl ProcessManager {
201496ba7bSLoGin     /// 初始化每个核的idle进程
init_idle()211496ba7bSLoGin     pub fn init_idle() {
221496ba7bSLoGin         static INIT_IDLE: AtomicBool = AtomicBool::new(false);
231496ba7bSLoGin         if INIT_IDLE
241496ba7bSLoGin             .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst)
251496ba7bSLoGin             .is_err()
261496ba7bSLoGin         {
271496ba7bSLoGin             panic!("Idle process already initialized");
281496ba7bSLoGin         }
291496ba7bSLoGin 
301496ba7bSLoGin         assert!(
31e2841179SLoGin             smp_get_processor_id() == ProcessorId::new(0),
321496ba7bSLoGin             "Idle process must be initialized on the first processor"
331496ba7bSLoGin         );
34e2841179SLoGin         let mut v: Vec<Arc<ProcessControlBlock>> = Vec::with_capacity(PerCpu::MAX_CPU_NUM as usize);
351496ba7bSLoGin 
361496ba7bSLoGin         for i in 0..PerCpu::MAX_CPU_NUM {
371496ba7bSLoGin             let kstack = if unlikely(i == 0) {
381496ba7bSLoGin                 let stack_ptr =
391496ba7bSLoGin                     VirtAddr::new(Self::stack_ptr().data() & (!(KernelStack::ALIGN - 1)));
401496ba7bSLoGin                 // 初始化bsp的idle进程
412f6f547aSGnoCiYeH                 let mut ks = unsafe { KernelStack::from_existed(stack_ptr) }
422f6f547aSGnoCiYeH                     .expect("Failed to create kernel stack struct for BSP.");
432f6f547aSGnoCiYeH                 unsafe { ks.clear_pcb(true) };
442f6f547aSGnoCiYeH                 ks
451496ba7bSLoGin             } else {
4691e9d4abSLoGin                 KernelStack::new().unwrap_or_else(|e| {
471496ba7bSLoGin                     panic!("Failed to create kernel stack struct for AP {}: {:?}", i, e)
481496ba7bSLoGin                 })
491496ba7bSLoGin             };
501496ba7bSLoGin 
51b5b571e0SLoGin             let idle_pcb = ProcessControlBlock::new_idle(i, kstack);
521496ba7bSLoGin 
531496ba7bSLoGin             assert!(idle_pcb.basic().user_vm().is_none());
541496ba7bSLoGin             unsafe {
551496ba7bSLoGin                 idle_pcb
561496ba7bSLoGin                     .basic_mut()
578cb2e9b3SLoGin                     .set_user_vm(Some(IDLE_PROCESS_ADDRESS_SPACE()))
581496ba7bSLoGin             };
591496ba7bSLoGin 
601496ba7bSLoGin             assert!(idle_pcb.sched_info().on_cpu().is_none());
61e2841179SLoGin             idle_pcb.sched_info().set_on_cpu(Some(ProcessorId::new(i)));
62*f0c87a89SGnoCiYeH             *idle_pcb.sched_info().sched_policy.write_irqsave() = crate::sched::SchedPolicy::IDLE;
63*f0c87a89SGnoCiYeH 
64*f0c87a89SGnoCiYeH             let rq = cpu_rq(i as usize);
65*f0c87a89SGnoCiYeH             let (rq, _guard) = rq.self_lock();
66*f0c87a89SGnoCiYeH             rq.set_current(Arc::downgrade(&idle_pcb));
67*f0c87a89SGnoCiYeH             rq.set_idle(Arc::downgrade(&idle_pcb));
68*f0c87a89SGnoCiYeH 
69*f0c87a89SGnoCiYeH             *idle_pcb.sched_info().on_rq.lock_irqsave() = OnRq::Queued;
70*f0c87a89SGnoCiYeH 
71*f0c87a89SGnoCiYeH             idle_pcb
72*f0c87a89SGnoCiYeH                 .sched_info()
73*f0c87a89SGnoCiYeH                 .sched_entity()
74*f0c87a89SGnoCiYeH                 .force_mut()
75*f0c87a89SGnoCiYeH                 .set_cfs(Arc::downgrade(&rq.cfs_rq()));
76*f0c87a89SGnoCiYeH 
771496ba7bSLoGin             v.push(idle_pcb);
781496ba7bSLoGin         }
791496ba7bSLoGin 
801496ba7bSLoGin         unsafe {
811496ba7bSLoGin             __IDLE_PCB = Some(v);
821496ba7bSLoGin         }
831496ba7bSLoGin     }
841496ba7bSLoGin 
851496ba7bSLoGin     /// 获取当前的栈指针
861496ba7bSLoGin     ///
871496ba7bSLoGin     /// 请注意,该函数只是于辅助bsp核心的idle进程初始化
stack_ptr() -> VirtAddr881496ba7bSLoGin     fn stack_ptr() -> VirtAddr {
891496ba7bSLoGin         #[cfg(target_arch = "x86_64")]
901496ba7bSLoGin         return VirtAddr::new(x86::current::registers::rsp() as usize);
914fda81ceSLoGin 
924fda81ceSLoGin         #[cfg(target_arch = "riscv64")]
9340169973SLoGin         {
9440169973SLoGin             let stack_ptr: usize;
9540169973SLoGin             unsafe {
9640169973SLoGin                 core::arch::asm!("mv {}, sp", out(reg) stack_ptr);
9740169973SLoGin             }
9840169973SLoGin             return VirtAddr::new(stack_ptr);
9940169973SLoGin         }
1001496ba7bSLoGin     }
1011496ba7bSLoGin 
1021496ba7bSLoGin     /// 获取idle进程数组的引用
idle_pcb() -> &'static Vec<Arc<ProcessControlBlock>>1031496ba7bSLoGin     pub fn idle_pcb() -> &'static Vec<Arc<ProcessControlBlock>> {
1041496ba7bSLoGin         unsafe { __IDLE_PCB.as_ref().unwrap() }
1051496ba7bSLoGin     }
1061496ba7bSLoGin }
107