1338f6903SLoGin use alloc::vec::Vec; 270f159a3SLoGin use sbi_rt::HartMask; 3338f6903SLoGin 4338f6903SLoGin use crate::{ 5338f6903SLoGin init::boot_params, 6338f6903SLoGin kdebug, 7338f6903SLoGin mm::percpu::{PerCpu, PerCpuVar}, 8338f6903SLoGin smp::cpu::{ProcessorId, SmpCpuManager}, 9338f6903SLoGin }; 10e2841179SLoGin 115c4224e5SLoGin /// 栈对齐 125c4224e5SLoGin pub(super) const STACK_ALIGN: usize = 16; 135c4224e5SLoGin 1470f159a3SLoGin /// RISC-V的XLEN,也就是寄存器的位宽 1570f159a3SLoGin pub const RISCV_XLEN: usize = core::mem::size_of::<usize>() * 8; 1670f159a3SLoGin 174fda81ceSLoGin /// 获取当前cpu的id 184fda81ceSLoGin #[inline] 19e2841179SLoGin pub fn current_cpu_id() -> ProcessorId { 205c4224e5SLoGin let ptr: *const LocalContext = riscv::register::tp::read() as *const LocalContext; 21338f6903SLoGin 22338f6903SLoGin if core::intrinsics::unlikely(ptr.is_null()) { 23338f6903SLoGin return boot_params().read_irqsave().arch.boot_hartid; 24338f6903SLoGin } 25338f6903SLoGin 26338f6903SLoGin unsafe { (*ptr).current_cpu() } 274fda81ceSLoGin } 2870f159a3SLoGin impl Into<HartMask> for ProcessorId { 2970f159a3SLoGin fn into(self) -> HartMask { 3070f159a3SLoGin let base = self.data() as usize / RISCV_XLEN; 3170f159a3SLoGin let offset = self.data() as usize & (RISCV_XLEN - 1); 3270f159a3SLoGin HartMask::from_mask_base(offset, base) 3370f159a3SLoGin } 3470f159a3SLoGin } 354fda81ceSLoGin /// 重置cpu 364fda81ceSLoGin pub unsafe fn cpu_reset() -> ! { 37d14e28a8SLuo Jia / Zhouqi Jiang sbi_rt::system_reset(sbi_rt::WarmReboot, sbi_rt::NoReason); 38d14e28a8SLuo Jia / Zhouqi Jiang unimplemented!("RiscV64 reset failed, manual override expected ...") 394fda81ceSLoGin } 40338f6903SLoGin 41338f6903SLoGin static mut LOCAL_CONTEXT: Option<PerCpuVar<LocalContext>> = None; 42338f6903SLoGin 43338f6903SLoGin #[inline(always)] 44338f6903SLoGin pub(super) fn local_context() -> &'static PerCpuVar<LocalContext> { 45338f6903SLoGin unsafe { LOCAL_CONTEXT.as_ref().unwrap() } 46338f6903SLoGin } 47338f6903SLoGin 48338f6903SLoGin /// Per cpu的上下文数据 49338f6903SLoGin /// 505c4224e5SLoGin /// 每个CPU的tp寄存器指向这个结构体 515c4224e5SLoGin /// 525c4224e5SLoGin /// 注意: 535c4224e5SLoGin /// 545c4224e5SLoGin /// - 从用户态进入内核态时,会从sscratch寄存器加载这个结构体的地址到tp寄存器,并把sscratch寄存器清零 555c4224e5SLoGin /// - 从内核态进入用户态时,会将tp寄存器的值保存到sscratch寄存器 56*9b96c5b5SLoGin #[derive(Debug, Clone, Copy)] 57338f6903SLoGin pub(super) struct LocalContext { 58338f6903SLoGin /// 当前cpu的id 595c4224e5SLoGin pub current_cpu: ProcessorId, 605c4224e5SLoGin // 当前进程的内核栈指针(暂存,当进入中断处理程序的时候需要保存到pcb,进程切换的时候需要重新设置这个值) 615c4224e5SLoGin pub kernel_sp: usize, 625c4224e5SLoGin // 当前进程的用户栈指针(暂存,当进入中断处理程序的时候需要保存到pcb,进程切换的时候需要重新设置这个值) 635c4224e5SLoGin pub user_sp: usize, 64338f6903SLoGin } 65338f6903SLoGin 66338f6903SLoGin impl LocalContext { 67*9b96c5b5SLoGin pub fn new(cpu: ProcessorId) -> Self { 685c4224e5SLoGin Self { 695c4224e5SLoGin current_cpu: cpu, 705c4224e5SLoGin kernel_sp: 0, 715c4224e5SLoGin user_sp: 0, 725c4224e5SLoGin } 73338f6903SLoGin } 74338f6903SLoGin pub fn current_cpu(&self) -> ProcessorId { 75338f6903SLoGin self.current_cpu 76338f6903SLoGin } 77338f6903SLoGin 78338f6903SLoGin pub fn set_current_cpu(&mut self, cpu: ProcessorId) { 79338f6903SLoGin self.current_cpu = cpu; 80338f6903SLoGin } 81338f6903SLoGin 825c4224e5SLoGin pub fn kernel_sp(&self) -> usize { 835c4224e5SLoGin self.kernel_sp 845c4224e5SLoGin } 855c4224e5SLoGin 865c4224e5SLoGin pub fn set_kernel_sp(&mut self, sp: usize) { 875c4224e5SLoGin self.kernel_sp = sp; 885c4224e5SLoGin } 895c4224e5SLoGin 905c4224e5SLoGin pub fn user_sp(&self) -> usize { 915c4224e5SLoGin self.user_sp 925c4224e5SLoGin } 935c4224e5SLoGin 945c4224e5SLoGin pub fn set_user_sp(&mut self, sp: usize) { 955c4224e5SLoGin self.user_sp = sp; 965c4224e5SLoGin } 975c4224e5SLoGin 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 } 105*9b96c5b5SLoGin 106*9b96c5b5SLoGin pub fn restore(&mut self, from: &LocalContext) { 107*9b96c5b5SLoGin // 不恢复cpu id 108*9b96c5b5SLoGin 109*9b96c5b5SLoGin self.kernel_sp = from.kernel_sp; 110*9b96c5b5SLoGin self.user_sp = from.user_sp; 111*9b96c5b5SLoGin } 112338f6903SLoGin } 113338f6903SLoGin 114338f6903SLoGin /// 初始化本地上下文 115338f6903SLoGin #[inline(never)] 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 { 135338f6903SLoGin pub fn arch_init(boot_cpu: ProcessorId) { 136338f6903SLoGin // todo: 读取所有可用的CPU 137338f6903SLoGin } 138338f6903SLoGin } 139