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