88 */
99
1010use core:: arch:: naked_asm;
11+ use memory_addr:: PhysAddr ;
1112use memory_addr:: VirtAddr ;
1213
14+ use super :: reg_satp:: RegSatp ;
15+
1316include_asm_marcos ! ( ) ;
1417
1518/// General registers of RISC-V.
@@ -60,6 +63,7 @@ pub struct TrapFrame {
6063 pub sepc : usize ,
6164 /// Supervisor Status Register.
6265 pub sstatus : usize ,
66+ pub sscratch : usize ,
6367}
6468
6569/// Saved hardware states of a task.
@@ -95,6 +99,7 @@ pub struct TaskContext {
9599 pub s11 : usize ,
96100
97101 pub tp : usize ,
102+ pub gp : usize ,
98103 // TODO: FP states
99104}
100105
@@ -116,21 +121,96 @@ impl TaskContext {
116121 ///
117122 /// It first saves the current task's context from CPU to this place, and then
118123 /// restores the next task's context from `next_ctx` to CPU.
119- pub fn switch_to ( & mut self , next_ctx : & Self ) {
124+ pub fn switch_to ( & mut self , next_ctx : & Self , page_table_addr : PhysAddr ) {
120125 #[ cfg( feature = "tls" ) ]
121126 {
122127 self . tp = super :: read_thread_pointer ( ) ;
123128 unsafe { super :: write_thread_pointer ( next_ctx. tp ) } ;
124129 }
130+
131+ let satp = RegSatp :: gen_satp ( riscv:: register:: satp:: Mode :: Sv39 , 0 , page_table_addr. into ( ) ) ;
125132 unsafe {
126133 // TODO: switch FP states
127- context_switch ( self , next_ctx)
134+ context_switch ( self , next_ctx, satp ) ;
128135 }
129136 }
137+
138+ /// This function copy the content from src to dst,the content size is given by parameter "size"
139+ /// It's only supposed to use this function for processes stack's copying
140+ /// Not only the content of the src process's stack would be copied into dst's
141+ /// It would also save the current context of the process to src's stack
142+ ///
143+ /// # Argument
144+ /// - src: The raw pointer of the src process stack
145+ /// - dst: The raw pointer of the dst process stack
146+ /// - size: The size of the stack
147+ ///
148+ /// # Safety
149+ /// This function assumes that the parameter "size" indicate exactly the size of both stacks.
150+ /// The caller must ensure this to make safe function call.
151+ pub unsafe fn save_current_content ( & mut self , src : * const u8 , dst : * mut u8 , size : usize ) {
152+ unsafe {
153+ save_stack ( src, dst, size) ;
154+ save_current_context ( self ) ;
155+ }
156+ }
157+ }
158+
159+ #[ unsafe( naked) ]
160+ #[ allow( named_asm_labels) ]
161+ unsafe extern "C" fn save_current_context ( _current_task : & mut TaskContext ) {
162+ naked_asm ! (
163+ "
164+ sd ra,0(a0)
165+ sd sp,8(a0)
166+ sd s0,16(a0)
167+ sd s1,24(a0)
168+ sd s2,32(a0)
169+ sd s3,40(a0)
170+ sd s4,48(a0)
171+ sd s5,56(a0)
172+ sd s6,64(a0)
173+ sd s7,72(a0)
174+ sd s8,80(a0)
175+ sd s9,88(a0)
176+ sd s10,96(a0)
177+ sd s11,104(a0)
178+ sd tp,112(a0)
179+ ret
180+ "
181+ )
182+ }
183+
184+ #[ unsafe( naked) ]
185+ #[ no_mangle]
186+ #[ allow( named_asm_labels) ]
187+ // TODO: consider using SIMD instructions to copy the stack in parallel.
188+ unsafe extern "C" fn save_stack ( src : * const u8 , dst : * mut u8 , size : usize ) {
189+ // a0:src ; a1:dst ; a2:size
190+ naked_asm ! (
191+ "
192+ xor a4,a4,a4
193+ add a4,a4,a2
194+ start_copy:
195+ ld a5,0(a0)
196+ sd a5,0(a1)
197+ addi a0,a0,8
198+ addi a1,a1,8
199+ addi a4,a4,-8
200+ bnez a4,start_copy
201+ ret
202+
203+ "
204+ )
130205}
131206
132207#[ unsafe( naked) ]
133- unsafe extern "C" fn context_switch ( _current_task : & mut TaskContext , _next_task : & TaskContext ) {
208+ #[ allow( named_asm_labels) ]
209+ unsafe extern "C" fn context_switch (
210+ _current_task : & mut TaskContext ,
211+ _next_task : & TaskContext ,
212+ _page_table_addr : usize ,
213+ ) {
134214 naked_asm ! (
135215 "
136216 // save old context (callee-saved registers)
@@ -149,6 +229,12 @@ unsafe extern "C" fn context_switch(_current_task: &mut TaskContext, _next_task:
149229 sd s10, 96(a0)
150230 sd s11, 104(a0)
151231
232+ csrr a3,satp
233+ csrw satp,a2
234+ xor a3,a3,a2
235+ beqz a3,set_satp_done
236+ sfence.vma
237+ set_satp_done:
152238 // restore new context
153239 ld s11, 104(a1)
154240 ld s10, 96(a1)
0 commit comments