blob: 2d629200360aa35cc54cf0b365962dedab782ced [file] [log] [blame]
#include <arch/arch.h>
#include <pmap.h>
#include <process.h>
#include <smp.h>
#include <trap.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
void proc_pop_ctx(struct user_context *ctx)
{
struct hw_trapframe *tf = &ctx->tf.hw_tf;
assert(ctx->type == ROS_HW_CTX);
extern void pop_hw_tf(struct hw_trapframe * tf)
__attribute__((noreturn)); /* in asm */
pop_hw_tf(tf);
}
/* TODO: consider using a SW context */
void proc_init_ctx(struct user_context *ctx, uint32_t vcoreid, uintptr_t entryp,
uintptr_t stack_top, uintptr_t tls_desc)
{
struct hw_trapframe *tf = &ctx->tf.hw_tf;
ctx->type = ROS_HW_CTX;
/* TODO: If you'd like, take tls_desc and save it in the ctx somehow, so
* that proc_pop_ctx will set up that TLS before launching. If you do
* this, you can change _start.c to not reset the TLS in userspace.
*
* This is a bigger deal on amd64, where we take a (fast) syscall to
* change the TLS desc, right after the kernel just 0'd out the TLS
* desc. If you can change your HW TLS desc with negligible overhead,
* then feel free to do whatever. Long term, it might be better to do
* whatever amd64 does. */
memset(tf, 0, sizeof(*tf));
tf->gpr[GPR_SP] = stack_top - 64;
tf->sr = SR_U64 | SR_EF;
tf->epc = entryp;
/* Coupled closely with user's entry.S. id is the vcoreid, which
* entry.S uses to determine what to do. vcoreid == 0 is the main
* core/context. */
tf->gpr[GPR_A0] = vcoreid;
}
/* TODO: handle SW and VM contexts */
void proc_secure_ctx(struct user_context *ctx)
{
struct hw_trapframe *tf = &ctx->tf.hw_tf;
ctx->type = ROS_HW_CTX;
tf->sr = SR_U64 | SR_EF;
}
/* Called when we are currently running an address space on our core and want to
* abandon it. We need a known good pgdir before releasing the old one. We
* decref, since current no longer tracks the proc (and current no longer
* protects the cr3). We also need to clear out the TLS registers (before
* unmapping the address space!) */
void __abandon_core(void)
{
struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
struct proc *old_proc;
lcr3(boot_cr3);
old_proc = pcpui->cur_proc;
pcpui->cur_proc = NULL;
proc_decref(old_proc);
}
void __clear_owning_proc(uint32_t coreid)
{
}