Module Name:    src
Committed By:   matt
Date:           Sat Sep 12 17:37:00 UTC 2009

Modified Files:
        src/sys/arch/mips/mips [matt-nb5-mips64]: mips_machdep.c
Added Files:
        src/sys/arch/mips/mips [matt-nb5-mips64]: netbsd32_machdep.c

Log Message:
Add COMPAT_NETBSD32 support.


To generate a diff of this commit:
cvs rdiff -u -r1.205.4.1.2.1.2.9 -r1.205.4.1.2.1.2.10 \
    src/sys/arch/mips/mips/mips_machdep.c
cvs rdiff -u -r0 -r1.1.2.1 src/sys/arch/mips/mips/netbsd32_machdep.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/mips/mips/mips_machdep.c
diff -u src/sys/arch/mips/mips/mips_machdep.c:1.205.4.1.2.1.2.9 src/sys/arch/mips/mips/mips_machdep.c:1.205.4.1.2.1.2.10
--- src/sys/arch/mips/mips/mips_machdep.c:1.205.4.1.2.1.2.9	Sat Sep 12 00:03:27 2009
+++ src/sys/arch/mips/mips/mips_machdep.c	Sat Sep 12 17:37:00 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: mips_machdep.c,v 1.205.4.1.2.1.2.9 2009/09/12 00:03:27 matt Exp $	*/
+/*	$NetBSD: mips_machdep.c,v 1.205.4.1.2.1.2.10 2009/09/12 17:37:00 matt Exp $	*/
 
 /*
  * Copyright 2002 Wasabi Systems, Inc.
@@ -112,9 +112,10 @@
 
 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: mips_machdep.c,v 1.205.4.1.2.1.2.9 2009/09/12 00:03:27 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mips_machdep.c,v 1.205.4.1.2.1.2.10 2009/09/12 17:37:00 matt Exp $");
 
 #include "opt_cputype.h"
+#include "opt_compat_netbsd32.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -137,8 +138,12 @@
 #include <sys/cpu.h>
 #include <sys/ucontext.h>
 
-#include <machine/kcore.h>
-#include <machine/cpu.h>
+#include <mips/kcore.h>
+#include <mips/cpu.h>
+
+#ifdef COMPAT_NETBSD32
+#include <compat/netbsd32/netbsd32.h>
+#endif
 
 #include <uvm/uvm_extern.h>
 
@@ -1847,23 +1852,43 @@
  * Start a new LWP
  */
 void
-startlwp(arg)
-	void *arg;
+startlwp(void *arg)
 {
-	int err;
 	ucontext_t *uc = arg;
-	struct lwp *l = curlwp;
+	int err;
 
-	err = cpu_setmcontext(l, &uc->uc_mcontext, uc->uc_flags);
+	err = cpu_setmcontext(curlwp, &uc->uc_mcontext, uc->uc_flags);
 #if DIAGNOSTIC
 	if (err) {
-		printf("Error %d from cpu_setmcontext.", err);
+		printf("%s: Error %d from cpu_setmcontext", __func__, err);
 	}
 #endif
 	pool_put(&lwp_uc_pool, uc);
 
-	userret(l);
+	userret(curlwp);
+}
+
+#ifdef COMPAT_NETBSD32
+/* 
+ * Start a new LWP
+ */
+void
+startlwp32(void *arg)
+{
+	ucontext32_t *uc = arg;
+	int err;
+
+	err = cpu_setmcontext32(curlwp, &uc->uc_mcontext, uc->uc_flags);
+#if DIAGNOSTIC
+	if (err) {
+		printf("%s: Error %d from cpu_setmcontext32", __func__, err);
+	}
+#endif
+	pool_put(&lwp_uc_pool, uc);
+
+	userret(curlwp);
 }
+#endif /* COMPAT_NETBSD32 */
 
 /*
  * XXX This is a terrible name.
@@ -1878,8 +1903,13 @@
 cpu_upcall(struct lwp *l, int type, int nevents, int ninterrupted,
     void *sas, void *ap, void *sp, sa_upcall_t upcall)
 {
-	struct saframe *sf, frame;
 	struct frame *f = l->l_md.md_regs;
+	struct saframe frame;
+#ifdef COMPAT_NETBSD32
+	struct saframe32 frame32;
+#endif
+	void *ksf, *usf;
+	size_t sfsz;
 
 #if 0 /* First 4 args in regs (see below). */
 	frame.sa_type = type;
