@@ -198,9 +198,136 @@ void ProcessorBase<T>::initialize_context_switching(Thread& initial_thread)
198
198
}
199
199
200
200
template <typename T>
201
- void ProcessorBase<T>::switch_context(Thread*&, Thread*&)
201
+ void ProcessorBase<T>::switch_context(Thread*& from_thread , Thread*& to_thread )
202
202
{
203
- TODO_RISCV64 ();
203
+ VERIFY (!m_in_irq);
204
+ VERIFY (m_in_critical == 1 );
205
+
206
+ dbgln_if (CONTEXT_SWITCH_DEBUG, " switch_context --> switching out of: {} {}" , VirtualAddress (from_thread), *from_thread);
207
+
208
+ // m_in_critical is restored in enter_thread_context
209
+ from_thread->save_critical (m_in_critical);
210
+
211
+ // clang-format off
212
+ asm volatile (
213
+ // Store a RegisterState of from_thread on from_thread's stack
214
+ " addi sp, sp, -(34 * 8) \n "
215
+
216
+ " sd x1, 0*8(sp) \n "
217
+ // sp
218
+ " sd x3, 2*8(sp) \n "
219
+ " sd x4, 3*8(sp) \n "
220
+ " sd x5, 4*8(sp) \n "
221
+ " sd x6, 5*8(sp) \n "
222
+ " sd x7, 6*8(sp) \n "
223
+ " sd x8, 7*8(sp) \n "
224
+ " sd x9, 8*8(sp) \n "
225
+ " sd x10, 9*8(sp) \n "
226
+ " sd x11, 10*8(sp) \n "
227
+ " sd x12, 11*8(sp) \n "
228
+ " sd x13, 12*8(sp) \n "
229
+ " sd x14, 13*8(sp) \n "
230
+ " sd x15, 14*8(sp) \n "
231
+ " sd x16, 15*8(sp) \n "
232
+ " sd x17, 16*8(sp) \n "
233
+ " sd x18, 17*8(sp) \n "
234
+ " sd x19, 18*8(sp) \n "
235
+ " sd x20, 19*8(sp) \n "
236
+ " sd x21, 20*8(sp) \n "
237
+ " sd x22, 21*8(sp) \n "
238
+ " sd x23, 22*8(sp) \n "
239
+ " sd x24, 23*8(sp) \n "
240
+ " sd x25, 24*8(sp) \n "
241
+ " sd x26, 25*8(sp) \n "
242
+ " sd x27, 26*8(sp) \n "
243
+ " sd x28, 27*8(sp) \n "
244
+ " sd x29, 28*8(sp) \n "
245
+ " sd x30, 29*8(sp) \n "
246
+ " sd x31, 30*8(sp) \n "
247
+
248
+ // Store current sp as from_thread's sp.
249
+ " sd sp, %[from_sp] \n "
250
+
251
+ // Set from_thread's pc to label "1"
252
+ " la t0, 1f \n "
253
+ " sd t0, %[from_ip] \n "
254
+
255
+ // Switch to to_thread's stack
256
+ " ld sp, %[to_sp] \n "
257
+
258
+ // Store from_thread, to_thread, to_ip on to_thread's stack
259
+ " addi sp, sp, -(4 * 8) \n "
260
+ " ld a0, %[from_thread] \n "
261
+ " sd a0, 0*8(sp) \n "
262
+ " ld a1, %[to_thread] \n "
263
+ " sd a1, 1*8(sp) \n "
264
+ " ld s1, %[to_ip] \n "
265
+ " sd s1, 2*8(sp) \n "
266
+
267
+ // enter_thread_context(from_thread, to_thread)
268
+ " call enter_thread_context \n "
269
+
270
+ // Jump to to_ip
271
+ " jr s1 \n "
272
+
273
+ // A thread enters here when they were already scheduled at least once
274
+ " 1: \n "
275
+ " addi sp, sp, (4 * 8) \n "
276
+
277
+ // Restore the RegisterState of to_thread
278
+ " ld x1, 0*8(sp) \n "
279
+ // sp
280
+ " ld x3, 2*8(sp) \n "
281
+ " ld x4, 3*8(sp) \n "
282
+ " ld x5, 4*8(sp) \n "
283
+ " ld x6, 5*8(sp) \n "
284
+ " ld x7, 6*8(sp) \n "
285
+ " ld x8, 7*8(sp) \n "
286
+ " ld x9, 8*8(sp) \n "
287
+ " ld x10, 9*8(sp) \n "
288
+ " ld x11, 10*8(sp) \n "
289
+ " ld x12, 11*8(sp) \n "
290
+ " ld x13, 12*8(sp) \n "
291
+ " ld x14, 13*8(sp) \n "
292
+ " ld x15, 14*8(sp) \n "
293
+ " ld x16, 15*8(sp) \n "
294
+ " ld x17, 16*8(sp) \n "
295
+ " ld x18, 17*8(sp) \n "
296
+ " ld x19, 18*8(sp) \n "
297
+ " ld x20, 19*8(sp) \n "
298
+ " ld x21, 20*8(sp) \n "
299
+ " ld x22, 21*8(sp) \n "
300
+ " ld x23, 22*8(sp) \n "
301
+ " ld x24, 23*8(sp) \n "
302
+ " ld x25, 24*8(sp) \n "
303
+ " ld x26, 25*8(sp) \n "
304
+ " ld x27, 26*8(sp) \n "
305
+ " ld x28, 27*8(sp) \n "
306
+ " ld x29, 28*8(sp) \n "
307
+ " ld x30, 29*8(sp) \n "
308
+ " ld x31, 30*8(sp) \n "
309
+
310
+ " addi sp, sp, -(4 * 8) \n "
311
+ " ld t0, 0*8(sp) \n "
312
+ " sd t0, %[from_thread] \n "
313
+ " ld t0, 1*8(sp) \n "
314
+ " sd t0, %[to_thread] \n "
315
+
316
+ " addi sp, sp, (34 * 8) + (4 * 8) \n "
317
+ :
318
+ [from_ip] " =m" (from_thread->regs ().pc ),
319
+ [from_sp] " =m" (from_thread->regs ().x [1 ]),
320
+ " =m" (from_thread),
321
+ " =m" (to_thread)
322
+
323
+ : [to_ip] " m" (to_thread->regs ().pc ),
324
+ [to_sp] " m" (to_thread->regs ().x [1 ]),
325
+ [from_thread] " m" (from_thread),
326
+ [to_thread] " m" (to_thread)
327
+ : " memory" , " t0" , " s1" , " a0" , " a1" );
328
+ // clang-format on
329
+
330
+ dbgln_if (CONTEXT_SWITCH_DEBUG, " switch_context <-- from {} {} to {} {}" , VirtualAddress (from_thread), *from_thread, VirtualAddress (to_thread), *to_thread);
204
331
}
205
332
206
333
extern " C" FlatPtr do_init_context (Thread*, u32 )
0 commit comments