xref: /DragonOS/kernel/src/arch/riscv64/process/kthread.rs (revision 1ea2daad8121b77ed704e6d7c3a09f478147441d)
1 use core::arch::asm;
2 
3 use crate::{
4     arch::{asm::csr::CSR_SSTATUS, interrupt::TrapFrame},
5     process::{
6         fork::CloneFlags,
7         kthread::{kernel_thread_bootstrap_stage2, KernelThreadCreateInfo, KernelThreadMechanism},
8         Pid, ProcessManager,
9     },
10 };
11 use alloc::sync::Arc;
12 use asm_macros::restore_from_x6_to_x31;
13 use kdepends::memoffset::offset_of;
14 use riscv::register::sstatus::SPP;
15 use system_error::SystemError;
16 
17 impl KernelThreadMechanism {
18     /// 伪造trapframe,创建内核线程
19     ///
20     /// ## 返回值
21     ///
22     /// 返回创建的内核线程的pid
23     #[inline(never)]
24     pub fn __inner_create(
25         info: &Arc<KernelThreadCreateInfo>,
26         clone_flags: CloneFlags,
27     ) -> Result<Pid, SystemError> {
28         // WARNING: If create failed, we must drop the info manually or it will cause memory leak. (refcount will not decrease when create failed)
29         let create_info: *const KernelThreadCreateInfo =
30             KernelThreadCreateInfo::generate_unsafe_arc_ptr(info.clone());
31 
32         let mut frame = TrapFrame::new();
33         frame.a2 = create_info as usize;
34 
35         // 使能中断
36         frame.status.update_sie(true);
37         frame.status.update_spp(SPP::Supervisor);
38         frame.status.update_sum(true);
39 
40         frame.ra = kernel_thread_bootstrap_stage1 as usize;
41 
42         // fork失败的话,子线程不会执行。否则将导致内存安全问题。
43         let pid = ProcessManager::fork(&frame, clone_flags).map_err(|e| {
44             unsafe { KernelThreadCreateInfo::parse_unsafe_arc_ptr(create_info) };
45             e
46         })?;
47 
48         ProcessManager::find(pid)
49             .unwrap()
50             .set_name(info.name().clone());
51 
52         return Ok(pid);
53     }
54 }
55 
56 /// 内核线程引导函数的第一阶段
57 ///
58 /// 当内核线程开始执行时,会先执行这个函数,这个函数会将伪造的trapframe中的数据弹出,然后跳转到第二阶段
59 ///
60 /// 跳转之后,指向Box<KernelThreadClosure>的指针将传入到stage2的函数
61 // #[naked]
62 // pub(super) unsafe extern "C" fn kernel_thread_bootstrap_stage1() {
63 //     todo!()
64 // }
65 #[naked]
66 pub(super) unsafe extern "C" fn kernel_thread_bootstrap_stage1() {
67     // 这个函数要是naked的,只是因为现在还没有实现,而naked func不能打`unimplemented!()`
68     // 所以先写成了普通函数
69     asm!(concat!(
70         "
71             ld x3, {off_gp}(sp)
72             ld x5, {off_t0}(sp)
73 
74         ",
75         restore_from_x6_to_x31!(),
76 
77         "
78             ld a0, {off_status}(sp)
79             csrw {csr_status}, a0
80             mv a0, a2
81             j {stage2_func}
82         "
83     ),
84         csr_status = const CSR_SSTATUS,
85         off_status = const offset_of!(TrapFrame, status),
86         off_gp = const offset_of!(TrapFrame, gp),
87         off_t0 = const offset_of!(TrapFrame, t0),
88         off_t1 = const offset_of!(TrapFrame, t1),
89         off_t2 = const offset_of!(TrapFrame, t2),
90         off_s0 = const offset_of!(TrapFrame, s0),
91         off_s1 = const offset_of!(TrapFrame, s1),
92         off_a0 = const offset_of!(TrapFrame, a0),
93         off_a1 = const offset_of!(TrapFrame, a1),
94         off_a2 = const offset_of!(TrapFrame, a2),
95         off_a3 = const offset_of!(TrapFrame, a3),
96         off_a4 = const offset_of!(TrapFrame, a4),
97         off_a5 = const offset_of!(TrapFrame, a5),
98         off_a6 = const offset_of!(TrapFrame, a6),
99         off_a7 = const offset_of!(TrapFrame, a7),
100         off_s2 = const offset_of!(TrapFrame, s2),
101         off_s3 = const offset_of!(TrapFrame, s3),
102         off_s4 = const offset_of!(TrapFrame, s4),
103         off_s5 = const offset_of!(TrapFrame, s5),
104         off_s6 = const offset_of!(TrapFrame, s6),
105         off_s7 = const offset_of!(TrapFrame, s7),
106         off_s8 = const offset_of!(TrapFrame, s8),
107         off_s9 = const offset_of!(TrapFrame, s9),
108         off_s10 = const offset_of!(TrapFrame, s10),
109         off_s11 = const offset_of!(TrapFrame, s11),
110         off_t3 = const offset_of!(TrapFrame, t3),
111         off_t4 = const offset_of!(TrapFrame, t4),
112         off_t5 = const offset_of!(TrapFrame, t5),
113         off_t6 = const offset_of!(TrapFrame, t6),
114         stage2_func = sym jump_to_stage2,
115         options(noreturn),
116     );
117 }
118 
119 fn jump_to_stage2(ptr: *const KernelThreadCreateInfo) {
120     unsafe { kernel_thread_bootstrap_stage2(ptr) };
121 }
122