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