@@ -1887,11 +1917,29 @@
 	frame.sa_events = nevents;
 	frame.sa_interrupted = ninterrupted;
 #endif
-	frame.sa_arg = ap;
-	frame.sa_upcall = upcall;
+#ifdef COMPAT_NETBSD32
+	switch (l->l_proc->p_md.md_abi) {
+	case _MIPS_BSD_API_O32:
+	case _MIPS_BSD_API_N32:
+		NETBSD32PTR32(frame32.sa_arg, ap);
+		NETBSD32PTR32(frame32.sa_upcall, upcall);
+		ksf = &frame32;
+		usf = (struct saframe32 *)sp - 1;
+		sfsz = sizeof(frame32);
+		break;
+	default:
+#endif
+		frame.sa_arg = ap;
+		frame.sa_upcall = upcall;
+		ksf = &frame;
+		usf = (struct saframe *)sp - 1;
+		sfsz = sizeof(frame);
+#ifdef COMPAT_NETBSD32
+		break;
+	}
+#endif
 
-	sf = (struct saframe *)sp - 1;
-	if (copyout(&frame, sf, sizeof(frame)) != 0) {
+	if (copyout(ksf, usf, sfsz) != 0) {
 		/* Copying onto the stack didn't work. Die. */
 		mutex_enter(l->l_proc->p_lock);
 		sigexit(l, SIGILL);
@@ -1899,7 +1947,7 @@
 	}
 
 	f->f_regs[_R_PC] = (intptr_t)upcall;
-	f->f_regs[_R_SP] = (intptr_t)sf;
+	f->f_regs[_R_SP] = (intptr_t)usf;
 	f->f_regs[_R_A0] = type;
 	f->f_regs[_R_A1] = (intptr_t)sas;
 	f->f_regs[_R_A2] = nevents;
@@ -1911,10 +1959,7 @@
 
 
 void
-cpu_getmcontext(l, mcp, flags)
-	struct lwp *l;
-	mcontext_t *mcp;
-	unsigned int *flags;
+cpu_getmcontext(struct lwp *l, mcontext_t *mcp, unsigned int *flags)
 {
 	const struct frame *f = l->l_md.md_regs;
 	__greg_t *gr = mcp->__gregs;
@@ -1937,6 +1982,7 @@
 
 	/* Save floating point register context, if any. */
 	if (l->l_md.md_flags & MDP_FPUSED) {
+		size_t fplen;
 		/*
 		 * If this process is the current FP owner, dump its
 		 * context to the PCB first.
@@ -1948,23 +1994,26 @@
 		 * The PCB FP regs struct includes the FP CSR, so use the
 		 * size of __fpregs.__fp_r when copying.
 		 */
-		memcpy(&mcp->__fpregs.__fp_r,
-		    &l->l_addr->u_pcb.pcb_fpregs.r_regs,
-		    sizeof(mcp->__fpregs.__fp_r));
-		mcp->__fpregs.__fp_csr = l->l_addr->u_pcb.pcb_fpregs.r_regs[32];
+#if !defined(__mips_o32)
+		if (_MIPS_SIM_NEWABI_P(l->l_proc->p_md.md_abi)) {
+			fplen = sizeof(struct fpreg);
+		} else {
+#endif
+			fplen = sizeof(struct fpreg_oabi);
+#if !defined(__mips_o32)
+		}
+#endif
+		memcpy(&mcp->__fpregs, &l->l_addr->u_pcb.pcb_fpregs, fplen);
 		*flags |= _UC_FPU;
 	}
 }
 
 int
-cpu_setmcontext(l, mcp, flags)
-	struct lwp *l;
-	const mcontext_t *mcp;
-	unsigned int flags;
+cpu_setmcontext(struct lwp *l, const mcontext_t *mcp, unsigned int flags)
 {
 	struct frame *f = l->l_md.md_regs;
-	const __greg_t *gr = mcp->__gregs;
 	struct proc *p = l->l_proc;
+	const __greg_t *gr = mcp->__gregs;
 
 	/* Restore register context, if any. */
 	if (flags & _UC_CPU) {
@@ -1982,17 +2031,25 @@
 
 	/* Restore floating point register context, if any. */
 	if (flags & _UC_FPU) {
+		size_t fplen;
 		/* Disable the FPU to fault in FP registers. */
 		f->f_regs[_R_SR] &= ~MIPS_SR_COP_1_BIT;
 		fpcurlwp = &lwp0;
 
+#if !defined(__mips_o32)
+		if (_MIPS_SIM_NEWABI_P(l->l_proc->p_md.md_abi)) {
+			fplen = sizeof(struct fpreg);
+		} else {
+#endif
+			fplen = sizeof(struct fpreg_oabi);
+#if !defined(__mips_o32)
+		}
+#endif
 		/*
 		 * The PCB FP regs struct includes the FP CSR, so use the
-		 * size of __fpregs.__fp_r when copying.
+		 * proper size of fpreg when copying.
 		 */
-		memcpy(&l->l_addr->u_pcb.pcb_fpregs.r_regs,
-		    &mcp->__fpregs.__fp_r, sizeof(mcp->__fpregs.__fp_r));
-		l->l_addr->u_pcb.pcb_fpregs.r_regs[32] = mcp->__fpregs.__fp_csr;
+		memcpy(&l->l_addr->u_pcb.pcb_fpregs, &mcp->__fpregs, fplen);
 	}
 
 	mutex_enter(p->p_lock);

Added files:

Index: src/sys/arch/mips/mips/netbsd32_machdep.c
diff -u /dev/null src/sys/arch/mips/mips/netbsd32_machdep.c:1.1.2.1
--- /dev/null	Sat Sep 12 17:37:00 2009
+++ src/sys/arch/mips/mips/netbsd32_machdep.c	Sat Sep 12 17:37:00 2009
@@ -0,0 +1,312 @@
+/*	$NetBSD: netbsd32_machdep.c,v 1.1.2.1 2009/09/12 17:37:00 matt Exp $	*/
+
+/*-
+ * Copyright (c) 2009 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas <m...@3am-software.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.1.2.1 2009/09/12 17:37:00 matt Exp $");
+
+#include "opt_compat_netbsd.h"
+#include "opt_sa.h"
+#include "opt_coredump.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/ioctl.h>
+#include <sys/exec.h>
+#include <sys/core.h>
+#include <sys/file.h>
+#include <sys/time.h>
+#include <sys/proc.h>
+#include <sys/uio.h>
+#include <sys/kernel.h>
+#include <sys/buf.h>
+#include <sys/signal.h>
+#include <sys/signalvar.h>
+#include <sys/mount.h>
+#include <sys/user.h>
+#include <sys/syscallargs.h>
+
+#include <compat/netbsd32/netbsd32.h>
+#include <compat/netbsd32/netbsd32_exec.h>
+#include <compat/netbsd32/netbsd32_syscallargs.h>
+
+#include <mips/cpu.h>
+#include <mips/cache.h>
+#include <mips/sysarch.h>
+#include <mips/cachectl.h>
+#include <mips/locore.h>
+#include <mips/frame.h>
+#include <mips/regnum.h>
+#include <mips/reg.h>
+
+#include <uvm/uvm_extern.h>
+
+char machine32[] = MACHINE;
+char machine_arch32[] = MACHINE32_ARCH;
+
+#if 0
+cpu_coredump32
+netbsd32_cpu_upcall
+netbsd32_vm_default_addr
+#endif
+
+int
+netbsd32_sysarch(struct lwp *l, const struct netbsd32_sysarch_args *uap,
+	register_t *retval)
+{
+	/* {
+		syscallarg(int) op;
+		syscallarg(netbsd32_voidp) parms;
+	} */
+	struct proc *p = l->l_proc;
+	void *parms = SCARG_P32(uap, parms);
+	int error = 0;
+
+	switch(SCARG(uap, op)) {
+	case MIPS_CACHEFLUSH: {
+		struct mips_cacheflush_args32 cfua;
+
+		error = copyin(parms, &cfua, sizeof(cfua));
+		if (error != 0)
+			return (error);
+		error =  mips_user_cacheflush(p, cfua.va, cfua.nbytes,
+		     cfua.whichcache);
+		break;
+	}
+	case MIPS_CACHECTL: {
+		struct mips_cachectl_args32 ccua;
+
+		error = copyin(parms, &ccua, sizeof(ccua));
+		if (error != 0)
+			return (error);
+		error = mips_user_cachectl(p, ccua.va, ccua.nbytes, ccua.ctl);
+		break;
+	}
+	default:
+		error = ENOSYS;
+		break;
+	}
+	return (error);
+}
+
+#ifdef COMPAT_16
+int
+compat_16_netbsd32___sigreturn14(struct lwp *l,
+	const struct compat_16_netbsd32___sigreturn14_args *uap,
+	register_t *retval)
+{
+	struct compat_16_sys___sigreturn14_args ua;
+
+	NETBSD32TOP_UAP(sigcntxp, struct sigcontext *);
+
+	return compat_16_sys___sigreturn14(l, &ua, retval);
+}
+#endif
+
+vaddr_t
+netbsd32_vm_default_addr(struct proc *p, vaddr_t base, vsize_t size)
+{
+	return VM_DEFAULT_ADDRESS32(base, size);
+}
+
+
+struct sigframe_siginfo32 {
+	siginfo32_t sf_si;
+	ucontext32_t sf_uc;
+};
+
+/*
+ * Send a signal to process.
+ */
+static void
+netbsd32_sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask)
+{
+	struct lwp * const l = curlwp;
+	struct proc * const p = l->l_proc;
+	struct sigacts * const ps = p->p_sigacts;
+	int onstack, error;
+	int sig = ksi->ksi_signo;
+	struct sigframe_siginfo32 *sfp = getframe(l, sig, &onstack);
+	struct sigframe_siginfo32 sf;
+	struct frame * const tf = l->l_md.md_regs;
+	size_t sfsz;
+	sig_t catcher = SIGACTION(p, sig).sa_handler;
+
+	sfp--;
+
+	netbsd32_si_to_si32(&sf.sf_si, (const siginfo_t *)&ksi->ksi_info);
+
+        /* Build stack frame for signal trampoline. */
+        switch (ps->sa_sigdesc[sig].sd_vers) {
+        case 0:         /* handled by sendsig_sigcontext */
+        case 1:         /* handled by sendsig_sigcontext */
+        default:        /* unknown version */
+                printf("sendsig_siginfo: bad version %d\n",
+                    ps->sa_sigdesc[sig].sd_vers);
+                sigexit(l, SIGILL);
+        case 2:
+                break;
+        }
+
+	sf.sf_uc.uc_flags = _UC_SIGMASK
+	    | ((l->l_sigstk.ss_flags & SS_ONSTACK)
+	    ? _UC_SETSTACK : _UC_CLRSTACK);
+	sf.sf_uc.uc_sigmask = *mask;
+	sf.sf_uc.uc_link = (intptr_t)l->l_ctxlink;
+	memset(&sf.sf_uc.uc_stack, 0, sizeof(sf.sf_uc.uc_stack));
+	sfsz = offsetof(struct sigframe_siginfo32, sf_uc.uc_mcontext);
+	if (p->p_md.md_abi == _MIPS_BSD_API_O32)
+		sfsz += sizeof(mcontext_o32_t);
+	else
+		sfsz += sizeof(mcontext32_t);
+	sendsig_reset(l, sig);
+	mutex_exit(p->p_lock);
+	cpu_getmcontext32(l, &sf.sf_uc.uc_mcontext, &sf.sf_uc.uc_flags);
+	error = copyout(&sf, sfp, sfsz);
+	mutex_enter(p->p_lock);
+
+	if (error != 0) {
+		/*
+		 * Process has trashed its stack; give it an illegal
+		 * instruction to halt it in its tracks.
+		 */
+		sigexit(l, SIGILL);
+		/* NOTREACHED */
+	}
+
+	/*
+	 * Set up the registers to directly invoke the signal
+	 * handler.  The return address will be set up to point
+	 * to the signal trampoline to bounce us back.
+	 */
+	tf->f_regs[_R_A0] = sig;
+	tf->f_regs[_R_A1] = (intptr_t)&sfp->sf_si;
+	tf->f_regs[_R_A2] = (intptr_t)&sfp->sf_uc;
+
+	tf->f_regs[_R_PC] = (intptr_t)catcher;
+	tf->f_regs[_R_T9] = (intptr_t)catcher;
+	tf->f_regs[_R_SP] = (intptr_t)sfp;
+	tf->f_regs[_R_RA] = (intptr_t)ps->sa_sigdesc[sig].sd_tramp;
+
+	/* Remember that we're now on the signal stack. */
+	if (onstack)
+		l->l_sigstk.ss_flags |= SS_ONSTACK;
+}
+
+void    
+netbsd32_sendsig(const ksiginfo_t *ksi, const sigset_t *mask)
+{               
+#ifdef COMPAT_16    
+	if (curproc->p_sigacts->sa_sigdesc[ksi->ksi_signo].sd_vers < 2)
+		sendsig_sigcontext(ksi, mask);
+	else    
+#endif  
+		netbsd32_sendsig_siginfo(ksi, mask);
+}       
+
+void
+cpu_getmcontext32(struct lwp *l, mcontext32_t *mc32, unsigned int *flagsp)
+{
+	mcontext_o32_t * const mco32 = (mcontext_o32_t *)mc32;
+	mcontext_t mc;
+	size_t i;
+
+	if (l->l_proc->p_md.md_abi == _MIPS_BSD_API_N32) {
+		cpu_getmcontext(l, (mcontext_t *)mc32, flagsp);
+		return;
+	}
+
+	cpu_getmcontext(l, &mc, flagsp);
+	for (i = 0; i < __arraycount(mc.__gregs); i++)
+		mco32->__gregs[i] = mc.__gregs[i];
+	if (*flagsp & _UC_FPU)
+		memcpy(&mco32->__fpregs, &mc.__fpregs,
+		    sizeof(struct fpreg_oabi));
+}
+
+int
+cpu_setmcontext32(struct lwp *l, const mcontext32_t *mc32, unsigned int flags)
+{
+	const mcontext_o32_t * const mco32 = (const mcontext_o32_t *)mc32;
+	mcontext_t mc;
+	size_t i;
+
+	if (l->l_proc->p_md.md_abi == _MIPS_BSD_API_N32)
+		return cpu_setmcontext(l, (const mcontext_t *)mc32, flags);
+
+	for (i = 0; i < __arraycount(mc.__gregs); i++)
+		mc.__gregs[i] = mco32->__gregs[i];
+	if (flags & _UC_FPU)
+		memcpy(&mc.__fpregs, &mco32->__fpregs,
+		    sizeof(struct fpreg_oabi));
+	return cpu_setmcontext(l, &mc, flags);
+}
+
+#ifdef COREDUMP
+/*
+ * Dump the machine specific segment at the start of a core dump.
+ */
+int
+cpu_coredump32(struct lwp *l, void *iocookie, struct core32 *chdr)
+{
+	int error;
+	struct coreseg cseg;
+	struct cpustate {
+		struct frame frame;
+		struct fpreg fpregs;
+	} cpustate;
+
+	if (iocookie == NULL) {
+		CORE_SETMAGIC(*chdr, COREMAGIC, MID_MACHINE, 0);
+		chdr->c_hdrsize = ALIGN(sizeof(struct core));
+		chdr->c_seghdrsize = ALIGN(sizeof(struct coreseg));
+		chdr->c_cpusize = sizeof(struct cpustate);
+		chdr->c_nseg++;
+		return 0;
+	}
+
+	if ((l->l_md.md_flags & MDP_FPUSED) && l == fpcurlwp)
+		savefpregs(l);
+	cpustate.frame = *l->l_md.md_regs;
+	cpustate.fpregs = l->l_addr->u_pcb.pcb_fpregs;
+
+	CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_MACHINE, CORE_CPU);
+	cseg.c_addr = 0;
+	cseg.c_size = chdr->c_cpusize;
+
+	error = coredump_write(iocookie, UIO_SYSSPACE, &cseg,
+	    chdr->c_seghdrsize);
+	if (error)
+		return error;
+
+	return coredump_write(iocookie, UIO_SYSSPACE, &cpustate,
+	    chdr->c_cpusize);
+}
+#endif

Reply via email to