xref: /DragonOS/kernel/src/arch/riscv64/cpu.rs (revision 942cf26b48c8b024a6fa7867bb0c8ae39bb1ae09)
1338f6903SLoGin use alloc::vec::Vec;
270f159a3SLoGin use sbi_rt::HartMask;
3338f6903SLoGin 
4338f6903SLoGin use crate::{
5338f6903SLoGin     init::boot_params,
6338f6903SLoGin     mm::percpu::{PerCpu, PerCpuVar},
7338f6903SLoGin     smp::cpu::{ProcessorId, SmpCpuManager},
8338f6903SLoGin };
9e2841179SLoGin 
105c4224e5SLoGin /// 栈对齐
115c4224e5SLoGin pub(super) const STACK_ALIGN: usize = 16;
125c4224e5SLoGin 
1370f159a3SLoGin /// RISC-V的XLEN,也就是寄存器的位宽
1470f159a3SLoGin pub const RISCV_XLEN: usize = core::mem::size_of::<usize>() * 8;
1570f159a3SLoGin 
164fda81ceSLoGin /// 获取当前cpu的id
174fda81ceSLoGin #[inline]
current_cpu_id() -> ProcessorId18e2841179SLoGin pub fn current_cpu_id() -> ProcessorId {
195c4224e5SLoGin     let ptr: *const LocalContext = riscv::register::tp::read() as *const LocalContext;
20338f6903SLoGin 
21338f6903SLoGin     if core::intrinsics::unlikely(ptr.is_null()) {
22338f6903SLoGin         return boot_params().read_irqsave().arch.boot_hartid;
23338f6903SLoGin     }
24338f6903SLoGin 
25338f6903SLoGin     unsafe { (*ptr).current_cpu() }
264fda81ceSLoGin }
2770f159a3SLoGin impl Into<HartMask> for ProcessorId {
into(self) -> HartMask2870f159a3SLoGin     fn into(self) -> HartMask {
2970f159a3SLoGin         let base = self.data() as usize / RISCV_XLEN;
3070f159a3SLoGin         let offset = self.data() as usize & (RISCV_XLEN - 1);
3170f159a3SLoGin         HartMask::from_mask_base(offset, base)
3270f159a3SLoGin     }
3370f159a3SLoGin }
344fda81ceSLoGin /// 重置cpu
cpu_reset() -> !354fda81ceSLoGin pub unsafe fn cpu_reset() -> ! {
36d14e28a8SLuo Jia / Zhouqi Jiang     sbi_rt::system_reset(sbi_rt::WarmReboot, sbi_rt::NoReason);
37d14e28a8SLuo Jia / Zhouqi Jiang     unimplemented!("RiscV64 reset failed, manual override expected ...")
384fda81ceSLoGin }
39338f6903SLoGin 
40338f6903SLoGin static mut LOCAL_CONTEXT: Option<PerCpuVar<LocalContext>> = None;
41338f6903SLoGin 
42338f6903SLoGin #[inline(always)]
local_context() -> &'static PerCpuVar<LocalContext>43338f6903SLoGin pub(super) fn local_context() -> &'static PerCpuVar<LocalContext> {
44338f6903SLoGin     unsafe { LOCAL_CONTEXT.as_ref().unwrap() }
45338f6903SLoGin }
46338f6903SLoGin 
47338f6903SLoGin /// Per cpu的上下文数据
48338f6903SLoGin ///
495c4224e5SLoGin /// 每个CPU的tp寄存器指向这个结构体
505c4224e5SLoGin ///
515c4224e5SLoGin /// 注意:
525c4224e5SLoGin ///
535c4224e5SLoGin /// - 从用户态进入内核态时,会从sscratch寄存器加载这个结构体的地址到tp寄存器,并把sscratch寄存器清零
545c4224e5SLoGin /// - 从内核态进入用户态时,会将tp寄存器的值保存到sscratch寄存器
559b96c5b5SLoGin #[derive(Debug, Clone, Copy)]
56338f6903SLoGin pub(super) struct LocalContext {
57338f6903SLoGin     /// 当前cpu的id
585c4224e5SLoGin     pub current_cpu: ProcessorId,
595c4224e5SLoGin     // 当前进程的内核栈指针(暂存,当进入中断处理程序的时候需要保存到pcb,进程切换的时候需要重新设置这个值)
605c4224e5SLoGin     pub kernel_sp: usize,
615c4224e5SLoGin     // 当前进程的用户栈指针(暂存,当进入中断处理程序的时候需要保存到pcb,进程切换的时候需要重新设置这个值)
625c4224e5SLoGin     pub user_sp: usize,
63338f6903SLoGin }
64338f6903SLoGin 
65*942cf26bSLoGin #[allow(dead_code)]
66338f6903SLoGin impl LocalContext {
new(cpu: ProcessorId) -> Self679b96c5b5SLoGin     pub fn new(cpu: ProcessorId) -> Self {
685c4224e5SLoGin         Self {
695c4224e5SLoGin             current_cpu: cpu,
705c4224e5SLoGin             kernel_sp: 0,
715c4224e5SLoGin             user_sp: 0,
725c4224e5SLoGin         }
73338f6903SLoGin     }
current_cpu(&self) -> ProcessorId74338f6903SLoGin     pub fn current_cpu(&self) -> ProcessorId {
75338f6903SLoGin         self.current_cpu
76338f6903SLoGin     }
77338f6903SLoGin 
set_current_cpu(&mut self, cpu: ProcessorId)78338f6903SLoGin     pub fn set_current_cpu(&mut self, cpu: ProcessorId) {
79338f6903SLoGin         self.current_cpu = cpu;
80338f6903SLoGin     }
81338f6903SLoGin 
kernel_sp(&self) -> usize825c4224e5SLoGin     pub fn kernel_sp(&self) -> usize {
835c4224e5SLoGin         self.kernel_sp
845c4224e5SLoGin     }
855c4224e5SLoGin 
set_kernel_sp(&mut self, sp: usize)865c4224e5SLoGin     pub fn set_kernel_sp(&mut self, sp: usize) {
875c4224e5SLoGin         self.kernel_sp = sp;
885c4224e5SLoGin     }
895c4224e5SLoGin 
user_sp(&self) -> usize905c4224e5SLoGin     pub fn user_sp(&self) -> usize {
915c4224e5SLoGin         self.user_sp
925c4224e5SLoGin     }
935c4224e5SLoGin 
set_user_sp(&mut self, sp: usize)945c4224e5SLoGin     pub fn set_user_sp(&mut self, sp: usize) {
955c4224e5SLoGin         self.user_sp = sp;
965c4224e5SLoGin     }
975c4224e5SLoGin 
sync_to_cpu(&self)98338f6903SLoGin     fn sync_to_cpu(&self) {
99338f6903SLoGin         let ptr = self as *const Self as usize;
1005c4224e5SLoGin         riscv::register::sscratch::write(0);
1015c4224e5SLoGin 
1025c4224e5SLoGin         // 写入tp寄存器
1035c4224e5SLoGin         riscv::register::tp::write(ptr);
104338f6903SLoGin     }
1059b96c5b5SLoGin 
restore(&mut self, from: &LocalContext)1069b96c5b5SLoGin     pub fn restore(&mut self, from: &LocalContext) {
1079b96c5b5SLoGin         // 不恢复cpu id
1089b96c5b5SLoGin 
1099b96c5b5SLoGin         self.kernel_sp = from.kernel_sp;
1109b96c5b5SLoGin         self.user_sp = from.user_sp;
1119b96c5b5SLoGin     }
112338f6903SLoGin }
113338f6903SLoGin 
114338f6903SLoGin /// 初始化本地上下文
115338f6903SLoGin #[inline(never)]
init_local_context()116338f6903SLoGin pub(super) fn init_local_context() {
117338f6903SLoGin     let mut data = Vec::new();
118338f6903SLoGin 
119338f6903SLoGin     for i in 0..PerCpu::MAX_CPU_NUM {
120338f6903SLoGin         data.push(LocalContext::new(ProcessorId::new(i)));
121338f6903SLoGin     }
122338f6903SLoGin     let ctx = PerCpuVar::new(data).unwrap();
123338f6903SLoGin 
124338f6903SLoGin     unsafe {
125338f6903SLoGin         LOCAL_CONTEXT = Some(ctx);
126338f6903SLoGin     }
127338f6903SLoGin 
128338f6903SLoGin     let hartid = boot_params().read().arch.boot_hartid;
129338f6903SLoGin 
130338f6903SLoGin     let ctx = unsafe { local_context().force_get(hartid) };
131338f6903SLoGin     ctx.sync_to_cpu();
132338f6903SLoGin }
133338f6903SLoGin 
134338f6903SLoGin impl SmpCpuManager {
arch_init(_boot_cpu: ProcessorId)135*942cf26bSLoGin     pub fn arch_init(_boot_cpu: ProcessorId) {
136338f6903SLoGin         // todo: 读取所有可用的CPU
137338f6903SLoGin     }
138338f6903SLoGin }
139