Ejemplo n.º 1
0
/*
 * Functions for entering user mode.
 *
 * This should not be used by threads returning from traps - they
 * should just return from mips_trap(). It should be used by threads
 * entering user mode for the first time - whether the child thread in
 * a fork(), or into a brand-new address space after exec(), or when
 * starting the first userlevel program.
 *
 * mips_usermode is the common code. It should not be called outside
 * the mips port.
 *
 * md_usermode is meant for use in exec and equivalent.
 * md_forkentry, in syscall.c, is meant for use in fork.
 */
void
mips_usermode(struct trapframe *tf)
{

	/*
	 * Interrupts should be off within the kernel while entering
	 * usermode. However, while in usermode, interrupts should be
	 * on. To interact properly with the spl-handling logic above,
	 * we call splhigh() to disable interrupts, but set curspl
	 * explicitly to 0.
	 */
	splhigh();
	curspl = 0;

	/*
	 * This assertion will fail if either
	 *   (1) curkstack is corrupted, or
	 *   (2) the trap frame is not on our own kernel stack.
	 *
	 * If curkstack is corrupted, the next trap back to the kernel
	 * will (most likely) hang the system, so it's better to find
	 * out now.
	 *
	 * It's necessary for the trap frame used here to be on the
	 * current thread's own stack. It cannot correctly be on either
	 * another thread's stack or in the kernel heap. (Why?)
	 */
	assert(SAME_STACK(curkstack-1, (vaddr_t)tf));

	/*
	 * This actually does it. See exception.S.
	 */
	asm_usermode(tf);
}
Ejemplo n.º 2
0
/*
 * Functions for entering user mode.
 *
 * This should not be used by threads returning from traps - they
 * should just return from mips_trap(). It should be used by threads
 * entering user mode for the first time - whether the child thread in
 * a fork(), or into a brand-new address space after exec(), or when
 * starting the first userlevel program.
 *
 * mips_usermode is the common code. It should not be called outside
 * the mips port.
 *
 * md_usermode is meant for use in exec and equivalent.
 * md_forkentry, in syscall.c, is meant for use in fork.
 */
void
mips_usermode(struct trapframe *tf)
{

	/*
	 * Interrupts should be off within the kernel while entering
	 * usermode. However, while in usermode, interrupts should be
	 * on. To interact properly with the spl-handling logic above,
	 * we call splhigh() to disable interrupts, but set curspl
	 * explicitly to 0.
	 */
	splhigh();
	curspl = 0;

	/*
	 * If curkstack is wrong, chances are the first trap back to
	 * the kernel will hang the system. So make sure it's something
	 * near correct.
	 *
	 * This test assumes that tf is on our own thread stack, but
	 * that's more or less necessary anyway.
	 */
	assert(((curkstack-1) & 0xffffe000)==(((u_int32_t)tf) & 0xffffe000));

	/*
	 * This actually does it. See exception.S.
	 */
	asm_usermode(tf);
}
Ejemplo n.º 3
0
Archivo: trap.c Proyecto: rootid/os161
/*
 * Function for entering user mode.
 *
 * This should not be used by threads returning from traps - they
 * should just return from mips_trap(). It should be used by threads
 * entering user mode for the first time - whether the child thread in
 * a fork(), or into a brand-new address space after exec(), or when
 * starting the first userlevel program.
 *
 * It works by jumping into the exception return code.
 *
 * mips_usermode is common code for this. It cannot usefully be called
 * outside the mips port, but should be called from one of the
 * following places:
 *    - enter_new_process, for use by exec and equivalent.
 *    - enter_forked_process, in syscall.c, for use by fork.
 */
void
mips_usermode(struct trapframe *tf)
{

	/*
	 * Interrupts should be off within the kernel while entering
	 * user mode. However, while in user mode, interrupts should
	 * be on. To interact properly with the spl-handling logic
	 * above, we explicitly call spl0() and then call cpu_irqoff().
	 */
	spl0();
	cpu_irqoff();

	cputhreads[curcpu->c_number] = (vaddr_t)curthread;
	cpustacks[curcpu->c_number] = (vaddr_t)curthread->t_stack + STACK_SIZE;

	/*
	 * This assertion will fail if either
	 *   (1) cpustacks[] is corrupted, or
	 *   (2) the trap frame is not on our own kernel stack, or
	 *   (3) the boot thread tries to enter user mode.
	 *
	 * If cpustacks[] is corrupted, the next trap back to the
	 * kernel will (most likely) hang the system, so it's better
	 * to find out now.
	 *
	 * It's necessary for the trap frame used here to be on the
	 * current thread's own stack. It cannot correctly be on
	 * either another thread's stack or in the kernel heap.
	 * (Exercise: why?)
	 */
	KASSERT(((vaddr_t)tf) >= ((vaddr_t)curthread->t_stack));
	KASSERT(((vaddr_t)tf) <  ((vaddr_t)curthread->t_stack+STACK_SIZE));

	//KASSERT(SAME_STACK(cpustacks[curcpu->c_number]-1, (vaddr_t)tf));

	/*
	 * This actually does it. See exception.S.
	 */
	asm_usermode(tf);
}