| #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) | 
 | { | 
 | } |