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