sched: implement passing arguments to user-mode threads
This commit is contained in:
@@ -1,6 +1,14 @@
|
||||
#include <kernel/machine/cpu.h>
|
||||
#include <kernel/machine/thread.h>
|
||||
|
||||
#define MAX_REG_ARGS 6
|
||||
#define REG_ARG_0 rdi
|
||||
#define REG_ARG_1 rsi
|
||||
#define REG_ARG_2 rdx
|
||||
#define REG_ARG_3 rcx
|
||||
#define REG_ARG_4 r8
|
||||
#define REG_ARG_5 r9
|
||||
|
||||
/* 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. */
|
||||
@@ -23,10 +31,12 @@ void ml_thread_prepare_kernel_context(uintptr_t ip, uintptr_t *sp)
|
||||
ctx->rfl = 0x202;
|
||||
}
|
||||
|
||||
extern void ml_thread_prepare_user_context(
|
||||
extern kern_status_t ml_thread_prepare_user_context(
|
||||
virt_addr_t ip,
|
||||
virt_addr_t user_sp,
|
||||
virt_addr_t *kernel_sp)
|
||||
virt_addr_t *kernel_sp,
|
||||
const uintptr_t *args,
|
||||
size_t nr_args)
|
||||
{
|
||||
(*kernel_sp) -= sizeof(struct ml_cpu_context);
|
||||
|
||||
@@ -39,4 +49,31 @@ extern void ml_thread_prepare_user_context(
|
||||
ctx->rflags = 0x202;
|
||||
ctx->rdi = 0; // arg 0
|
||||
ctx->rsi = 0; // arg 1
|
||||
|
||||
for (size_t i = 0; i < nr_args; i++) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
ctx->REG_ARG_0 = args[i];
|
||||
break;
|
||||
case 1:
|
||||
ctx->REG_ARG_1 = args[i];
|
||||
break;
|
||||
case 2:
|
||||
ctx->REG_ARG_2 = args[i];
|
||||
break;
|
||||
case 3:
|
||||
ctx->REG_ARG_3 = args[i];
|
||||
break;
|
||||
case 4:
|
||||
ctx->REG_ARG_4 = args[i];
|
||||
break;
|
||||
case 5:
|
||||
ctx->REG_ARG_5 = args[i];
|
||||
break;
|
||||
default:
|
||||
return KERN_INVALID_ARGUMENT;
|
||||
}
|
||||
}
|
||||
|
||||
return KERN_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user