1use alloc::sync::Arc;
5use alloc::vec::Vec;
6
7use crate::mm::activate;
8use crate::{kernel::task::SharedTask, mm::memory_space::MemorySpace, sync::SpinLock};
9use lazy_static::lazy_static;
10
11pub static mut NUM_CPU: usize = 1;
12pub static mut CLOCK_FREQ: usize = 12_500_000;
13
14lazy_static! {
15 pub static ref CPUS: Vec<SpinLock<Cpu>> = {
16 let num_cpu = unsafe { NUM_CPU };
17 let mut cpus = Vec::with_capacity(num_cpu);
18 for _ in 0..num_cpu {
19 cpus.push(SpinLock::new(Cpu::new()));
20 }
21 cpus
22 };
23}
24
25pub struct Cpu {
27 pub current_task: Option<SharedTask>,
31 pub current_memory_space: Option<Arc<SpinLock<MemorySpace>>>,
34}
35
36impl Cpu {
37 pub fn new() -> Self {
39 Cpu {
40 current_task: None,
41 current_memory_space: None,
42 }
43 }
44
45 pub fn switch_task(&mut self, task: SharedTask) {
49 self.current_task = Some(task.clone());
50 if !task.lock().is_kernel_thread() {
51 self.current_memory_space = task.lock().memory_space.clone();
52 activate(
53 self.current_memory_space
54 .as_ref()
55 .unwrap()
56 .lock()
57 .root_ppn(),
58 );
59 }
60 }
61
62 pub fn switch_space(&mut self, space: Arc<SpinLock<MemorySpace>>) {
66 self.current_memory_space = Some(space.clone());
67 activate(space.lock().root_ppn());
68 }
69}
70
71pub fn current_cpu() -> &'static SpinLock<Cpu> {
73 let cpu_id = crate::arch::kernel::cpu::cpu_id();
74 &CPUS[cpu_id]
75}