77 * See the Mulan PSL v2 for more details.
88 */
99
10+ use core:: arch:: asm;
1011use core:: arch:: naked_asm;
12+ use memory_addr:: PhysAddr ;
1113use memory_addr:: VirtAddr ;
1214
15+ use super :: reg_satp:: RegSatp ;
16+
1317include_asm_marcos ! ( ) ;
1418
1519/// General registers of RISC-V.
@@ -60,6 +64,7 @@ pub struct TrapFrame {
6064 pub sepc : usize ,
6165 /// Supervisor Status Register.
6266 pub sstatus : usize ,
67+ pub sscratch : usize ,
6368}
6469
6570/// Saved hardware states of a task.
@@ -95,6 +100,7 @@ pub struct TaskContext {
95100 pub s11 : usize ,
96101
97102 pub tp : usize ,
103+ pub gp : usize ,
98104 // TODO: FP states
99105}
100106
@@ -116,21 +122,96 @@ impl TaskContext {
116122 ///
117123 /// It first saves the current task's context from CPU to this place, and then
118124 /// restores the next task's context from `next_ctx` to CPU.
119- pub fn switch_to ( & mut self , next_ctx : & Self ) {
125+ pub fn switch_to ( & mut self , next_ctx : & Self , page_table_addr : PhysAddr ) {
120126 #[ cfg( feature = "tls" ) ]
121127 {
122128 self . tp = super :: read_thread_pointer ( ) ;
123129 unsafe { super :: write_thread_pointer ( next_ctx. tp ) } ;
124130 }
131+
132+ let satp = RegSatp :: gen_satp ( riscv:: register:: satp:: Mode :: Sv39 , 0 , page_table_addr. into ( ) ) ;
125133 unsafe {
126134 // TODO: switch FP states
127- context_switch ( self , next_ctx)
135+ context_switch ( self , next_ctx, satp ) ;
128136 }
129137 }
138+
139+ /// This function copy the content from src to dst,the content size is given by parameter "size"
140+ /// It's only supposed to use this function for processes stack's copying
141+ /// Not only the content of the src process's stack would be copied into dst's
142+ /// It would also save the current context of the process to src's stack
143+ ///
144+ /// # Argument
145+ /// - src: The raw pointer of the src process stack
146+ /// - dst: The raw pointer of the dst process stack
147+ /// - size: The size of the stack
148+ ///
149+ /// # Safety
150+ /// This function assumes that the parameter "size" indicate exactly the size of both stacks.
151+ /// The caller must ensure this to make safe function call.
152+ pub unsafe fn save_current_content ( & mut self , src : * const u8 , dst : * mut u8 , size : usize ) {
153+ unsafe {
154+ save_stack ( src, dst, size) ;
155+ save_current_context ( self ) ;
156+ }
157+ }
158+ }
159+
160+ #[ unsafe( naked) ]
161+ #[ allow( named_asm_labels) ]
162+ unsafe extern "C" fn save_current_context ( _current_task : & mut TaskContext ) {
163+ naked_asm ! (
164+ "
165+ sd ra,0(a0)
166+ sd sp,8(a0)
167+ sd s0,16(a0)
168+ sd s1,24(a0)
169+ sd s2,32(a0)
170+ sd s3,40(a0)
171+ sd s4,48(a0)
172+ sd s5,56(a0)
173+ sd s6,64(a0)
174+ sd s7,72(a0)
175+ sd s8,80(a0)
176+ sd s9,88(a0)
177+ sd s10,96(a0)
178+ sd s11,104(a0)
179+ sd tp,112(a0)
180+ ret
181+ "
182+ )
183+ }
184+
185+ #[ unsafe( naked) ]
186+ #[ no_mangle]
187+ #[ allow( named_asm_labels) ]
188+ // TODO: consider using SIMD instructions to copy the stack in parallel.
189+ unsafe extern "C" fn save_stack ( src : * const u8 , dst : * mut u8 , size : usize ) {
190+ // a0:src ; a1:dst ; a2:size
191+ naked_asm ! (
192+ "
193+ xor a4,a4,a4
194+ add a4,a4,a2
195+ start_copy:
196+ ld a5,0(a0)
197+ sd a5,0(a1)
198+ addi a0,a0,8
199+ addi a1,a1,8
200+ addi a4,a4,-8
201+ bnez a4,start_copy
202+ ret
203+
204+ "
205+ )
130206}
131207
132208#[ unsafe( naked) ]
133- unsafe extern "C" fn context_switch ( _current_task : & mut TaskContext , _next_task : & TaskContext ) {
209+ #[ allow( named_asm_labels) ]
210+ unsafe extern "C" fn context_switch (
211+ _current_task : & mut TaskContext ,
212+ _next_task : & TaskContext ,
213+ _page_table_addr : usize ,
214+ ) {
134215 naked_asm ! (
135216 "
136217 // save old context (callee-saved registers)
@@ -149,6 +230,12 @@ unsafe extern "C" fn context_switch(_current_task: &mut TaskContext, _next_task:
149230 sd s10, 96(a0)
150231 sd s11, 104(a0)
151232
233+ csrr a3,satp
234+ csrw satp,a2
235+ xor a3,a3,a2
236+ beqz a3,set_satp_done
237+ sfence.vma
238+ set_satp_done:
152239 // restore new context
153240 ld s11, 104(a1)
154241 ld s10, 96(a1)
0 commit comments