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