Esempio n. 1
0
lwp_t *
cpu_switchto(lwp_t *oldlwp, lwp_t *newlwp, bool returning)
{
	struct pcb *oldpcb = oldlwp ? lwp_getpcb(oldlwp) : NULL;
	struct pcb *newpcb = lwp_getpcb(newlwp);
	struct cpu_info *ci = curcpu();
	cpu_softc_t *sc = device_private(ci->ci_dev);

#ifdef CPU_DEBUG
	thunk_printf_debug("cpu_switchto [%s,pid=%d,lid=%d] -> [%s,pid=%d,lid=%d]\n",
	    oldlwp ? oldlwp->l_name : "none",
	    oldlwp ? oldlwp->l_proc->p_pid : -1,
	    oldlwp ? oldlwp->l_lid : -1,
	    newlwp ? newlwp->l_name : "none",
	    newlwp ? newlwp->l_proc->p_pid : -1,
	    newlwp ? newlwp->l_lid : -1);
	if (oldpcb) {
		thunk_printf_debug("    oldpcb uc_link=%p, uc_stack.ss_sp=%p, "
		    "uc_stack.ss_size=%d\n",
		    oldpcb->pcb_ucp.uc_link,
		    oldpcb->pcb_ucp.uc_stack.ss_sp,
		    (int)oldpcb->pcb_ucp.uc_stack.ss_size);
	}
	if (newpcb) {
		thunk_printf_debug("    newpcb uc_link=%p, uc_stack.ss_sp=%p, "
		    "uc_stack.ss_size=%d\n",
		    newpcb->pcb_ucp.uc_link,
		    newpcb->pcb_ucp.uc_stack.ss_sp,
		    (int)newpcb->pcb_ucp.uc_stack.ss_size);
	}
#endif /* !CPU_DEBUG */

	/* create atomic switcher */
	thunk_makecontext(&sc->sc_ucp, (void (*)(void)) cpu_switchto_atomic,
			2, oldlwp, newlwp, NULL, NULL);

	KASSERT(sc);
	if (oldpcb) {
		thunk_swapcontext(&oldpcb->pcb_ucp, &sc->sc_ucp);
		/* returns here */
	} else {
		thunk_setcontext(&sc->sc_ucp);
		/* never returns */
	}

#ifdef CPU_DEBUG
	thunk_printf_debug("cpu_switchto: returning %p (was %p)\n", ci->ci_stash, oldlwp);
#endif
	return ci->ci_stash;
}
Esempio n. 2
0
void
cpu_lwp_free(struct lwp *l, int proc)
{
#ifdef CPU_DEBUG
	thunk_printf_debug("cpu_lwp_free (dummy)\n");
#endif
}
Esempio n. 3
0
void
cpu_dumpconf(void)
{
#ifdef CPU_DEBUG
	thunk_printf_debug("cpu_dumpconf\n");
#endif
}
Esempio n. 4
0
int
cpu_setmcontext(struct lwp *l, const mcontext_t *mcp, unsigned int flags)
{
	struct pcb *pcb = lwp_getpcb(l);
	ucontext_t *ucp = &pcb->pcb_userret_ucp;

#ifdef CPU_DEBUG
	thunk_printf_debug("cpu_setmcontext\n");
#endif
	memcpy(&ucp->uc_mcontext, mcp, sizeof(mcontext_t));
	return 0;
}
Esempio n. 5
0
static void
cpu_lwp_trampoline(ucontext_t *ucp, void (*func)(void *), void *arg)
{
#ifdef CPU_DEBUG
	thunk_printf_debug("cpu_lwp_trampoline called with func %p, arg %p\n", (void *) func, arg);
#endif
	/* init lwp */
	lwp_startup(curcpu()->ci_stash, curlwp);

	/* actual jump */
	thunk_makecontext(ucp, (void (*)(void)) func, 1, arg, NULL, NULL, NULL);
	thunk_setcontext(ucp);
}
Esempio n. 6
0
void
cpu_lwp_free2(struct lwp *l)
{
	struct pcb *pcb = lwp_getpcb(l);

#ifdef CPU_DEBUG
	thunk_printf_debug("cpu_lwp_free2\n");
#endif

	if (pcb == NULL)
		return;
	/* XXX nothing to do? */
}
Esempio n. 7
0
void
cpu_lwp_fork(struct lwp *l1, struct lwp *l2, void *stack, size_t stacksize,
    void (*func)(void *), void *arg)
{
	struct pcb *pcb1 = lwp_getpcb(l1);
	struct pcb *pcb2 = lwp_getpcb(l2);

#ifdef CPU_DEBUG
	thunk_printf_debug("cpu_lwp_fork [%s/%p] -> [%s/%p] stack=%p stacksize=%d\n",
	    l1 ? l1->l_name : "none", l1,
	    l2 ? l2->l_name : "none", l2,
	    stack, (int)stacksize);
#endif

	if (stack)
		panic("%s: stack passed, can't handle\n", __func__);

	/* copy the PCB and its switchframes from parent */
	memcpy(pcb2, pcb1, sizeof(struct pcb));

	/* refresh context */
	if (thunk_getcontext(&pcb2->pcb_ucp))
		panic("getcontext failed");

	/* recalculate the system stack top */
	pcb2->sys_stack_top = pcb2->sys_stack + TRAPSTACKSIZE;

	/* get l2 its own stack */
	pcb2->pcb_ucp.uc_stack.ss_sp = pcb2->sys_stack;
	pcb2->pcb_ucp.uc_stack.ss_size = pcb2->sys_stack_top - pcb2->sys_stack;
	pcb2->pcb_ucp.uc_link = &pcb2->pcb_userret_ucp;

	thunk_sigemptyset(&pcb2->pcb_ucp.uc_sigmask);
	pcb2->pcb_ucp.uc_flags = _UC_STACK | _UC_CPU | _UC_SIGMASK;
	thunk_makecontext(&pcb2->pcb_ucp,
	    (void (*)(void)) cpu_lwp_trampoline,
	    3, &pcb2->pcb_ucp, func, arg, NULL);
}
Esempio n. 8
0
void
syscall(void)
{	
	lwp_t *l = curlwp;
	const struct proc * const p = l->l_proc;
	const struct sysent *callp;
	struct pcb *pcb = lwp_getpcb(l);
	ucontext_t *ucp = &pcb->pcb_userret_ucp;
	register_t copyargs[2+SYS_MAXSYSARGS];
	register_t *args;
	register_t rval[2];
	uint32_t code, opcode;
	uint nargs, argsize;
	int error;

	/* system call accounting */
	curcpu()->ci_data.cpu_nsyscall++;
	LWP_CACHE_CREDS(l, l->l_proc);

	/* XXX do we want do do emulation? */
	md_syscall_get_opcode(ucp, &opcode);
	md_syscall_get_syscallnumber(ucp, &code);
	code &= (SYS_NSYSENT -1);

	callp   = p->p_emul->e_sysent + code;
	nargs   = callp->sy_narg;
	argsize = callp->sy_argsize;

	args  = copyargs;
	rval[0] = rval[1] = 0;
	error = md_syscall_getargs(l, ucp, nargs, argsize, args);

#if 0
	aprint_debug("syscall no. %d, ", code);
	aprint_debug("nargs %d, argsize %d =>  ", nargs, argsize);
	thunk_printf_debug("syscall no. %d, ", code);
	thunk_printf_debug("nargs %d, argsize %d =>  ", nargs, argsize);
#endif

	/*
	 * TODO change the pre and post printing into functions so they can be
	 * easily adjusted and dont clobber up this space
	 */

	if (!error)
		syscall_args_print(l, code, nargs, argsize, args);

	md_syscall_inc_pc(ucp, opcode);

	if (!error) {
		error = sy_invoke(callp, l, args, rval, code);
	}

	syscall_retvals_print(l, curlwp, code, nargs, args, error, rval);

//out:
	switch (error) {
	default:
		/* fall trough */
	case 0:
		md_syscall_set_returnargs(l, ucp, error, rval);
		/* fall trough */
	case EJUSTRETURN:
		break;
	case ERESTART:
		md_syscall_dec_pc(ucp, opcode);
		/* nothing to do */
		break;
	}
	//thunk_printf_debug("end of syscall : return to userland\n");
//if (code != 4) thunk_printf("userret() code %d\n", code);
}