os/kernel/
cpu.rs

1//! CPU 相关模块
2//!
3//! 包含 CPU 结构体及其相关操作
4use 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
25/// CPU 结构体
26pub struct Cpu {
27    /// 任务上下文
28    /// 用于在调度器中保存和恢复 CPU 寄存器状态
29    /// 当前运行的任务
30    pub current_task: Option<SharedTask>,
31    /// 当前使用的内存空间
32    /// 对于内核线程,其本身相应字段为 None,因而使用上一个任务的内存空间
33    pub current_memory_space: Option<Arc<SpinLock<MemorySpace>>>,
34}
35
36impl Cpu {
37    /// 创建一个新的 CPU 实例
38    pub fn new() -> Self {
39        Cpu {
40            current_task: None,
41            current_memory_space: None,
42        }
43    }
44
45    /// 切换当前任务
46    /// # 参数
47    /// * `task` - 要切换到的任务
48    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    /// 切换当前内存空间
63    /// # 参数
64    /// * `space` - 要切换到的内存空间
65    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
71/// 获取当前 CPU 的引用
72pub fn current_cpu() -> &'static SpinLock<Cpu> {
73    let cpu_id = crate::arch::kernel::cpu::cpu_id();
74    &CPUS[cpu_id]
75}