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