xref: /DragonOS/kernel/src/arch/riscv64/cpu.rs (revision 338f6903262c5031abad3c8e361813355a27fcdb)
1*338f6903SLoGin use alloc::vec::Vec;
2*338f6903SLoGin 
3*338f6903SLoGin use crate::{
4*338f6903SLoGin     init::boot_params,
5*338f6903SLoGin     kdebug,
6*338f6903SLoGin     mm::percpu::{PerCpu, PerCpuVar},
7*338f6903SLoGin     smp::cpu::{ProcessorId, SmpCpuManager},
8*338f6903SLoGin };
9e2841179SLoGin 
104fda81ceSLoGin /// 获取当前cpu的id
114fda81ceSLoGin #[inline]
12e2841179SLoGin pub fn current_cpu_id() -> ProcessorId {
13*338f6903SLoGin     let ptr: *const LocalContext = riscv::register::sscratch::read() as *const LocalContext;
14*338f6903SLoGin 
15*338f6903SLoGin     if core::intrinsics::unlikely(ptr.is_null()) {
16*338f6903SLoGin         return boot_params().read_irqsave().arch.boot_hartid;
17*338f6903SLoGin     }
18*338f6903SLoGin 
19*338f6903SLoGin     unsafe { (*ptr).current_cpu() }
204fda81ceSLoGin }
214fda81ceSLoGin 
224fda81ceSLoGin /// 重置cpu
234fda81ceSLoGin pub unsafe fn cpu_reset() -> ! {
24d14e28a8SLuo Jia / Zhouqi Jiang     sbi_rt::system_reset(sbi_rt::WarmReboot, sbi_rt::NoReason);
25d14e28a8SLuo Jia / Zhouqi Jiang     unimplemented!("RiscV64 reset failed, manual override expected ...")
264fda81ceSLoGin }
27*338f6903SLoGin 
28*338f6903SLoGin static mut LOCAL_CONTEXT: Option<PerCpuVar<LocalContext>> = None;
29*338f6903SLoGin 
30*338f6903SLoGin #[inline(always)]
31*338f6903SLoGin pub(super) fn local_context() -> &'static PerCpuVar<LocalContext> {
32*338f6903SLoGin     unsafe { LOCAL_CONTEXT.as_ref().unwrap() }
33*338f6903SLoGin }
34*338f6903SLoGin 
35*338f6903SLoGin /// Per cpu的上下文数据
36*338f6903SLoGin ///
37*338f6903SLoGin /// 每个CPU的sscratch寄存器指向这个结构体
38*338f6903SLoGin #[derive(Debug)]
39*338f6903SLoGin pub(super) struct LocalContext {
40*338f6903SLoGin     /// 当前cpu的id
41*338f6903SLoGin     current_cpu: ProcessorId,
42*338f6903SLoGin }
43*338f6903SLoGin 
44*338f6903SLoGin impl LocalContext {
45*338f6903SLoGin     fn new(cpu: ProcessorId) -> Self {
46*338f6903SLoGin         Self { current_cpu: cpu }
47*338f6903SLoGin     }
48*338f6903SLoGin     pub fn current_cpu(&self) -> ProcessorId {
49*338f6903SLoGin         self.current_cpu
50*338f6903SLoGin     }
51*338f6903SLoGin 
52*338f6903SLoGin     pub fn set_current_cpu(&mut self, cpu: ProcessorId) {
53*338f6903SLoGin         self.current_cpu = cpu;
54*338f6903SLoGin     }
55*338f6903SLoGin 
56*338f6903SLoGin     fn sync_to_cpu(&self) {
57*338f6903SLoGin         let ptr = self as *const Self as usize;
58*338f6903SLoGin         riscv::register::sscratch::write(ptr);
59*338f6903SLoGin     }
60*338f6903SLoGin }
61*338f6903SLoGin 
62*338f6903SLoGin /// 初始化本地上下文
63*338f6903SLoGin #[inline(never)]
64*338f6903SLoGin pub(super) fn init_local_context() {
65*338f6903SLoGin     kdebug!("init_local_context");
66*338f6903SLoGin     let mut data = Vec::new();
67*338f6903SLoGin 
68*338f6903SLoGin     for i in 0..PerCpu::MAX_CPU_NUM {
69*338f6903SLoGin         data.push(LocalContext::new(ProcessorId::new(i)));
70*338f6903SLoGin     }
71*338f6903SLoGin     let ctx = PerCpuVar::new(data).unwrap();
72*338f6903SLoGin 
73*338f6903SLoGin     unsafe {
74*338f6903SLoGin         LOCAL_CONTEXT = Some(ctx);
75*338f6903SLoGin     }
76*338f6903SLoGin 
77*338f6903SLoGin     let hartid = boot_params().read().arch.boot_hartid;
78*338f6903SLoGin 
79*338f6903SLoGin     let ctx = unsafe { local_context().force_get(hartid) };
80*338f6903SLoGin     ctx.sync_to_cpu();
81*338f6903SLoGin }
82*338f6903SLoGin 
83*338f6903SLoGin impl SmpCpuManager {
84*338f6903SLoGin     pub fn arch_init(boot_cpu: ProcessorId) {
85*338f6903SLoGin         // todo: 读取所有可用的CPU
86*338f6903SLoGin     }
87*338f6903SLoGin }
88