xref: /DragonOS/kernel/src/arch/riscv64/process/mod.rs (revision 9d9a09841ce2d650a41fed776916c0a11d52f92e)
1 use core::{arch::asm, mem::ManuallyDrop};
2 
3 use alloc::{
4     string::String,
5     sync::{Arc, Weak},
6     vec::Vec,
7 };
8 use system_error::SystemError;
9 
10 use crate::{
11     kerror,
12     mm::VirtAddr,
13     process::{fork::KernelCloneArgs, KernelStack, ProcessControlBlock, ProcessManager},
14 };
15 
16 use super::interrupt::TrapFrame;
17 
18 pub mod idle;
19 pub mod kthread;
20 pub mod syscall;
21 
22 #[allow(dead_code)]
23 #[repr(align(32768))]
24 union InitProcUnion {
25     /// 用于存放idle进程的内核栈
26     idle_stack: [u8; 32768],
27 }
28 
29 #[link_section = ".data.init_proc_union"]
30 #[no_mangle]
31 static BSP_IDLE_STACK_SPACE: InitProcUnion = InitProcUnion {
32     idle_stack: [0; 32768],
33 };
34 
35 pub unsafe fn arch_switch_to_user(path: String, argv: Vec<String>, envp: Vec<String>) -> ! {
36     unimplemented!("RiscV64 arch_switch_to_user")
37 }
38 
39 impl ProcessManager {
40     pub fn arch_init() {
41         // do nothing
42     }
43 
44     /// fork的过程中复制线程
45     ///
46     /// 由于这个过程与具体的架构相关,所以放在这里
47     pub fn copy_thread(
48         current_pcb: &Arc<ProcessControlBlock>,
49         new_pcb: &Arc<ProcessControlBlock>,
50         clone_args: KernelCloneArgs,
51         current_trapframe: &TrapFrame,
52     ) -> Result<(), SystemError> {
53         unimplemented!("ProcessManager::copy_thread")
54     }
55 
56     /// 切换进程
57     ///
58     /// ## 参数
59     ///
60     /// - `prev`:上一个进程的pcb
61     /// - `next`:下一个进程的pcb
62     pub unsafe fn switch_process(prev: Arc<ProcessControlBlock>, next: Arc<ProcessControlBlock>) {
63         // todo: https://code.dragonos.org.cn/xref/linux-6.6.21/arch/riscv/include/asm/switch_to.h#76
64         unimplemented!("ProcessManager::switch_process")
65     }
66 }
67 
68 impl ProcessControlBlock {
69     /// 获取当前进程的pcb
70     pub fn arch_current_pcb() -> Arc<Self> {
71         // 获取栈指针
72         let mut sp: usize;
73         unsafe { asm!("mv {}, sp", lateout(reg) sp, options(nostack)) };
74         let ptr = VirtAddr::new(sp);
75 
76         let stack_base = VirtAddr::new(ptr.data() & (!(KernelStack::ALIGN - 1)));
77 
78         // 从内核栈的最低地址处取出pcb的地址
79         let p = stack_base.data() as *const *const ProcessControlBlock;
80         if core::intrinsics::unlikely((unsafe { *p }).is_null()) {
81             kerror!("p={:p}", p);
82             panic!("current_pcb is null");
83         }
84         unsafe {
85             // 为了防止内核栈的pcb weak 指针被释放,这里需要将其包装一下
86             let weak_wrapper: ManuallyDrop<Weak<ProcessControlBlock>> =
87                 ManuallyDrop::new(Weak::from_raw(*p));
88 
89             let new_arc: Arc<ProcessControlBlock> = weak_wrapper.upgrade().unwrap();
90             return new_arc;
91         }
92     }
93 }
94 
95 /// PCB中与架构相关的信息
96 #[derive(Debug)]
97 #[allow(dead_code)]
98 pub struct ArchPCBInfo {
99     // todo: add arch related fields
100 }
101 
102 #[allow(dead_code)]
103 impl ArchPCBInfo {
104     /// 创建一个新的ArchPCBInfo
105     ///
106     /// ## 参数
107     ///
108     /// - `kstack`:内核栈的引用
109     ///
110     /// ## 返回值
111     ///
112     /// 返回一个新的ArchPCBInfo
113     pub fn new(kstack: &KernelStack) -> Self {
114         Self {}
115     }
116     // ### 从另一个ArchPCBInfo处clone,但是保留部分字段不变
117     pub fn clone_from(&mut self, from: &Self) {
118         unimplemented!("ArchPCBInfo::clone_from")
119     }
120 }
121