2026-02-19 18:54:48 +00:00
|
|
|
#include <kernel/machine/cpu.h>
|
|
|
|
|
#include <kernel/machine/thread.h>
|
2023-04-30 14:27:57 +01:00
|
|
|
|
2026-02-08 11:58:27 +00:00
|
|
|
/* this is the context information restored by ml_thread_switch.
|
|
|
|
|
* since ml_thread_switch only jumps to kernel-mode, IRETQ isn't used,
|
|
|
|
|
* and the extra register values needed by IRETQ aren't present. */
|
2023-04-30 14:27:57 +01:00
|
|
|
struct thread_ctx {
|
|
|
|
|
uint64_t r15, r14, r13, r12, r11, r10, r9, r8;
|
|
|
|
|
uint64_t rdi, rsi, rbp, unused_rsp, rbx, rdx, rcx, rax;
|
|
|
|
|
uint64_t rfl;
|
|
|
|
|
} __packed;
|
|
|
|
|
|
2026-02-08 11:58:27 +00:00
|
|
|
void ml_thread_prepare_kernel_context(uintptr_t ip, uintptr_t *sp)
|
2023-04-30 14:27:57 +01:00
|
|
|
{
|
|
|
|
|
(*sp) -= sizeof(uintptr_t);
|
|
|
|
|
uintptr_t *dest_ip = (uintptr_t *)(*sp);
|
|
|
|
|
*dest_ip = ip;
|
|
|
|
|
|
|
|
|
|
(*sp) -= sizeof(struct thread_ctx);
|
|
|
|
|
struct thread_ctx *ctx = (struct thread_ctx *)(*sp);
|
|
|
|
|
memset(ctx, 0x0, sizeof *ctx);
|
|
|
|
|
|
|
|
|
|
ctx->rfl = 0x202;
|
|
|
|
|
}
|
2026-02-08 11:58:27 +00:00
|
|
|
|
|
|
|
|
extern void ml_thread_prepare_user_context(
|
|
|
|
|
virt_addr_t ip,
|
|
|
|
|
virt_addr_t user_sp,
|
|
|
|
|
virt_addr_t *kernel_sp)
|
|
|
|
|
{
|
|
|
|
|
(*kernel_sp) -= sizeof(struct ml_cpu_context);
|
|
|
|
|
|
|
|
|
|
struct ml_cpu_context *ctx = (struct ml_cpu_context *)(*kernel_sp);
|
|
|
|
|
ctx->rip = ip;
|
|
|
|
|
ctx->rsp = user_sp;
|
|
|
|
|
ctx->ss = 0x23;
|
|
|
|
|
ctx->cs = 0x1B;
|
|
|
|
|
ctx->rflags = 0x202;
|
|
|
|
|
ctx->rdi = 0; // arg 0
|
|
|
|
|
ctx->rsi = 0; // arg 1
|
|
|
|
|
}
|