diff --git a/Kernel/Arch/riscv64/Processor.cpp b/Kernel/Arch/riscv64/Processor.cpp index 9308654215..5b18e08655 100644 --- a/Kernel/Arch/riscv64/Processor.cpp +++ b/Kernel/Arch/riscv64/Processor.cpp @@ -330,15 +330,29 @@ void ProcessorBase::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); } -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 -void ProcessorBase::assume_context(Thread&, InterruptsState) +void ProcessorBase::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 @@ -505,7 +519,22 @@ NAKED void thread_context_first_enter() 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