1 use alloc::{ 2 string::String, 3 sync::{Arc, Weak}, 4 vec::Vec, 5 }; 6 use core::{ 7 arch::asm, 8 intrinsics::unlikely, 9 mem::ManuallyDrop, 10 sync::atomic::{compiler_fence, Ordering}, 11 }; 12 use kdepends::memoffset::offset_of; 13 use system_error::SystemError; 14 15 use crate::{ 16 arch::{ 17 interrupt::entry::ret_from_exception, process::kthread::kernel_thread_bootstrap_stage1, 18 CurrentIrqArch, 19 }, 20 exception::InterruptArch, 21 kerror, 22 libs::spinlock::SpinLockGuard, 23 mm::VirtAddr, 24 process::{ 25 fork::{CloneFlags, KernelCloneArgs}, 26 switch_finish_hook, KernelStack, ProcessControlBlock, ProcessFlags, ProcessManager, 27 PROCESS_SWITCH_RESULT, 28 }, 29 smp::cpu::ProcessorId, 30 }; 31 32 use super::{ 33 cpu::{local_context, LocalContext}, 34 interrupt::TrapFrame, 35 }; 36 37 pub mod idle; 38 pub mod kthread; 39 pub mod syscall; 40 41 #[allow(dead_code)] 42 #[repr(align(32768))] 43 union InitProcUnion { 44 /// 用于存放idle进程的内核栈 45 idle_stack: [u8; 32768], 46 } 47 48 #[link_section = ".data.init_proc_union"] 49 #[no_mangle] 50 static BSP_IDLE_STACK_SPACE: InitProcUnion = InitProcUnion { 51 idle_stack: [0; 32768], 52 }; 53 54 pub unsafe fn arch_switch_to_user(path: String, argv: Vec<String>, envp: Vec<String>) -> ! { 55 unimplemented!("RiscV64 arch_switch_to_user") 56 } 57 58 impl ProcessManager { 59 pub fn arch_init() { 60 // do nothing 61 } 62 63 /// fork的过程中复制线程 64 /// 65 /// 由于这个过程与具体的架构相关,所以放在这里 66 pub fn copy_thread( 67 current_pcb: &Arc<ProcessControlBlock>, 68 new_pcb: &Arc<ProcessControlBlock>, 69 clone_args: KernelCloneArgs, 70 current_trapframe: &TrapFrame, 71 ) -> Result<(), SystemError> { 72 let clone_flags = clone_args.flags; 73 let mut child_trapframe = *current_trapframe; 74 75 // 子进程的返回值为0 76 child_trapframe.set_return_value(0); 77 78 // 设置子进程的栈基址(开始执行中断返回流程时的栈基址) 79 let mut new_arch_guard = unsafe { new_pcb.arch_info() }; 80 let kernel_stack_guard = new_pcb.kernel_stack(); 81 let trap_frame_vaddr: VirtAddr = 82 kernel_stack_guard.stack_max_address() - core::mem::size_of::<TrapFrame>(); 83 new_arch_guard.set_stack(trap_frame_vaddr); 84 85 // 拷贝栈帧 86 unsafe { 87 let usp = clone_args.stack; 88 if usp != 0 { 89 child_trapframe.sp = usp; 90 } 91 let trap_frame_ptr = trap_frame_vaddr.data() as *mut TrapFrame; 92 *trap_frame_ptr = child_trapframe; 93 } 94 95 // copy arch info 96 97 let current_arch_guard = current_pcb.arch_info_irqsave(); 98 // 拷贝浮点寄存器的状态 99 new_arch_guard.fp_state = current_arch_guard.fp_state; 100 101 drop(current_arch_guard); 102 103 // 设置返回地址(子进程开始执行的指令地址) 104 if new_pcb.flags().contains(ProcessFlags::KTHREAD) { 105 let kthread_bootstrap_stage1_func_addr = kernel_thread_bootstrap_stage1 as usize; 106 new_arch_guard.ra = kthread_bootstrap_stage1_func_addr; 107 } else { 108 new_arch_guard.ra = ret_from_exception as usize; 109 } 110 111 // 设置tls 112 if clone_flags.contains(CloneFlags::CLONE_SETTLS) { 113 drop(new_arch_guard); 114 todo!("set tls"); 115 } 116 117 return Ok(()); 118 } 119 120 /// 切换进程 121 /// 122 /// ## 参数 123 /// 124 /// - `prev`:上一个进程的pcb 125 /// - `next`:下一个进程的pcb 126 /// 127 /// 参考: https://code.dragonos.org.cn/xref/linux-6.6.21/arch/riscv/include/asm/switch_to.h#76 128 pub unsafe fn switch_process(prev: Arc<ProcessControlBlock>, next: Arc<ProcessControlBlock>) { 129 assert!(!CurrentIrqArch::is_irq_enabled()); 130 Self::switch_process_fpu(&prev, &next); 131 Self::switch_local_context(&prev, &next); 132 133 // 切换地址空间 134 let next_addr_space = next.basic().user_vm().as_ref().unwrap().clone(); 135 compiler_fence(Ordering::SeqCst); 136 137 next_addr_space.read().user_mapper.utable.make_current(); 138 drop(next_addr_space); 139 compiler_fence(Ordering::SeqCst); 140 141 // 获取arch info的锁,并强制泄露其守卫(切换上下文后,在switch_finish_hook中会释放锁) 142 let next_arch = SpinLockGuard::leak(next.arch_info_irqsave()) as *mut ArchPCBInfo; 143 let prev_arch = SpinLockGuard::leak(prev.arch_info_irqsave()) as *mut ArchPCBInfo; 144 145 // 恢复当前的 preempt count*2 146 ProcessManager::current_pcb().preempt_enable(); 147 ProcessManager::current_pcb().preempt_enable(); 148 PROCESS_SWITCH_RESULT.as_mut().unwrap().get_mut().prev_pcb = Some(prev); 149 PROCESS_SWITCH_RESULT.as_mut().unwrap().get_mut().next_pcb = Some(next); 150 // kdebug!("switch tss ok"); 151 compiler_fence(Ordering::SeqCst); 152 // 正式切换上下文 153 switch_to_inner(prev_arch, next_arch); 154 } 155 156 fn switch_process_fpu(prev: &Arc<ProcessControlBlock>, next: &Arc<ProcessControlBlock>) { 157 let prev_regs = unsafe { Self::task_trapframe(prev) }; 158 let next_regs = unsafe { Self::task_trapframe(next) }; 159 if unlikely(prev_regs.status.sd()) { 160 prev.arch_info_irqsave().fp_state.save(prev_regs); 161 } 162 next.arch_info_irqsave().fp_state.restore(next_regs); 163 } 164 165 fn switch_local_context(prev: &Arc<ProcessControlBlock>, next: &Arc<ProcessControlBlock>) { 166 prev.arch_info_irqsave().local_context = *local_context().get(); 167 local_context() 168 .get_mut() 169 .restore(&next.arch_info_irqsave().local_context); 170 } 171 172 unsafe fn task_trapframe(task: &Arc<ProcessControlBlock>) -> &mut TrapFrame { 173 let mut sp = task.kernel_stack().stack_max_address().data(); 174 sp -= core::mem::size_of::<TrapFrame>(); 175 return (sp as *mut TrapFrame).as_mut().unwrap(); 176 } 177 } 178 179 /// 切换上下文 180 /// 181 /// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/arch/riscv/kernel/entry.S#233 182 #[naked] 183 unsafe extern "C" fn switch_to_inner(prev: *mut ArchPCBInfo, next: *mut ArchPCBInfo) { 184 core::arch::asm!(concat!( 185 " 186 sd ra, {off_ra}(a0) 187 sd sp, {off_sp}(a0) 188 sd s0, {off_s0}(a0) 189 sd s1, {off_s1}(a0) 190 sd s2, {off_s2}(a0) 191 sd s3, {off_s3}(a0) 192 sd s4, {off_s4}(a0) 193 sd s5, {off_s5}(a0) 194 sd s6, {off_s6}(a0) 195 sd s7, {off_s7}(a0) 196 sd s8, {off_s8}(a0) 197 sd s9, {off_s9}(a0) 198 sd s10, {off_s10}(a0) 199 sd s11, {off_s11}(a0) 200 201 202 ld sp, {off_sp}(a1) 203 ld s0, {off_s0}(a1) 204 ld s1, {off_s1}(a1) 205 ld s2, {off_s2}(a1) 206 ld s3, {off_s3}(a1) 207 ld s4, {off_s4}(a1) 208 ld s5, {off_s5}(a1) 209 ld s6, {off_s6}(a1) 210 ld s7, {off_s7}(a1) 211 ld s8, {off_s8}(a1) 212 ld s9, {off_s9}(a1) 213 ld s10, {off_s10}(a1) 214 ld s11, {off_s11}(a1) 215 216 // 将ra设置为标签1,并跳转到before_switch_finish_hook 217 la ra, 1f 218 j {before_switch_finish_hook} 219 220 1: 221 ld sp, {off_sp}(a1) 222 ld ra, {off_ra}(a1) 223 ret 224 225 " 226 ), 227 off_ra = const(offset_of!(ArchPCBInfo, ra)), 228 off_sp = const(offset_of!(ArchPCBInfo, ksp)), 229 off_s0 = const(offset_of!(ArchPCBInfo, s0)), 230 off_s1 = const(offset_of!(ArchPCBInfo, s1)), 231 off_s2 = const(offset_of!(ArchPCBInfo, s2)), 232 off_s3 = const(offset_of!(ArchPCBInfo, s3)), 233 off_s4 = const(offset_of!(ArchPCBInfo, s4)), 234 off_s5 = const(offset_of!(ArchPCBInfo, s5)), 235 off_s6 = const(offset_of!(ArchPCBInfo, s6)), 236 off_s7 = const(offset_of!(ArchPCBInfo, s7)), 237 off_s8 = const(offset_of!(ArchPCBInfo, s8)), 238 off_s9 = const(offset_of!(ArchPCBInfo, s9)), 239 off_s10 = const(offset_of!(ArchPCBInfo, s10)), 240 off_s11 = const(offset_of!(ArchPCBInfo, s11)), 241 before_switch_finish_hook = sym before_switch_finish_hook, 242 options(noreturn)); 243 } 244 245 /// 在切换上下文完成后的钩子函数(必须在这里加一个跳转函数,否则会出现relocation truncated to fit: R_RISCV_JAL错误) 246 unsafe extern "C" fn before_switch_finish_hook() { 247 switch_finish_hook(); 248 } 249 250 impl ProcessControlBlock { 251 /// 获取当前进程的pcb 252 pub fn arch_current_pcb() -> Arc<Self> { 253 // 获取栈指针 254 let mut sp: usize; 255 unsafe { asm!("mv {}, sp", lateout(reg) sp, options(nostack)) }; 256 let ptr = VirtAddr::new(sp); 257 258 let stack_base = VirtAddr::new(ptr.data() & (!(KernelStack::ALIGN - 1))); 259 260 // 从内核栈的最低地址处取出pcb的地址 261 let p = stack_base.data() as *const *const ProcessControlBlock; 262 if core::intrinsics::unlikely((unsafe { *p }).is_null()) { 263 kerror!("p={:p}", p); 264 panic!("current_pcb is null"); 265 } 266 unsafe { 267 // 为了防止内核栈的pcb weak 指针被释放,这里需要将其包装一下 268 let weak_wrapper: ManuallyDrop<Weak<ProcessControlBlock>> = 269 ManuallyDrop::new(Weak::from_raw(*p)); 270 271 let new_arc: Arc<ProcessControlBlock> = weak_wrapper.upgrade().unwrap(); 272 return new_arc; 273 } 274 } 275 } 276 277 /// PCB中与架构相关的信息 278 #[derive(Debug, Clone, Copy)] 279 #[allow(dead_code)] 280 #[repr(C)] 281 pub struct ArchPCBInfo { 282 ra: usize, 283 ksp: usize, 284 s0: usize, 285 s1: usize, 286 s2: usize, 287 s3: usize, 288 s4: usize, 289 s5: usize, 290 s6: usize, 291 s7: usize, 292 s8: usize, 293 s9: usize, 294 s10: usize, 295 s11: usize, 296 297 fp_state: FpDExtState, 298 local_context: LocalContext, 299 } 300 301 #[allow(dead_code)] 302 impl ArchPCBInfo { 303 /// 创建一个新的ArchPCBInfo 304 /// 305 /// ## 参数 306 /// 307 /// - `kstack`:内核栈的引用 308 /// 309 /// ## 返回值 310 /// 311 /// 返回一个新的ArchPCBInfo 312 pub fn new(kstack: &KernelStack) -> Self { 313 Self { 314 ra: 0, 315 ksp: kstack.stack_max_address().data(), 316 s0: 0, 317 s1: 0, 318 s2: 0, 319 s3: 0, 320 s4: 0, 321 s5: 0, 322 s6: 0, 323 s7: 0, 324 s8: 0, 325 s9: 0, 326 s10: 0, 327 s11: 0, 328 fp_state: FpDExtState::new(), 329 local_context: LocalContext::new(ProcessorId::new(0)), 330 } 331 } 332 // ### 从另一个ArchPCBInfo处clone,但是保留部分字段不变 333 pub fn clone_from(&mut self, from: &Self) { 334 *self = from.clone(); 335 } 336 337 pub fn set_stack(&mut self, stack: VirtAddr) { 338 self.ksp = stack.data(); 339 } 340 } 341 342 #[repr(C)] 343 #[derive(Debug, Clone, Copy)] 344 struct FpDExtState { 345 f: [u64; 32], 346 fcsr: u32, 347 } 348 349 impl FpDExtState { 350 /// 创建一个新的FpState 351 const fn new() -> Self { 352 Self { 353 f: [0; 32], 354 fcsr: 0, 355 } 356 } 357 358 fn save(&mut self, regs: &mut TrapFrame) { 359 if regs.status.fs() == riscv::register::sstatus::FS::Dirty { 360 self.do_save(); 361 self.do_clean(regs); 362 } 363 } 364 365 fn restore(&mut self, regs: &mut TrapFrame) { 366 if regs.status.fs() != riscv::register::sstatus::FS::Off { 367 self.do_restore(); 368 self.do_clean(regs); 369 } 370 } 371 372 fn do_clean(&mut self, regs: &mut TrapFrame) { 373 regs.status.update_fs(riscv::register::sstatus::FS::Clean); 374 } 375 376 fn do_save(&mut self) { 377 compiler_fence(Ordering::SeqCst); 378 unsafe { 379 riscv::register::sstatus::set_fs(riscv::register::sstatus::FS::Initial); 380 asm!("frcsr {0}", lateout(reg) self.fcsr); 381 asm!(concat!( 382 " 383 // 为原来的a0寄存器的值在堆栈上分配空间 384 addi sp, sp, -8 385 sd a0, 0(sp) 386 mv a0, {0} 387 388 fsd f0, 0(a0) 389 fsd f1, 8(a0) 390 fsd f2, 16(a0) 391 fsd f3, 24(a0) 392 fsd f4, 32(a0) 393 fsd f5, 40(a0) 394 fsd f6, 48(a0) 395 fsd f7, 56(a0) 396 fsd f8, 64(a0) 397 fsd f9, 72(a0) 398 fsd f10, 80(a0) 399 fsd f11, 88(a0) 400 fsd f12, 96(a0) 401 fsd f13, 104(a0) 402 fsd f14, 112(a0) 403 fsd f15, 120(a0) 404 fsd f16, 128(a0) 405 fsd f17, 136(a0) 406 fsd f18, 144(a0) 407 fsd f19, 152(a0) 408 fsd f20, 160(a0) 409 fsd f21, 168(a0) 410 fsd f22, 176(a0) 411 fsd f23, 184(a0) 412 fsd f24, 192(a0) 413 fsd f25, 200(a0) 414 fsd f26, 208(a0) 415 fsd f27, 216(a0) 416 fsd f28, 224(a0) 417 fsd f29, 232(a0) 418 fsd f30, 240(a0) 419 fsd f31, 248(a0) 420 421 // 恢复a0寄存器的值 422 ld a0, 0(sp) 423 addi sp, sp, 8 424 " 425 ), 426 in (reg) &self.f as *const _, 427 ); 428 riscv::register::sstatus::set_fs(riscv::register::sstatus::FS::Off); 429 } 430 431 compiler_fence(Ordering::SeqCst); 432 } 433 434 fn do_restore(&mut self) { 435 compiler_fence(Ordering::SeqCst); 436 let fcsr = self.fcsr; 437 unsafe { 438 riscv::register::sstatus::set_fs(riscv::register::sstatus::FS::Initial); 439 compiler_fence(Ordering::SeqCst); 440 asm!(concat!( 441 " 442 // 为原来的a0寄存器的值在堆栈上分配空间 443 addi sp, sp, -8 444 sd a0, 0(sp) 445 mv a0, {0} 446 447 fld f0, 0(a0) 448 fld f1, 8(a0) 449 fld f2, 16(a0) 450 fld f3, 24(a0) 451 fld f4, 32(a0) 452 fld f5, 40(a0) 453 fld f6, 48(a0) 454 fld f7, 56(a0) 455 fld f8, 64(a0) 456 fld f9, 72(a0) 457 fld f10, 80(a0) 458 fld f11, 88(a0) 459 fld f12, 96(a0) 460 fld f13, 104(a0) 461 fld f14, 112(a0) 462 fld f15, 120(a0) 463 fld f16, 128(a0) 464 fld f17, 136(a0) 465 fld f18, 144(a0) 466 fld f19, 152(a0) 467 fld f20, 160(a0) 468 fld f21, 168(a0) 469 fld f22, 176(a0) 470 fld f23, 184(a0) 471 fld f24, 192(a0) 472 fld f25, 200(a0) 473 fld f26, 208(a0) 474 fld f27, 216(a0) 475 fld f28, 224(a0) 476 fld f29, 232(a0) 477 fld f30, 240(a0) 478 fld f31, 248(a0) 479 480 // 恢复a0寄存器的值 481 ld a0, 0(sp) 482 addi sp, sp, 8 483 " 484 ), 485 in (reg) &self.f as *const _, 486 ); 487 compiler_fence(Ordering::SeqCst); 488 asm!("fscsr {0}", in(reg) fcsr); 489 riscv::register::sstatus::set_fs(riscv::register::sstatus::FS::Off); 490 } 491 compiler_fence(Ordering::SeqCst); 492 } 493 } 494