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 kdebug, 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 kdebug!( 131 "riscv switch process: prev: {:?}, next: {:?}", 132 prev.pid(), 133 next.pid() 134 ); 135 Self::switch_process_fpu(&prev, &next); 136 kdebug!("riscv switch process: after switch_process_fpu"); 137 Self::switch_local_context(&prev, &next); 138 kdebug!("riscv switch process: after switch_local_context"); 139 140 // 切换地址空间 141 let next_addr_space = next.basic().user_vm().as_ref().unwrap().clone(); 142 compiler_fence(Ordering::SeqCst); 143 144 next_addr_space.read().user_mapper.utable.make_current(); 145 kdebug!("riscv switch process: after switch addr space"); 146 drop(next_addr_space); 147 compiler_fence(Ordering::SeqCst); 148 149 // 获取arch info的锁,并强制泄露其守卫(切换上下文后,在switch_finish_hook中会释放锁) 150 let next_arch = SpinLockGuard::leak(next.arch_info_irqsave()) as *mut ArchPCBInfo; 151 let prev_arch = SpinLockGuard::leak(prev.arch_info_irqsave()) as *mut ArchPCBInfo; 152 153 // 恢复当前的 preempt count*2 154 ProcessManager::current_pcb().preempt_enable(); 155 ProcessManager::current_pcb().preempt_enable(); 156 PROCESS_SWITCH_RESULT.as_mut().unwrap().get_mut().prev_pcb = Some(prev); 157 PROCESS_SWITCH_RESULT.as_mut().unwrap().get_mut().next_pcb = Some(next); 158 kdebug!("riscv switch process: before to inner"); 159 compiler_fence(Ordering::SeqCst); 160 // 正式切换上下文 161 switch_to_inner(prev_arch, next_arch); 162 } 163 164 fn switch_process_fpu(prev: &Arc<ProcessControlBlock>, next: &Arc<ProcessControlBlock>) { 165 let prev_regs = unsafe { Self::task_trapframe(prev) }; 166 let next_regs = unsafe { Self::task_trapframe(next) }; 167 if unlikely(prev_regs.status.sd()) { 168 prev.arch_info_irqsave().fp_state.save(prev_regs); 169 } 170 next.arch_info_irqsave().fp_state.restore(next_regs); 171 } 172 173 fn switch_local_context(prev: &Arc<ProcessControlBlock>, next: &Arc<ProcessControlBlock>) { 174 prev.arch_info_irqsave().local_context = *local_context().get(); 175 local_context() 176 .get_mut() 177 .restore(&next.arch_info_irqsave().local_context); 178 } 179 180 unsafe fn task_trapframe(task: &Arc<ProcessControlBlock>) -> &mut TrapFrame { 181 let mut sp = task.kernel_stack().stack_max_address().data(); 182 sp -= core::mem::size_of::<TrapFrame>(); 183 return (sp as *mut TrapFrame).as_mut().unwrap(); 184 } 185 } 186 187 /// 切换上下文 188 /// 189 /// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/arch/riscv/kernel/entry.S#233 190 #[naked] 191 unsafe extern "C" fn switch_to_inner(prev: *mut ArchPCBInfo, next: *mut ArchPCBInfo) { 192 core::arch::asm!(concat!( 193 " 194 sd ra, {off_ra}(a0) 195 sd sp, {off_sp}(a0) 196 sd s0, {off_s0}(a0) 197 sd s1, {off_s1}(a0) 198 sd s2, {off_s2}(a0) 199 sd s3, {off_s3}(a0) 200 sd s4, {off_s4}(a0) 201 sd s5, {off_s5}(a0) 202 sd s6, {off_s6}(a0) 203 sd s7, {off_s7}(a0) 204 sd s8, {off_s8}(a0) 205 sd s9, {off_s9}(a0) 206 sd s10, {off_s10}(a0) 207 sd s11, {off_s11}(a0) 208 209 210 ld sp, {off_sp}(a1) 211 ld s0, {off_s0}(a1) 212 ld s1, {off_s1}(a1) 213 ld s2, {off_s2}(a1) 214 ld s3, {off_s3}(a1) 215 ld s4, {off_s4}(a1) 216 ld s5, {off_s5}(a1) 217 ld s6, {off_s6}(a1) 218 ld s7, {off_s7}(a1) 219 ld s8, {off_s8}(a1) 220 ld s9, {off_s9}(a1) 221 ld s10, {off_s10}(a1) 222 ld s11, {off_s11}(a1) 223 224 // 将ra设置为标签1,并跳转到before_switch_finish_hook 225 la ra, 1f 226 j {before_switch_finish_hook} 227 228 1: 229 ld sp, {off_sp}(a1) 230 ld ra, {off_ra}(a1) 231 ret 232 233 " 234 ), 235 off_ra = const(offset_of!(ArchPCBInfo, ra)), 236 off_sp = const(offset_of!(ArchPCBInfo, ksp)), 237 off_s0 = const(offset_of!(ArchPCBInfo, s0)), 238 off_s1 = const(offset_of!(ArchPCBInfo, s1)), 239 off_s2 = const(offset_of!(ArchPCBInfo, s2)), 240 off_s3 = const(offset_of!(ArchPCBInfo, s3)), 241 off_s4 = const(offset_of!(ArchPCBInfo, s4)), 242 off_s5 = const(offset_of!(ArchPCBInfo, s5)), 243 off_s6 = const(offset_of!(ArchPCBInfo, s6)), 244 off_s7 = const(offset_of!(ArchPCBInfo, s7)), 245 off_s8 = const(offset_of!(ArchPCBInfo, s8)), 246 off_s9 = const(offset_of!(ArchPCBInfo, s9)), 247 off_s10 = const(offset_of!(ArchPCBInfo, s10)), 248 off_s11 = const(offset_of!(ArchPCBInfo, s11)), 249 before_switch_finish_hook = sym before_switch_finish_hook, 250 options(noreturn)); 251 } 252 253 /// 在切换上下文完成后的钩子函数(必须在这里加一个跳转函数,否则会出现relocation truncated to fit: R_RISCV_JAL错误) 254 unsafe extern "C" fn before_switch_finish_hook() { 255 let pcb = ProcessManager::current_pcb(); 256 kdebug!( 257 "before_switch_finish_hook, pid: {:?}, name: {:?}", 258 pcb.pid(), 259 pcb.basic().name() 260 ); 261 switch_finish_hook(); 262 kdebug!("after switch_finish_hook"); 263 } 264 265 impl ProcessControlBlock { 266 /// 获取当前进程的pcb 267 pub fn arch_current_pcb() -> Arc<Self> { 268 // 获取栈指针 269 let mut sp: usize; 270 unsafe { asm!("mv {}, sp", lateout(reg) sp, options(nostack)) }; 271 let ptr = VirtAddr::new(sp); 272 273 let stack_base = VirtAddr::new(ptr.data() & (!(KernelStack::ALIGN - 1))); 274 275 // 从内核栈的最低地址处取出pcb的地址 276 let p = stack_base.data() as *const *const ProcessControlBlock; 277 if core::intrinsics::unlikely((unsafe { *p }).is_null()) { 278 kerror!("p={:p}", p); 279 panic!("current_pcb is null"); 280 } 281 unsafe { 282 // 为了防止内核栈的pcb weak 指针被释放,这里需要将其包装一下 283 let weak_wrapper: ManuallyDrop<Weak<ProcessControlBlock>> = 284 ManuallyDrop::new(Weak::from_raw(*p)); 285 286 let new_arc: Arc<ProcessControlBlock> = weak_wrapper.upgrade().unwrap(); 287 return new_arc; 288 } 289 } 290 } 291 292 /// PCB中与架构相关的信息 293 #[derive(Debug, Clone, Copy)] 294 #[allow(dead_code)] 295 #[repr(C)] 296 pub struct ArchPCBInfo { 297 ra: usize, 298 ksp: usize, 299 s0: usize, 300 s1: usize, 301 s2: usize, 302 s3: usize, 303 s4: usize, 304 s5: usize, 305 s6: usize, 306 s7: usize, 307 s8: usize, 308 s9: usize, 309 s10: usize, 310 s11: usize, 311 312 fp_state: FpDExtState, 313 local_context: LocalContext, 314 } 315 316 #[allow(dead_code)] 317 impl ArchPCBInfo { 318 /// 创建一个新的ArchPCBInfo 319 /// 320 /// ## 参数 321 /// 322 /// - `kstack`:内核栈的引用 323 /// 324 /// ## 返回值 325 /// 326 /// 返回一个新的ArchPCBInfo 327 pub fn new(kstack: &KernelStack) -> Self { 328 Self { 329 ra: 0, 330 ksp: kstack.stack_max_address().data(), 331 s0: 0, 332 s1: 0, 333 s2: 0, 334 s3: 0, 335 s4: 0, 336 s5: 0, 337 s6: 0, 338 s7: 0, 339 s8: 0, 340 s9: 0, 341 s10: 0, 342 s11: 0, 343 fp_state: FpDExtState::new(), 344 local_context: LocalContext::new(ProcessorId::new(0)), 345 } 346 } 347 // ### 从另一个ArchPCBInfo处clone,但是保留部分字段不变 348 pub fn clone_from(&mut self, from: &Self) { 349 *self = from.clone(); 350 } 351 352 pub fn set_stack(&mut self, stack: VirtAddr) { 353 self.ksp = stack.data(); 354 } 355 } 356 357 #[repr(C)] 358 #[derive(Debug, Clone, Copy)] 359 struct FpDExtState { 360 f: [u64; 32], 361 fcsr: u32, 362 } 363 364 impl FpDExtState { 365 /// 创建一个新的FpState 366 const fn new() -> Self { 367 Self { 368 f: [0; 32], 369 fcsr: 0, 370 } 371 } 372 373 fn save(&mut self, regs: &mut TrapFrame) { 374 if regs.status.fs() == riscv::register::sstatus::FS::Dirty { 375 self.do_save(); 376 self.do_clean(regs); 377 } 378 } 379 380 fn restore(&mut self, regs: &mut TrapFrame) { 381 if regs.status.fs() != riscv::register::sstatus::FS::Off { 382 self.do_restore(); 383 self.do_clean(regs); 384 } 385 } 386 387 fn do_clean(&mut self, regs: &mut TrapFrame) { 388 regs.status.update_fs(riscv::register::sstatus::FS::Clean); 389 } 390 391 fn do_save(&mut self) { 392 compiler_fence(Ordering::SeqCst); 393 unsafe { 394 riscv::register::sstatus::set_fs(riscv::register::sstatus::FS::Initial); 395 asm!("frcsr {0}", lateout(reg) self.fcsr); 396 asm!(concat!( 397 " 398 // 为原来的a0寄存器的值在堆栈上分配空间 399 addi sp, sp, -8 400 sd a0, 0(sp) 401 mv a0, {0} 402 403 fsd f0, 0(a0) 404 fsd f1, 8(a0) 405 fsd f2, 16(a0) 406 fsd f3, 24(a0) 407 fsd f4, 32(a0) 408 fsd f5, 40(a0) 409 fsd f6, 48(a0) 410 fsd f7, 56(a0) 411 fsd f8, 64(a0) 412 fsd f9, 72(a0) 413 fsd f10, 80(a0) 414 fsd f11, 88(a0) 415 fsd f12, 96(a0) 416 fsd f13, 104(a0) 417 fsd f14, 112(a0) 418 fsd f15, 120(a0) 419 fsd f16, 128(a0) 420 fsd f17, 136(a0) 421 fsd f18, 144(a0) 422 fsd f19, 152(a0) 423 fsd f20, 160(a0) 424 fsd f21, 168(a0) 425 fsd f22, 176(a0) 426 fsd f23, 184(a0) 427 fsd f24, 192(a0) 428 fsd f25, 200(a0) 429 fsd f26, 208(a0) 430 fsd f27, 216(a0) 431 fsd f28, 224(a0) 432 fsd f29, 232(a0) 433 fsd f30, 240(a0) 434 fsd f31, 248(a0) 435 436 // 恢复a0寄存器的值 437 ld a0, 0(sp) 438 addi sp, sp, 8 439 " 440 ), 441 in (reg) &self.f as *const _, 442 ); 443 riscv::register::sstatus::set_fs(riscv::register::sstatus::FS::Off); 444 } 445 446 compiler_fence(Ordering::SeqCst); 447 } 448 449 fn do_restore(&mut self) { 450 compiler_fence(Ordering::SeqCst); 451 let fcsr = self.fcsr; 452 unsafe { 453 riscv::register::sstatus::set_fs(riscv::register::sstatus::FS::Initial); 454 compiler_fence(Ordering::SeqCst); 455 asm!(concat!( 456 " 457 // 为原来的a0寄存器的值在堆栈上分配空间 458 addi sp, sp, -8 459 sd a0, 0(sp) 460 mv a0, {0} 461 462 fld f0, 0(a0) 463 fld f1, 8(a0) 464 fld f2, 16(a0) 465 fld f3, 24(a0) 466 fld f4, 32(a0) 467 fld f5, 40(a0) 468 fld f6, 48(a0) 469 fld f7, 56(a0) 470 fld f8, 64(a0) 471 fld f9, 72(a0) 472 fld f10, 80(a0) 473 fld f11, 88(a0) 474 fld f12, 96(a0) 475 fld f13, 104(a0) 476 fld f14, 112(a0) 477 fld f15, 120(a0) 478 fld f16, 128(a0) 479 fld f17, 136(a0) 480 fld f18, 144(a0) 481 fld f19, 152(a0) 482 fld f20, 160(a0) 483 fld f21, 168(a0) 484 fld f22, 176(a0) 485 fld f23, 184(a0) 486 fld f24, 192(a0) 487 fld f25, 200(a0) 488 fld f26, 208(a0) 489 fld f27, 216(a0) 490 fld f28, 224(a0) 491 fld f29, 232(a0) 492 fld f30, 240(a0) 493 fld f31, 248(a0) 494 495 // 恢复a0寄存器的值 496 ld a0, 0(sp) 497 addi sp, sp, 8 498 " 499 ), 500 in (reg) &self.f as *const _, 501 ); 502 compiler_fence(Ordering::SeqCst); 503 asm!("fscsr {0}", in(reg) fcsr); 504 riscv::register::sstatus::set_fs(riscv::register::sstatus::FS::Off); 505 } 506 compiler_fence(Ordering::SeqCst); 507 } 508 } 509