xref: /DragonOS/kernel/src/arch/riscv64/process/kthread.rs (revision cb02d0bbc213867ac845b7e8a0fb337f723d396a)
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 
39         frame.ra = kernel_thread_bootstrap_stage1 as usize;
40 
41         // fork失败的话,子线程不会执行。否则将导致内存安全问题。
42         let pid = ProcessManager::fork(&frame, clone_flags).map_err(|e| {
43             unsafe { KernelThreadCreateInfo::parse_unsafe_arc_ptr(create_info) };
44             e
45         })?;
46 
47         ProcessManager::find(pid)
48             .unwrap()
49             .set_name(info.name().clone());
50 
51         return Ok(pid);
52     }
53 }
54 
55 /// 内核线程引导函数的第一阶段
56 ///
57 /// 当内核线程开始执行时,会先执行这个函数,这个函数会将伪造的trapframe中的数据弹出,然后跳转到第二阶段
58 ///
59 /// 跳转之后,指向Box<KernelThreadClosure>的指针将传入到stage2的函数
60 // #[naked]
61 // pub(super) unsafe extern "C" fn kernel_thread_bootstrap_stage1() {
62 //     todo!()
63 // }
64 #[naked]
65 pub(super) unsafe extern "C" fn kernel_thread_bootstrap_stage1() {
66     // 这个函数要是naked的,只是因为现在还没有实现,而naked func不能打`unimplemented!()`
67     // 所以先写成了普通函数
68     asm!(concat!(
69         "
70             ld x3, {off_gp}(sp)
71             ld x5, {off_t0}(sp)
72 
73         ",
74         restore_from_x6_to_x31!(),
75 
76         "
77             ld a0, {off_status}(sp)
78             csrw {csr_status}, a0
79             mv a0, a2
80             j {stage2_func}
81         "
82     ),
83         csr_status = const CSR_SSTATUS,
84         off_status = const offset_of!(TrapFrame, status),
85         off_gp = const offset_of!(TrapFrame, gp),
86         off_t0 = const offset_of!(TrapFrame, t0),
87         off_t1 = const offset_of!(TrapFrame, t1),
88         off_t2 = const offset_of!(TrapFrame, t2),
89         off_s0 = const offset_of!(TrapFrame, s0),
90         off_s1 = const offset_of!(TrapFrame, s1),
91         off_a0 = const offset_of!(TrapFrame, a0),
92         off_a1 = const offset_of!(TrapFrame, a1),
93         off_a2 = const offset_of!(TrapFrame, a2),
94         off_a3 = const offset_of!(TrapFrame, a3),
95         off_a4 = const offset_of!(TrapFrame, a4),
96         off_a5 = const offset_of!(TrapFrame, a5),
97         off_a6 = const offset_of!(TrapFrame, a6),
98         off_a7 = const offset_of!(TrapFrame, a7),
99         off_s2 = const offset_of!(TrapFrame, s2),
100         off_s3 = const offset_of!(TrapFrame, s3),
101         off_s4 = const offset_of!(TrapFrame, s4),
102         off_s5 = const offset_of!(TrapFrame, s5),
103         off_s6 = const offset_of!(TrapFrame, s6),
104         off_s7 = const offset_of!(TrapFrame, s7),
105         off_s8 = const offset_of!(TrapFrame, s8),
106         off_s9 = const offset_of!(TrapFrame, s9),
107         off_s10 = const offset_of!(TrapFrame, s10),
108         off_s11 = const offset_of!(TrapFrame, s11),
109         off_t3 = const offset_of!(TrapFrame, t3),
110         off_t4 = const offset_of!(TrapFrame, t4),
111         off_t5 = const offset_of!(TrapFrame, t5),
112         off_t6 = const offset_of!(TrapFrame, t6),
113         stage2_func = sym jump_to_stage2,
114         options(noreturn),
115     );
116 }
117 
118 fn jump_to_stage2(ptr: *const KernelThreadCreateInfo) {
119     unsafe { kernel_thread_bootstrap_stage2(ptr) };
120 }
121