xref: /DragonOS/kernel/src/arch/riscv64/cpu.rs (revision 5c4224e5a8244cb0fb32512e70354362fccd6321)
1338f6903SLoGin use alloc::vec::Vec;
2338f6903SLoGin 
3338f6903SLoGin use crate::{
4338f6903SLoGin     init::boot_params,
5338f6903SLoGin     kdebug,
6338f6903SLoGin     mm::percpu::{PerCpu, PerCpuVar},
7338f6903SLoGin     smp::cpu::{ProcessorId, SmpCpuManager},
8338f6903SLoGin };
9e2841179SLoGin 
10*5c4224e5SLoGin /// 栈对齐
11*5c4224e5SLoGin pub(super) const STACK_ALIGN: usize = 16;
12*5c4224e5SLoGin 
134fda81ceSLoGin /// 获取当前cpu的id
144fda81ceSLoGin #[inline]
15e2841179SLoGin pub fn current_cpu_id() -> ProcessorId {
16*5c4224e5SLoGin     let ptr: *const LocalContext = riscv::register::tp::read() as *const LocalContext;
17338f6903SLoGin 
18338f6903SLoGin     if core::intrinsics::unlikely(ptr.is_null()) {
19338f6903SLoGin         return boot_params().read_irqsave().arch.boot_hartid;
20338f6903SLoGin     }
21338f6903SLoGin 
22338f6903SLoGin     unsafe { (*ptr).current_cpu() }
234fda81ceSLoGin }
244fda81ceSLoGin 
254fda81ceSLoGin /// 重置cpu
264fda81ceSLoGin pub unsafe fn cpu_reset() -> ! {
27d14e28a8SLuo Jia / Zhouqi Jiang     sbi_rt::system_reset(sbi_rt::WarmReboot, sbi_rt::NoReason);
28d14e28a8SLuo Jia / Zhouqi Jiang     unimplemented!("RiscV64 reset failed, manual override expected ...")
294fda81ceSLoGin }
30338f6903SLoGin 
31338f6903SLoGin static mut LOCAL_CONTEXT: Option<PerCpuVar<LocalContext>> = None;
32338f6903SLoGin 
33338f6903SLoGin #[inline(always)]
34338f6903SLoGin pub(super) fn local_context() -> &'static PerCpuVar<LocalContext> {
35338f6903SLoGin     unsafe { LOCAL_CONTEXT.as_ref().unwrap() }
36338f6903SLoGin }
37338f6903SLoGin 
38338f6903SLoGin /// Per cpu的上下文数据
39338f6903SLoGin ///
40*5c4224e5SLoGin /// 每个CPU的tp寄存器指向这个结构体
41*5c4224e5SLoGin ///
42*5c4224e5SLoGin /// 注意:
43*5c4224e5SLoGin ///
44*5c4224e5SLoGin /// - 从用户态进入内核态时,会从sscratch寄存器加载这个结构体的地址到tp寄存器,并把sscratch寄存器清零
45*5c4224e5SLoGin /// - 从内核态进入用户态时,会将tp寄存器的值保存到sscratch寄存器
46338f6903SLoGin #[derive(Debug)]
47338f6903SLoGin pub(super) struct LocalContext {
48338f6903SLoGin     /// 当前cpu的id
49*5c4224e5SLoGin     pub current_cpu: ProcessorId,
50*5c4224e5SLoGin     // 当前进程的内核栈指针(暂存,当进入中断处理程序的时候需要保存到pcb,进程切换的时候需要重新设置这个值)
51*5c4224e5SLoGin     pub kernel_sp: usize,
52*5c4224e5SLoGin     // 当前进程的用户栈指针(暂存,当进入中断处理程序的时候需要保存到pcb,进程切换的时候需要重新设置这个值)
53*5c4224e5SLoGin     pub user_sp: usize,
54338f6903SLoGin }
55338f6903SLoGin 
56338f6903SLoGin impl LocalContext {
57338f6903SLoGin     fn new(cpu: ProcessorId) -> Self {
58*5c4224e5SLoGin         Self {
59*5c4224e5SLoGin             current_cpu: cpu,
60*5c4224e5SLoGin             kernel_sp: 0,
61*5c4224e5SLoGin             user_sp: 0,
62*5c4224e5SLoGin         }
63338f6903SLoGin     }
64338f6903SLoGin     pub fn current_cpu(&self) -> ProcessorId {
65338f6903SLoGin         self.current_cpu
66338f6903SLoGin     }
67338f6903SLoGin 
68338f6903SLoGin     pub fn set_current_cpu(&mut self, cpu: ProcessorId) {
69338f6903SLoGin         self.current_cpu = cpu;
70338f6903SLoGin     }
71338f6903SLoGin 
72*5c4224e5SLoGin     pub fn kernel_sp(&self) -> usize {
73*5c4224e5SLoGin         self.kernel_sp
74*5c4224e5SLoGin     }
75*5c4224e5SLoGin 
76*5c4224e5SLoGin     pub fn set_kernel_sp(&mut self, sp: usize) {
77*5c4224e5SLoGin         self.kernel_sp = sp;
78*5c4224e5SLoGin     }
79*5c4224e5SLoGin 
80*5c4224e5SLoGin     pub fn user_sp(&self) -> usize {
81*5c4224e5SLoGin         self.user_sp
82*5c4224e5SLoGin     }
83*5c4224e5SLoGin 
84*5c4224e5SLoGin     pub fn set_user_sp(&mut self, sp: usize) {
85*5c4224e5SLoGin         self.user_sp = sp;
86*5c4224e5SLoGin     }
87*5c4224e5SLoGin 
88338f6903SLoGin     fn sync_to_cpu(&self) {
89338f6903SLoGin         let ptr = self as *const Self as usize;
90*5c4224e5SLoGin         riscv::register::sscratch::write(0);
91*5c4224e5SLoGin 
92*5c4224e5SLoGin         // 写入tp寄存器
93*5c4224e5SLoGin         riscv::register::tp::write(ptr);
94338f6903SLoGin     }
95338f6903SLoGin }
96338f6903SLoGin 
97338f6903SLoGin /// 初始化本地上下文
98338f6903SLoGin #[inline(never)]
99338f6903SLoGin pub(super) fn init_local_context() {
100338f6903SLoGin     let mut data = Vec::new();
101338f6903SLoGin 
102338f6903SLoGin     for i in 0..PerCpu::MAX_CPU_NUM {
103338f6903SLoGin         data.push(LocalContext::new(ProcessorId::new(i)));
104338f6903SLoGin     }
105338f6903SLoGin     let ctx = PerCpuVar::new(data).unwrap();
106338f6903SLoGin 
107338f6903SLoGin     unsafe {
108338f6903SLoGin         LOCAL_CONTEXT = Some(ctx);
109338f6903SLoGin     }
110338f6903SLoGin 
111338f6903SLoGin     let hartid = boot_params().read().arch.boot_hartid;
112338f6903SLoGin 
113338f6903SLoGin     let ctx = unsafe { local_context().force_get(hartid) };
114338f6903SLoGin     ctx.sync_to_cpu();
115338f6903SLoGin }
116338f6903SLoGin 
117338f6903SLoGin impl SmpCpuManager {
118338f6903SLoGin     pub fn arch_init(boot_cpu: ProcessorId) {
119338f6903SLoGin         // todo: 读取所有可用的CPU
120338f6903SLoGin     }
121338f6903SLoGin }
122