mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 08:57:35 +00:00
Kernel/aarch64: Implement thread_context_first_enter
This requires two new functions, context_first_init and restore_context_and_eret. With this code in place, we are now running the first idle thread! :^)
This commit is contained in:
parent
262309d9bf
commit
0b95d8cd24
2 changed files with 34 additions and 4 deletions
|
@ -24,6 +24,7 @@ namespace Kernel {
|
||||||
|
|
||||||
extern "C" void thread_context_first_enter(void);
|
extern "C" void thread_context_first_enter(void);
|
||||||
extern "C" void exit_kernel_thread(void);
|
extern "C" void exit_kernel_thread(void);
|
||||||
|
extern "C" void context_first_init(Thread* from_thread, Thread* to_thread) __attribute__((used));
|
||||||
|
|
||||||
Processor* g_current_processor;
|
Processor* g_current_processor;
|
||||||
|
|
||||||
|
@ -279,8 +280,11 @@ void Processor::check_invoke_scheduler()
|
||||||
NAKED void thread_context_first_enter(void)
|
NAKED void thread_context_first_enter(void)
|
||||||
{
|
{
|
||||||
asm(
|
asm(
|
||||||
// FIXME: Implement this
|
"ldr x0, [sp, #0] \n"
|
||||||
"wfi \n");
|
"ldr x1, [sp, #8] \n"
|
||||||
|
"add sp, sp, 24 \n"
|
||||||
|
"bl context_first_init \n"
|
||||||
|
"b restore_context_and_eret \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void exit_kernel_thread(void)
|
void exit_kernel_thread(void)
|
||||||
|
@ -288,4 +292,27 @@ void exit_kernel_thread(void)
|
||||||
Thread::current()->exit();
|
Thread::current()->exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" void context_first_init([[maybe_unused]] Thread* from_thread, [[maybe_unused]] Thread* to_thread)
|
||||||
|
{
|
||||||
|
VERIFY(!are_interrupts_enabled());
|
||||||
|
|
||||||
|
dbgln_if(CONTEXT_SWITCH_DEBUG, "switch_context <-- from {} {} to {} {} (context_first_init)", VirtualAddress(from_thread), *from_thread, VirtualAddress(to_thread), *to_thread);
|
||||||
|
|
||||||
|
VERIFY(to_thread == Thread::current());
|
||||||
|
|
||||||
|
Scheduler::enter_current(*from_thread);
|
||||||
|
|
||||||
|
auto in_critical = to_thread->saved_critical();
|
||||||
|
VERIFY(in_critical > 0);
|
||||||
|
Processor::restore_critical(in_critical);
|
||||||
|
|
||||||
|
// Since we got here and don't have Scheduler::context_switch in the
|
||||||
|
// call stack (because this is the first time we switched into this
|
||||||
|
// context), we need to notify the scheduler so that it can release
|
||||||
|
// the scheduler lock. We don't want to enable interrupts at this point
|
||||||
|
// as we're still in the middle of a context switch. Doing so could
|
||||||
|
// trigger a context switch within a context switch, leading to a crash.
|
||||||
|
Scheduler::leave_on_first_switch(InterruptsState::Disabled);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,8 +85,6 @@
|
||||||
msr elr_el1, x0
|
msr elr_el1, x0
|
||||||
ldr x0, [sp, #TPIDR_EL0_SLOT]
|
ldr x0, [sp, #TPIDR_EL0_SLOT]
|
||||||
msr tpidr_el0, x0
|
msr tpidr_el0, x0
|
||||||
ldr x0, [sp, #SP_EL0_SLOT]
|
|
||||||
msr sp_el0, x0
|
|
||||||
|
|
||||||
ldp x0, x1, [sp, #(0 * 0)]
|
ldp x0, x1, [sp, #(0 * 0)]
|
||||||
ldp x2, x3, [sp, #(2 * 8)]
|
ldp x2, x3, [sp, #(2 * 8)]
|
||||||
|
@ -186,3 +184,8 @@ system_error_current_elsp_el0:
|
||||||
bl exception_common
|
bl exception_common
|
||||||
restore_previous_context
|
restore_previous_context
|
||||||
eret
|
eret
|
||||||
|
|
||||||
|
.global restore_context_and_eret
|
||||||
|
restore_context_and_eret:
|
||||||
|
restore_previous_context
|
||||||
|
eret
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue