#include "tasking.h"
#include "memory.h"
#include "string.h"
#include "arch/cpu.h"
#define UMODE_STACK_TOP (USERLAND_MEMORY_LIMIT)
#define UMODE_STACKW PAGE_SIZE
static void*
s_umode_stack(void)
{
uintptr_t top = UMODE_STACK_TOP;
uintptr_t bottom = top - (UMODE_STACKW - 1);
vm_ensure(bottom, top, (page_flags_t) {
.present = true,
.writeable = true,
.useraccess = true,
.executable = false
});
return (void*)top;
}
static inline void*
s_stack_push(void *sp, void *data, size_t len)
{
sp = (void*)((uintptr_t)sp - len);
memcpy(sp, data, len);
return sp;
}
void
kexec(void *ip, int kargc, char **kargv, int kenvc, char **kenvp)
{
/* Allocate a page for the user stack. */
void *sp = s_umode_stack();
intmax_t argc = kargc;
sp = s_stack_push(sp, &argc, sizeof(intmax_t));
/* TODO: Proper argv, envp*/
sp = s_stack_push(sp, &kargv, sizeof(char**));
intmax_t envc = kenvc;
sp = s_stack_push(sp, &envc, sizeof(intmax_t));
sp = s_stack_push(sp, &kenvp, sizeof(char**));
umode_enter(ip, sp);
}