Skip to content

Commit 7268655

Browse files
spholzADKaster
authored andcommitted
Kernel/riscv64: Implement Processor::switch_context
This code is based on the aarch64 implementation.
1 parent 494e026 commit 7268655

File tree

1 file changed

+129
-2
lines changed

1 file changed

+129
-2
lines changed

Kernel/Arch/riscv64/Processor.cpp

Lines changed: 129 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,136 @@ void ProcessorBase<T>::initialize_context_switching(Thread& initial_thread)
198198
}
199199

200200
template<typename T>
201-
void ProcessorBase<T>::switch_context(Thread*&, Thread*&)
201+
void ProcessorBase<T>::switch_context(Thread*& from_thread, Thread*& to_thread)
202202
{
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);
204331
}
205332

206333
extern "C" FlatPtr do_init_context(Thread*, u32)

0 commit comments

Comments
 (0)