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 KernelStack, ProcessControlBlock, ProcessFlags, ProcessManager, PROCESS_SWITCH_RESULT, 27 }, 28 smp::cpu::ProcessorId, 29 syscall::Syscall, 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,并跳转到{switch_finish_hook} 217 la ra, 1f 218 j {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 switch_finish_hook = sym crate::process::switch_finish_hook, 242 options(noreturn)); 243 } 244 245 impl ProcessControlBlock { 246 /// 获取当前进程的pcb 247 pub fn arch_current_pcb() -> Arc<Self> { 248 // 获取栈指针 249 let mut sp: usize; 250 unsafe { asm!("mv {}, sp", lateout(reg) sp, options(nostack)) }; 251 let ptr = VirtAddr::new(sp); 252 253 let stack_base = VirtAddr::new(ptr.data() & (!(KernelStack::ALIGN - 1))); 254 255 // 从内核栈的最低地址处取出pcb的地址 256 let p = stack_base.data() as *const *const ProcessControlBlock; 257 if core::intrinsics::unlikely((unsafe { *p }).is_null()) { 258 kerror!("p={:p}", p); 259 panic!("current_pcb is null"); 260 } 261 unsafe { 262 // 为了防止内核栈的pcb weak 指针被释放,这里需要将其包装一下 263 let weak_wrapper: ManuallyDrop<Weak<ProcessControlBlock>> = 264 ManuallyDrop::new(Weak::from_raw(*p)); 265 266 let new_arc: Arc<ProcessControlBlock> = weak_wrapper.upgrade().unwrap(); 267 return new_arc; 268 } 269 } 270 } 271 272 /// PCB中与架构相关的信息 273 #[derive(Debug, Clone, Copy)] 274 #[allow(dead_code)] 275 #[repr(C)] 276 pub struct ArchPCBInfo { 277 ra: usize, 278 ksp: usize, 279 s0: usize, 280 s1: usize, 281 s2: usize, 282 s3: usize, 283 s4: usize, 284 s5: usize, 285 s6: usize, 286 s7: usize, 287 s8: usize, 288 s9: usize, 289 s10: usize, 290 s11: usize, 291 292 fp_state: FpDExtState, 293 local_context: LocalContext, 294 } 295 296 #[allow(dead_code)] 297 impl ArchPCBInfo { 298 /// 创建一个新的ArchPCBInfo 299 /// 300 /// ## 参数 301 /// 302 /// - `kstack`:内核栈的引用 303 /// 304 /// ## 返回值 305 /// 306 /// 返回一个新的ArchPCBInfo 307 pub fn new(kstack: &KernelStack) -> Self { 308 Self { 309 ra: 0, 310 ksp: kstack.stack_max_address().data(), 311 s0: 0, 312 s1: 0, 313 s2: 0, 314 s3: 0, 315 s4: 0, 316 s5: 0, 317 s6: 0, 318 s7: 0, 319 s8: 0, 320 s9: 0, 321 s10: 0, 322 s11: 0, 323 fp_state: FpDExtState::new(), 324 local_context: LocalContext::new(ProcessorId::new(0)), 325 } 326 } 327 // ### 从另一个ArchPCBInfo处clone,但是保留部分字段不变 328 pub fn clone_from(&mut self, from: &Self) { 329 *self = from.clone(); 330 } 331 332 pub fn set_stack(&mut self, stack: VirtAddr) { 333 self.ksp = stack.data(); 334 } 335 } 336 337 #[repr(C)] 338 #[derive(Debug, Clone, Copy)] 339 struct FpDExtState { 340 f: [u64; 32], 341 fcsr: u32, 342 } 343 344 impl FpDExtState { 345 /// 创建一个新的FpState 346 const fn new() -> Self { 347 Self { 348 f: [0; 32], 349 fcsr: 0, 350 } 351 } 352 353 fn save(&mut self, regs: &mut TrapFrame) { 354 if regs.status.fs() == riscv::register::sstatus::FS::Dirty { 355 self.do_save(); 356 self.do_clean(regs); 357 } 358 } 359 360 fn restore(&mut self, regs: &mut TrapFrame) { 361 if regs.status.fs() != riscv::register::sstatus::FS::Off { 362 self.do_restore(); 363 self.do_clean(regs); 364 } 365 } 366 367 fn do_clean(&mut self, regs: &mut TrapFrame) { 368 regs.status.update_fs(riscv::register::sstatus::FS::Clean); 369 } 370 371 fn do_save(&mut self) { 372 compiler_fence(Ordering::SeqCst); 373 unsafe { 374 riscv::register::sstatus::set_fs(riscv::register::sstatus::FS::Initial); 375 asm!("frcsr {0}", lateout(reg) self.fcsr); 376 asm!(concat!( 377 " 378 fsd f0, {0} 379 fsd f1, {1} 380 fsd f2, {2} 381 fsd f3, {3} 382 fsd f4, {4} 383 fsd f5, {5} 384 fsd f6, {6} 385 fsd f7, {7} 386 fsd f8, {8} 387 fsd f9, {9} 388 fsd f10, {10} 389 fsd f11, {11} 390 fsd f12, {12} 391 fsd f13, {13} 392 fsd f14, {14} 393 fsd f15, {15} 394 fsd f16, {16} 395 fsd f17, {17} 396 fsd f18, {18} 397 fsd f19, {19} 398 fsd f20, {20} 399 fsd f21, {21} 400 fsd f22, {22} 401 fsd f23, {23} 402 fsd f24, {24} 403 fsd f25, {25} 404 fsd f26, {26} 405 fsd f27, {27} 406 fsd f28, {28} 407 fsd f29, {29} 408 fsd f30, {30} 409 fsd f31, {31} 410 " 411 ), 412 lateout(reg) self.f[0], 413 lateout(reg) self.f[1], 414 lateout(reg) self.f[2], 415 lateout(reg) self.f[3], 416 lateout(reg) self.f[4], 417 lateout(reg) self.f[5], 418 lateout(reg) self.f[6], 419 lateout(reg) self.f[7], 420 lateout(reg) self.f[8], 421 lateout(reg) self.f[9], 422 lateout(reg) self.f[10], 423 lateout(reg) self.f[11], 424 lateout(reg) self.f[12], 425 lateout(reg) self.f[13], 426 lateout(reg) self.f[14], 427 lateout(reg) self.f[15], 428 lateout(reg) self.f[16], 429 lateout(reg) self.f[17], 430 lateout(reg) self.f[18], 431 lateout(reg) self.f[19], 432 lateout(reg) self.f[20], 433 lateout(reg) self.f[21], 434 lateout(reg) self.f[22], 435 lateout(reg) self.f[23], 436 lateout(reg) self.f[24], 437 lateout(reg) self.f[25], 438 lateout(reg) self.f[26], 439 lateout(reg) self.f[27], 440 lateout(reg) self.f[28], 441 lateout(reg) self.f[29], 442 lateout(reg) self.f[30], 443 lateout(reg) self.f[31], 444 445 ); 446 riscv::register::sstatus::set_fs(riscv::register::sstatus::FS::Off); 447 } 448 449 compiler_fence(Ordering::SeqCst); 450 } 451 452 fn do_restore(&mut self) { 453 compiler_fence(Ordering::SeqCst); 454 let fcsr = self.fcsr; 455 unsafe { 456 riscv::register::sstatus::set_fs(riscv::register::sstatus::FS::Initial); 457 compiler_fence(Ordering::SeqCst); 458 asm!(concat!( 459 " 460 fld f0, {0} 461 fld f1, {1} 462 fld f2, {2} 463 fld f3, {3} 464 fld f4, {4} 465 fld f5, {5} 466 fld f6, {6} 467 fld f7, {7} 468 fld f8, {8} 469 fld f9, {9} 470 fld f10, {10} 471 fld f11, {11} 472 fld f12, {12} 473 fld f13, {13} 474 fld f14, {14} 475 fld f15, {15} 476 fld f16, {16} 477 fld f17, {17} 478 fld f18, {18} 479 fld f19, {19} 480 fld f20, {20} 481 fld f21, {21} 482 fld f22, {22} 483 fld f23, {23} 484 fld f24, {24} 485 fld f25, {25} 486 fld f26, {26} 487 fld f27, {27} 488 fld f28, {28} 489 fld f29, {29} 490 fld f30, {30} 491 fld f31, {31} 492 " 493 ), 494 in(reg) self.f[0], 495 in(reg) self.f[1], 496 in(reg) self.f[2], 497 in(reg) self.f[3], 498 in(reg) self.f[4], 499 in(reg) self.f[5], 500 in(reg) self.f[6], 501 in(reg) self.f[7], 502 in(reg) self.f[8], 503 in(reg) self.f[9], 504 in(reg) self.f[10], 505 in(reg) self.f[11], 506 in(reg) self.f[12], 507 in(reg) self.f[13], 508 in(reg) self.f[14], 509 in(reg) self.f[15], 510 in(reg) self.f[16], 511 in(reg) self.f[17], 512 in(reg) self.f[18], 513 in(reg) self.f[19], 514 in(reg) self.f[20], 515 in(reg) self.f[21], 516 in(reg) self.f[22], 517 in(reg) self.f[23], 518 in(reg) self.f[24], 519 in(reg) self.f[25], 520 in(reg) self.f[26], 521 in(reg) self.f[27], 522 in(reg) self.f[28], 523 in(reg) self.f[29], 524 in(reg) self.f[30], 525 in(reg) self.f[31], 526 ); 527 compiler_fence(Ordering::SeqCst); 528 asm!("fscsr {0}", in(reg) fcsr); 529 riscv::register::sstatus::set_fs(riscv::register::sstatus::FS::Off); 530 } 531 compiler_fence(Ordering::SeqCst); 532 } 533 } 534