Kernel/riscv64: Implement Processor::assume_context

This code is based on the aarch64 implementation.
This commit is contained in:
Sönke Holz 2024-02-06 21:04:30 +01:00 committed by Andrew Kaster
parent 726865592c
commit 1fc0c84017
Notes: sideshowbarker 2024-07-16 18:03:21 +09:00

View file

@ -330,15 +330,29 @@ void ProcessorBase<T>::switch_context(Thread*& from_thread, Thread*& to_thread)
dbgln_if(CONTEXT_SWITCH_DEBUG, "switch_context <-- from {} {} to {} {}", VirtualAddress(from_thread), *from_thread, VirtualAddress(to_thread), *to_thread); dbgln_if(CONTEXT_SWITCH_DEBUG, "switch_context <-- from {} {} to {} {}", VirtualAddress(from_thread), *from_thread, VirtualAddress(to_thread), *to_thread);
} }
extern "C" FlatPtr do_init_context(Thread*, u32) extern "C" FlatPtr do_init_context(Thread* thread, u32 new_interrupts_state)
{ {
TODO_RISCV64(); VERIFY_INTERRUPTS_DISABLED();
thread->regs().sstatus.SPIE = (new_interrupts_state == to_underlying(InterruptsState::Enabled));
return Processor::current().init_context(*thread, true);
} }
template<typename T> template<typename T>
void ProcessorBase<T>::assume_context(Thread&, InterruptsState) void ProcessorBase<T>::assume_context(Thread& thread, InterruptsState new_interrupts_state)
{ {
TODO_RISCV64(); dbgln_if(CONTEXT_SWITCH_DEBUG, "Assume context for thread {} {}", VirtualAddress(&thread), thread);
VERIFY_INTERRUPTS_DISABLED();
Scheduler::prepare_after_exec();
// in_critical() should be 2 here. The critical section in Process::exec
// and then the scheduler lock
VERIFY(Processor::in_critical() == 2);
do_assume_context(&thread, to_underlying(new_interrupts_state));
VERIFY_NOT_REACHED();
} }
template<typename T> template<typename T>
@ -505,7 +519,22 @@ NAKED void thread_context_first_enter()
NAKED void do_assume_context(Thread*, u32) NAKED void do_assume_context(Thread*, u32)
{ {
asm("unimp"); // clang-format off
asm(
"mv s1, a0 \n" // save thread ptr
// We're going to call Processor::init_context, so just make sure
// we have enough stack space so we don't stomp over it
"addi sp, sp, -" __STRINGIFY(8 + REGISTER_STATE_SIZE + TRAP_FRAME_SIZE + 8) " \n"
"call do_init_context \n"
"mv sp, a0 \n" // move stack pointer to what Processor::init_context set up for us
"mv a0, s1 \n" // to_thread
"mv a1, s1 \n" // from_thread
"addi sp, sp, -32 \n"
"sd s1, 0(sp) \n"
"sd s1, 8(sp) \n"
"la ra, thread_context_first_enter \n" // should be same as regs.sepc
"tail enter_thread_context \n");
// clang-format on
} }
template<typename T> template<typename T>