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 <[email protected]>.
+ *
+ * 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