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