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