[Zrouter-src-freebsd] ZRouter.org: push to FreeBSD HEAD tree

zrouter-src-freebsd at zrouter.org zrouter-src-freebsd at zrouter.org
Sat Mar 3 10:26:01 UTC 2012


details:   http://zrouter.org/hg/FreeBSD/head//rev/6fd2152eeca3
changeset: 414:6fd2152eeca3
user:      ray at terran.dlink.ua
date:      Sat Mar 03 12:26:05 2012 +0200
description:
MIPS updates.

diffstat:

 head/sys/mips/cavium/octeon_machdep.c    |    5 +-
 head/sys/mips/cavium/octopci.c           |    1 -
 head/sys/mips/cavium/octopci_bus_space.c |   13 +-
 head/sys/mips/cavium/octopcivar.h        |    2 +
 head/sys/mips/conf/OCTEON1               |    6 +-
 head/sys/mips/include/elf.h              |    5 +-
 head/sys/mips/include/md_var.h           |    8 +-
 head/sys/mips/include/param.h            |    8 +-
 head/sys/mips/include/proc.h             |    3 +-
 head/sys/mips/include/reg.h              |   33 ++-
 head/sys/mips/include/sigframe.h         |   20 +-
 head/sys/mips/include/ucontext.h         |   32 +-
 head/sys/mips/include/vmparam.h          |    7 +-
 head/sys/mips/mips/bus_space_generic.c   |   13 +-
 head/sys/mips/mips/freebsd32_machdep.c   |  496 +++++++++++++++++++++++++++++++
 head/sys/mips/mips/genassym.c            |    5 +-
 head/sys/mips/mips/swtch.S               |   21 +-
 head/sys/mips/mips/trap.c                |  123 +++++--
 head/sys/mips/mips/vm_machdep.c          |   16 +-
 19 files changed, 741 insertions(+), 76 deletions(-)

diffs (1212 lines):

diff -r e8744e5a2f8e -r 6fd2152eeca3 head/sys/mips/cavium/octeon_machdep.c
--- a/head/sys/mips/cavium/octeon_machdep.c	Fri Mar 02 17:36:33 2012 +0200
+++ b/head/sys/mips/cavium/octeon_machdep.c	Sat Mar 03 12:26:05 2012 +0200
@@ -23,10 +23,10 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/mips/cavium/octeon_machdep.c 228872 2011-12-24 23:15:25Z gonzo $
+ * $FreeBSD: head/sys/mips/cavium/octeon_machdep.c 232402 2012-03-02 20:34:15Z jmallett $
  */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/mips/cavium/octeon_machdep.c 228872 2011-12-24 23:15:25Z gonzo $");
+__FBSDID("$FreeBSD: head/sys/mips/cavium/octeon_machdep.c 232402 2012-03-02 20:34:15Z jmallett $");
 
 #include <sys/param.h>
 #include <sys/conf.h>
@@ -575,6 +575,7 @@
 		octeon_bootinfo->compact_flash_common_base_addr;
 	cvmx_sysinfo_get()->compact_flash_attribute_base_addr = 
 		octeon_bootinfo->compact_flash_attribute_base_addr;
+	cvmx_sysinfo_get()->core_mask = octeon_bootinfo->core_mask;
 }
 
 static void
diff -r e8744e5a2f8e -r 6fd2152eeca3 head/sys/mips/cavium/octopci.c
--- a/head/sys/mips/cavium/octopci.c	Fri Mar 02 17:36:33 2012 +0200
+++ b/head/sys/mips/cavium/octopci.c	Sat Mar 03 12:26:05 2012 +0200
@@ -339,7 +339,6 @@
 
 	sc = device_get_softc(dev);
 
-#define PCI_CONFIG_SPACE_DELAY 10000
 	if (octeon_has_feature(OCTEON_FEATURE_PCIE)) {
 		if (bus == 0 && slot == 0 && func == 0)
 			return ((uint32_t)-1);
diff -r e8744e5a2f8e -r 6fd2152eeca3 head/sys/mips/cavium/octopci_bus_space.c
--- a/head/sys/mips/cavium/octopci_bus_space.c	Fri Mar 02 17:36:33 2012 +0200
+++ b/head/sys/mips/cavium/octopci_bus_space.c	Sat Mar 03 12:26:05 2012 +0200
@@ -69,10 +69,10 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  *	from: src/sys/alpha/include/bus.h,v 1.5 1999/08/28 00:38:40 peter
- * $FreeBSD: head/sys/mips/cavium/octopci_bus_space.c 210311 2010-07-20 19:25:11Z jmallett $
+ * $FreeBSD: head/sys/mips/cavium/octopci_bus_space.c 232410 2012-03-02 21:46:31Z jmallett $
  */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/mips/cavium/octopci_bus_space.c 210311 2010-07-20 19:25:11Z jmallett $");
+__FBSDID("$FreeBSD: head/sys/mips/cavium/octopci_bus_space.c 232410 2012-03-02 21:46:31Z jmallett $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -230,13 +230,12 @@
 }
 
 int
-octopci_bs_subregion(void *t __unused, bus_space_handle_t handle __unused,
-	      bus_size_t offset __unused, bus_size_t size __unused,
-	      bus_space_handle_t *nhandle __unused)
+octopci_bs_subregion(void *t __unused, bus_space_handle_t handle,
+	      bus_size_t offset, bus_size_t size __unused,
+	      bus_space_handle_t *bshp)
 {
 
-	printf("SUBREGION?!?!?!\n");
-	/* Do nothing */
+	*bshp = handle + offset;
 	return (0);
 }
 
diff -r e8744e5a2f8e -r 6fd2152eeca3 head/sys/mips/cavium/octopcivar.h
--- a/head/sys/mips/cavium/octopcivar.h	Fri Mar 02 17:36:33 2012 +0200
+++ b/head/sys/mips/cavium/octopcivar.h	Sat Mar 03 12:26:05 2012 +0200
@@ -28,6 +28,8 @@
 #ifndef	_MIPS_CAVIUM_OCTOPCIVAR_H
 #define	_MIPS_CAVIUM_OCTOPCIVAR_H
 
+#define PCI_CONFIG_SPACE_DELAY 1000 /* Linux use 10000 */
+
 DECLARE_BUS_SPACE_PROTOTYPES(octopci);
 
 extern bus_space_tag_t octopci_bus_space;
diff -r e8744e5a2f8e -r 6fd2152eeca3 head/sys/mips/conf/OCTEON1
--- a/head/sys/mips/conf/OCTEON1	Fri Mar 02 17:36:33 2012 +0200
+++ b/head/sys/mips/conf/OCTEON1	Sat Mar 03 12:26:05 2012 +0200
@@ -16,7 +16,7 @@
 # If you are in doubt as to the purpose or necessity of a line, check first
 # in NOTES.
 #
-# $FreeBSD: head/sys/mips/conf/OCTEON1 225482 2011-09-11 17:39:51Z brueffer $
+# $FreeBSD: head/sys/mips/conf/OCTEON1 232409 2012-03-02 21:44:39Z jmallett $
 
 ident		OCTEON1
 
@@ -268,8 +268,8 @@
 options		ATH_ENABLE_11N
 options		AH_DEBUG
 options		ATH_DEBUG
-options		AH_AR5416_INTERRUPT_MITIGATION
-options 	AH_SUPPORT_AR5416	# enable AR5416 tx/rx descriptors
+#options		AH_AR5416_INTERRUPT_MITIGATION
+#options 	AH_SUPPORT_AR5416	# enable AR5416 tx/rx descriptors
 device		ath_rate_sample	# SampleRate tx rate control for ath
 
 # Pseudo devices.
diff -r e8744e5a2f8e -r 6fd2152eeca3 head/sys/mips/include/elf.h
--- a/head/sys/mips/include/elf.h	Fri Mar 02 17:36:33 2012 +0200
+++ b/head/sys/mips/include/elf.h	Sat Mar 03 12:26:05 2012 +0200
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *	JNPR: elf.h,v 1.4 2006/12/02 09:53:40 katta
- * $FreeBSD: head/sys/mips/include/elf.h 231406 2012-02-10 19:17:14Z gonzo $
+ * $FreeBSD: head/sys/mips/include/elf.h 232449 2012-03-03 08:19:18Z jmallett $
  *
  */
 
@@ -52,6 +52,9 @@
 #include <sys/elf_generic.h>
 
 #define	ELF_ARCH	EM_MIPS
+#if __ELF_WORD_SIZE == 32
+#define	ELF_ARCH32	EM_MIPS
+#endif
 #define	ELF_MACHINE_OK(x) ((x) == EM_MIPS || (x) == EM_MIPS_RS4_BE)
 
 /* Architecture dependent Segment types - p_type */
diff -r e8744e5a2f8e -r 6fd2152eeca3 head/sys/mips/include/md_var.h
--- a/head/sys/mips/include/md_var.h	Fri Mar 02 17:36:33 2012 +0200
+++ b/head/sys/mips/include/md_var.h	Sat Mar 03 12:26:05 2012 +0200
@@ -28,7 +28,7 @@
  *
  *	from: src/sys/i386/include/md_var.h,v 1.35 2000/02/20 20:51:23 bsd
  *	JNPR: md_var.h,v 1.4 2006/10/16 12:30:34 katta
- * $FreeBSD: head/sys/mips/include/md_var.h 226517 2011-10-18 16:37:28Z jchandra $
+ * $FreeBSD: head/sys/mips/include/md_var.h 232449 2012-03-03 08:19:18Z jmallett $
  */
 
 #ifndef _MACHINE_MD_VAR_H_
@@ -41,7 +41,11 @@
  */
 extern	long	Maxmem;
 extern	char	sigcode[];
-extern	int	szsigcode, szosigcode;
+extern	int	szsigcode;
+#if defined(__mips_n32) || defined(__mips_n64)
+extern	char	sigcode32[];
+extern	int	szsigcode32;
+#endif
 extern	uint32_t *vm_page_dump;
 extern	int vm_page_dump_size;
 
diff -r e8744e5a2f8e -r 6fd2152eeca3 head/sys/mips/include/param.h
--- a/head/sys/mips/include/param.h	Fri Mar 02 17:36:33 2012 +0200
+++ b/head/sys/mips/include/param.h	Sat Mar 03 12:26:05 2012 +0200
@@ -36,7 +36,7 @@
  *	from: Utah Hdr: machparam.h 1.11 89/08/14
  *	from: @(#)param.h	8.1 (Berkeley) 6/10/93
  *	JNPR: param.h,v 1.6.2.1 2007/09/10 07:49:36 girish
- * $FreeBSD: head/sys/mips/include/param.h 226021 2011-10-04 18:06:08Z marcel $
+ * $FreeBSD: head/sys/mips/include/param.h 232449 2012-03-03 08:19:18Z jmallett $
  */
 
 #ifndef _MIPS_INCLUDE_PARAM_H_
@@ -60,6 +60,9 @@
 #if _BYTE_ORDER == _BIG_ENDIAN
 #ifdef __mips_n64
 #define	MACHINE_ARCH	"mips64eb"
+#ifndef	MACHINE_ARCH32
+#define	MACHINE_ARCH32	"mipseb"
+#endif
 #elif defined(__mips_n32)
 #define	MACHINE_ARCH	"mipsn32eb"
 #else
@@ -68,6 +71,9 @@
 #else
 #ifdef __mips_n64
 #define	MACHINE_ARCH	"mips64el"
+#ifndef	MACHINE_ARCH32
+#define	MACHINE_ARCH32	"mipsel"
+#endif
 #elif defined(__mips_n32)
 #define	MACHINE_ARCH	"mipsn32el"
 #else
diff -r e8744e5a2f8e -r 6fd2152eeca3 head/sys/mips/include/proc.h
--- a/head/sys/mips/include/proc.h	Fri Mar 02 17:36:33 2012 +0200
+++ b/head/sys/mips/include/proc.h	Sat Mar 03 12:26:05 2012 +0200
@@ -33,7 +33,7 @@
  *
  *	@(#)proc.h	8.1 (Berkeley) 6/10/93
  *	JNPR: proc.h,v 1.7.2.1 2007/09/10 06:25:24 girish
- * $FreeBSD: head/sys/mips/include/proc.h 229677 2012-01-06 01:23:26Z gonzo $
+ * $FreeBSD: head/sys/mips/include/proc.h 232449 2012-03-03 08:19:18Z jmallett $
  */
 
 #ifndef _MACHINE_PROC_H_
@@ -96,6 +96,7 @@
 
 #ifdef __mips_n64
 #define	KINFO_PROC_SIZE 1088
+#define	KINFO_PROC32_SIZE 816
 #else
 #define	KINFO_PROC_SIZE 816
 #endif
diff -r e8744e5a2f8e -r 6fd2152eeca3 head/sys/mips/include/reg.h
--- a/head/sys/mips/include/reg.h	Fri Mar 02 17:36:33 2012 +0200
+++ b/head/sys/mips/include/reg.h	Sat Mar 03 12:26:05 2012 +0200
@@ -36,12 +36,16 @@
  *	from: Utah Hdr: reg.h 1.1 90/07/09
  *	@(#)reg.h	8.2 (Berkeley) 1/11/94
  *	JNPR: reg.h,v 1.6 2006/09/15 12:52:34 katta
- * $FreeBSD$
+ * $FreeBSD: head/sys/mips/include/reg.h 232449 2012-03-03 08:19:18Z jmallett $
  */
 
 #ifndef _MACHINE_REG_H_
 #define	_MACHINE_REG_H_
 
+#if defined(_KERNEL) && !defined(KLD_MODULE) && !defined(_STANDALONE)
+#include "opt_compat.h"
+#endif
+
 /*
  * Location of the users' stored registers relative to ZERO.
  * must be visible to assembly code.
@@ -66,6 +70,21 @@
 	unsigned long junk;
 };
 
+#ifdef COMPAT_FREEBSD32
+/* Must match struct trapframe */
+struct reg32 {
+	uint32_t r_regs[NUMSAVEREGS];
+};
+
+struct fpreg32 {
+	int32_t r_regs[NUMFPREGS];
+};
+
+struct dbreg32 {
+	uint32_t junk;
+};
+#endif
+
 #ifdef _KERNEL
 int	fill_fpregs(struct thread *, struct fpreg *);
 int	fill_regs(struct thread *, struct reg *);
@@ -75,4 +94,16 @@
 int	set_dbregs(struct thread *, struct dbreg *);
 #endif
 
+#ifdef COMPAT_FREEBSD32
+struct image_params;
+
+int	fill_regs32(struct thread *, struct reg32 *);
+int	set_regs32(struct thread *, struct reg32 *);
+int	fill_fpregs32(struct thread *, struct fpreg32 *);
+int	set_fpregs32(struct thread *, struct fpreg32 *);
+
+#define	fill_dbregs32(td, reg)	0
+#define	set_dbregs32(td, reg)	0
+#endif
+
 #endif /* !_MACHINE_REG_H_ */
diff -r e8744e5a2f8e -r 6fd2152eeca3 head/sys/mips/include/sigframe.h
--- a/head/sys/mips/include/sigframe.h	Fri Mar 02 17:36:33 2012 +0200
+++ b/head/sys/mips/include/sigframe.h	Sat Mar 03 12:26:05 2012 +0200
@@ -27,11 +27,15 @@
  *
  *	from: src/sys/alpha/include/sigframe.h,v 1.1 1999/09/29 15:06:26 marcel
  *	from: sigframe.h,v 1.1 2006/08/07 05:38:57 katta
- * $FreeBSD$
+ * $FreeBSD: head/sys/mips/include/sigframe.h 232449 2012-03-03 08:19:18Z jmallett $
  */
 #ifndef _MACHINE_SIGFRAME_H_
 #define	_MACHINE_SIGFRAME_H_
 
+#if defined(_KERNEL) && !defined(KLD_MODULE) && !defined(_STANDALONE)
+#include "opt_compat.h"
+#endif
+
 /*
  * WARNING: code in locore.s assumes the layout shown for sf_signum
  * thru sf_addr so... don't alter them!
@@ -46,4 +50,18 @@
 	unsigned long	__spare__[2];
 };
 
+#if (defined(__mips_n32) || defined(__mips_n64)) && defined(COMPAT_FREEBSD32)
+#include <compat/freebsd32/freebsd32_signal.h>
+
+struct sigframe32 {
+	int32_t		sf_signum;
+	int32_t		sf_siginfo;	/* code or pointer to sf_si */
+	int32_t		sf_ucontext;	/* points to sf_uc */
+	int32_t		sf_addr;	/* undocumented 4th arg */
+	ucontext32_t	sf_uc;		/* = *sf_ucontext */
+	struct siginfo32	sf_si;	/* = *sf_siginfo (SA_SIGINFO case) */
+	uint32_t	__spare__[2];
+};
+#endif
+
 #endif /* !_MACHINE_SIGFRAME_H_ */
diff -r e8744e5a2f8e -r 6fd2152eeca3 head/sys/mips/include/ucontext.h
--- a/head/sys/mips/include/ucontext.h	Fri Mar 02 17:36:33 2012 +0200
+++ b/head/sys/mips/include/ucontext.h	Sat Mar 03 12:26:05 2012 +0200
@@ -31,7 +31,7 @@
  *
  *	@(#)ucontext.h	8.1 (Berkeley) 6/10/93
  *	JNPR: ucontext.h,v 1.2 2007/08/09 11:23:32 katta
- * $FreeBSD$
+ * $FreeBSD: head/sys/mips/include/ucontext.h 232449 2012-03-03 08:19:18Z jmallett $
  */
 
 #ifndef _MACHINE_UCONTEXT_H_
@@ -39,6 +39,10 @@
 
 #ifndef _LOCORE
 
+#if defined(_KERNEL) && !defined(KLD_MODULE) && !defined(_STANDALONE)
+#include "opt_compat.h"
+#endif
+
 typedef struct	__mcontext {
 	/*
 	 * These fields must match the corresponding fields in struct 
@@ -56,6 +60,32 @@
 	void		*mc_tls;	/* pointer to TLS area */
 	int		__spare__[8];	/* XXX reserved */ 
 } mcontext_t;
+
+#if (defined(__mips_n32) || defined(__mips_n64)) && defined(COMPAT_FREEBSD32)
+#include <compat/freebsd32/freebsd32_signal.h>
+
+typedef struct __mcontext32 {
+	int		mc_onstack;
+	int32_t		mc_pc;
+	int32_t		mc_regs[32];
+	int32_t		sr;
+	int32_t		mullo, mulhi;
+	int		mc_fpused;
+	int32_t		mc_fpregs[33];
+	int32_t		mc_fpc_eir;
+	void		*mc_tls;
+	int		__spare__[8];
+} mcontext32_t;
+
+typedef struct __ucontext32 {
+	sigset_t		uc_sigmask;
+	mcontext32_t		uc_mcontext;
+	uint32_t		uc_link;
+	struct sigaltstack32    uc_stack;
+	uint32_t		uc_flags;
+	uint32_t		__spare__[4];
+} ucontext32_t;
+#endif
 #endif
 
 #ifndef SZREG
diff -r e8744e5a2f8e -r 6fd2152eeca3 head/sys/mips/include/vmparam.h
--- a/head/sys/mips/include/vmparam.h	Fri Mar 02 17:36:33 2012 +0200
+++ b/head/sys/mips/include/vmparam.h	Sat Mar 03 12:26:05 2012 +0200
@@ -37,7 +37,7 @@
  *	from: Utah Hdr: vmparam.h 1.16 91/01/18
  *	@(#)vmparam.h	8.2 (Berkeley) 4/22/94
  *	JNPR: vmparam.h,v 1.3.2.1 2007/09/10 06:01:28 girish
- * $FreeBSD: head/sys/mips/include/vmparam.h 221855 2011-05-13 19:35:01Z mdf $
+ * $FreeBSD: head/sys/mips/include/vmparam.h 232449 2012-03-03 08:19:18Z jmallett $
  */
 
 #ifndef _MACHINE_VMPARAM_H_
@@ -96,7 +96,10 @@
  * offset is calculated.
  */
 #define	USRSTACK		(VM_MAXUSER_ADDRESS - PAGE_SIZE)
- 
+#ifdef __mips_n64
+#define	FREEBSD32_USRSTACK	(((vm_offset_t)0x80000000) - PAGE_SIZE)
+#endif
+
 /*
  * Only one memory domain.
  */
diff -r e8744e5a2f8e -r 6fd2152eeca3 head/sys/mips/mips/bus_space_generic.c
--- a/head/sys/mips/mips/bus_space_generic.c	Fri Mar 02 17:36:33 2012 +0200
+++ b/head/sys/mips/mips/bus_space_generic.c	Sat Mar 03 12:26:05 2012 +0200
@@ -69,10 +69,10 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  *	from: src/sys/alpha/include/bus.h,v 1.5 1999/08/28 00:38:40 peter
- * $FreeBSD$
+ * $FreeBSD: head/sys/mips/mips/bus_space_generic.c 232410 2012-03-02 21:46:31Z jmallett $
  */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/mips/mips/bus_space_generic.c 232410 2012-03-02 21:46:31Z jmallett $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -251,13 +251,12 @@
 }
 
 int
-generic_bs_subregion(void *t __unused, bus_space_handle_t handle __unused,
-	      bus_size_t offset __unused, bus_size_t size __unused,
-	      bus_space_handle_t *nhandle __unused)
+generic_bs_subregion(void *t __unused, bus_space_handle_t handle,
+	      bus_size_t offset, bus_size_t size __unused,
+	      bus_space_handle_t *bshp)
 {
 
-	printf("SUBREGION?!?!?!\n");
-	/* Do nothing */
+	*bshp = handle + offset;
 	return (0);
 }
 
diff -r e8744e5a2f8e -r 6fd2152eeca3 head/sys/mips/mips/freebsd32_machdep.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/mips/mips/freebsd32_machdep.c	Sat Mar 03 12:26:05 2012 +0200
@@ -0,0 +1,496 @@
+/*-
+ * Copyright (c) 2012 Juli Mallett <jmallett at FreeBSD.org>
+ * All rights reserved.
+ *
+ * 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 AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: head/sys/mips/mips/freebsd32_machdep.c 232449 2012-03-03 08:19:18Z jmallett $
+ */
+
+/*
+ * Based on nwhitehorn's COMPAT_FREEBSD32 support code for PowerPC64.
+ */
+
+#include "opt_compat.h"
+#include "opt_cputype.h"
+
+#define __ELF_WORD_SIZE 32
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/sysent.h>
+#include <sys/exec.h>
+#include <sys/imgact.h>
+#include <sys/malloc.h>
+#include <sys/proc.h>
+#include <sys/namei.h>
+#include <sys/fcntl.h>
+#include <sys/sysent.h>
+#include <sys/imgact_elf.h>
+#include <sys/syscall.h>
+#include <sys/syscallsubr.h>
+#include <sys/sysproto.h>
+#include <sys/signalvar.h>
+#include <sys/vnode.h>
+#include <sys/linker.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+
+#include <machine/md_var.h>
+#include <machine/reg.h>
+#include <machine/sigframe.h>
+#include <machine/sysarch.h>
+
+#include <compat/freebsd32/freebsd32_signal.h>
+#include <compat/freebsd32/freebsd32_util.h>
+#include <compat/freebsd32/freebsd32_proto.h>
+
+static void freebsd32_exec_setregs(struct thread *, struct image_params *, u_long);
+static int get_mcontext32(struct thread *, mcontext32_t *, int);
+static int set_mcontext32(struct thread *, const mcontext32_t *);
+static void freebsd32_sendsig(sig_t, ksiginfo_t *, sigset_t *);
+
+extern const char *freebsd32_syscallnames[];
+
+struct sysentvec elf32_freebsd_sysvec = {
+	.sv_size	= SYS_MAXSYSCALL,
+	.sv_table	= freebsd32_sysent,
+	.sv_mask	= 0,
+	.sv_sigsize	= 0,
+	.sv_sigtbl	= NULL,
+	.sv_errsize	= 0,
+	.sv_errtbl	= NULL,
+	.sv_transtrap	= NULL,
+	.sv_fixup	= __elfN(freebsd_fixup),
+	.sv_sendsig	= freebsd32_sendsig,
+	.sv_sigcode	= sigcode32,
+	.sv_szsigcode	= &szsigcode32,
+	.sv_prepsyscall	= NULL,
+	.sv_name	= "FreeBSD ELF32",
+	.sv_coredump	= __elfN(coredump),
+	.sv_imgact_try	= NULL,
+	.sv_minsigstksz	= MINSIGSTKSZ,
+	.sv_pagesize	= PAGE_SIZE,
+	.sv_minuser	= VM_MIN_ADDRESS,
+	.sv_maxuser	= ((vm_offset_t)0x80000000),
+	.sv_usrstack	= FREEBSD32_USRSTACK,
+	.sv_psstrings	= FREEBSD32_PS_STRINGS,
+	.sv_stackprot	= VM_PROT_ALL,
+	.sv_copyout_strings = freebsd32_copyout_strings,
+	.sv_setregs	= freebsd32_exec_setregs,
+	.sv_fixlimit	= NULL,
+	.sv_maxssiz	= NULL,
+	.sv_flags	= SV_ABI_FREEBSD | SV_ILP32,
+	.sv_set_syscall_retval = cpu_set_syscall_retval,
+	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
+	.sv_syscallnames = freebsd32_syscallnames,
+	.sv_schedtail	= NULL,
+};
+INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec);
+
+static Elf32_Brandinfo freebsd_brand_info = {
+	.brand		= ELFOSABI_FREEBSD,
+	.machine	= EM_MIPS,
+	.compat_3_brand	= "FreeBSD",
+	.emul_path	= NULL,
+	.interp_path	= "/libexec/ld-elf.so.1",
+	.sysvec		= &elf32_freebsd_sysvec,
+	.interp_newpath	= "/libexec/ld-elf32.so.1",
+	.flags		= 0
+};
+
+SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_FIRST,
+    (sysinit_cfunc_t) elf32_insert_brand_entry,
+    &freebsd_brand_info);
+
+static void
+freebsd32_exec_setregs(struct thread *td, struct image_params *imgp, u_long stack)
+{
+	exec_setregs(td, imgp, stack);
+
+	/*
+	 * See comment in exec_setregs about running 32-bit binaries with 64-bit
+	 * registers.
+	 */
+	td->td_frame->sp -= 65536;
+
+	/*
+	 * Clear extended address space bit for userland.
+	 */
+	td->td_frame->sr &= ~MIPS_SR_UX;
+}
+
+int
+set_regs32(struct thread *td, struct reg32 *regs)
+{
+	struct reg r;
+	unsigned i;
+
+	for (i = 0; i < NUMSAVEREGS; i++)
+		r.r_regs[i] = regs->r_regs[i];
+
+	return (set_regs(td, &r));
+}
+
+int
+fill_regs32(struct thread *td, struct reg32 *regs)
+{
+	struct reg r;
+	unsigned i;
+	int error;
+
+	error = fill_regs(td, &r);
+	if (error != 0)
+		return (error);
+
+	for (i = 0; i < NUMSAVEREGS; i++)
+		regs->r_regs[i] = r.r_regs[i];
+
+	return (0);
+}
+
+int
+set_fpregs32(struct thread *td, struct fpreg32 *fpregs)
+{
+	struct fpreg fp;
+	unsigned i;
+
+	for (i = 0; i < NUMFPREGS; i++)
+		fp.r_regs[i] = fpregs->r_regs[i];
+
+	return (set_fpregs(td, &fp));
+}
+
+int
+fill_fpregs32(struct thread *td, struct fpreg32 *fpregs)
+{
+	struct fpreg fp;
+	unsigned i;
+	int error;
+
+	error = fill_fpregs(td, &fp);
+	if (error != 0)
+		return (error);
+
+	for (i = 0; i < NUMFPREGS; i++)
+		fpregs->r_regs[i] = fp.r_regs[i];
+
+	return (0);
+}
+
+static int
+get_mcontext32(struct thread *td, mcontext32_t *mcp, int flags)
+{
+	mcontext_t mcp64;
+	unsigned i;
+	int error;
+
+	error = get_mcontext(td, &mcp64, flags);
+	if (error != 0)
+		return (error);
+
+	mcp->mc_onstack = mcp64.mc_onstack;
+	mcp->mc_pc = mcp64.mc_pc;
+	for (i = 0; i < 32; i++)
+		mcp->mc_regs[i] = mcp64.mc_regs[i];
+	mcp->sr = mcp64.sr;
+	mcp->mullo = mcp64.mullo;
+	mcp->mulhi = mcp64.mulhi;
+	mcp->mc_fpused = mcp64.mc_fpused;
+	for (i = 0; i < 33; i++)
+		mcp->mc_fpregs[i] = mcp64.mc_fpregs[i];
+	mcp->mc_fpc_eir = mcp64.mc_fpc_eir;
+	mcp->mc_tls = mcp64.mc_tls;
+
+	return (0);
+}
+
+static int
+set_mcontext32(struct thread *td, const mcontext32_t *mcp)
+{
+	mcontext_t mcp64;
+	unsigned i;
+
+	mcp64.mc_onstack = mcp->mc_onstack;
+	mcp64.mc_pc = mcp->mc_pc;
+	for (i = 0; i < 32; i++)
+		mcp64.mc_regs[i] = mcp->mc_regs[i];
+	mcp64.sr = mcp->sr;
+	mcp64.mullo = mcp->mullo;
+	mcp64.mulhi = mcp->mulhi;
+	mcp64.mc_fpused = mcp->mc_fpused;
+	for (i = 0; i < 33; i++)
+		mcp64.mc_fpregs[i] = mcp->mc_fpregs[i];
+	mcp64.mc_fpc_eir = mcp->mc_fpc_eir;
+	mcp64.mc_tls = mcp->mc_tls;
+
+	return (set_mcontext(td, &mcp64));
+}
+
+int
+freebsd32_sigreturn(struct thread *td, struct freebsd32_sigreturn_args *uap)
+{
+	ucontext32_t uc;
+	int error;
+
+	CTR2(KTR_SIG, "sigreturn: td=%p ucp=%p", td, uap->sigcntxp);
+
+	if (copyin(uap->sigcntxp, &uc, sizeof(uc)) != 0) {
+		CTR1(KTR_SIG, "sigreturn: efault td=%p", td);
+		return (EFAULT);
+	}
+
+	error = set_mcontext32(td, &uc.uc_mcontext);
+	if (error != 0)
+		return (error);
+
+	kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0);
+
+#if 0
+	CTR3(KTR_SIG, "sigreturn: return td=%p pc=%#x sp=%#x",
+	     td, uc.uc_mcontext.mc_srr0, uc.uc_mcontext.mc_gpr[1]);
+#endif
+
+	return (EJUSTRETURN);
+}
+
+/*
+ * The first two fields of a ucontext_t are the signal mask and the machine
+ * context.  The next field is uc_link; we want to avoid destroying the link
+ * when copying out contexts.
+ */
+#define	UC32_COPY_SIZE	offsetof(ucontext32_t, uc_link)
+
+int
+freebsd32_getcontext(struct thread *td, struct freebsd32_getcontext_args *uap)
+{
+	ucontext32_t uc;
+	int ret;
+
+	if (uap->ucp == NULL)
+		ret = EINVAL;
+	else {
+		get_mcontext32(td, &uc.uc_mcontext, GET_MC_CLEAR_RET);
+		PROC_LOCK(td->td_proc);
+		uc.uc_sigmask = td->td_sigmask;
+		PROC_UNLOCK(td->td_proc);
+		ret = copyout(&uc, uap->ucp, UC32_COPY_SIZE);
+	}
+	return (ret);
+}
+
+int
+freebsd32_setcontext(struct thread *td, struct freebsd32_setcontext_args *uap)
+{
+	ucontext32_t uc;
+	int ret;	
+
+	if (uap->ucp == NULL)
+		ret = EINVAL;
+	else {
+		ret = copyin(uap->ucp, &uc, UC32_COPY_SIZE);
+		if (ret == 0) {
+			ret = set_mcontext32(td, &uc.uc_mcontext);
+			if (ret == 0) {
+				kern_sigprocmask(td, SIG_SETMASK,
+				    &uc.uc_sigmask, NULL, 0);
+			}
+		}
+	}
+	return (ret == 0 ? EJUSTRETURN : ret);
+}
+
+int
+freebsd32_swapcontext(struct thread *td, struct freebsd32_swapcontext_args *uap)
+{
+	ucontext32_t uc;
+	int ret;
+
+	if (uap->oucp == NULL || uap->ucp == NULL)
+		ret = EINVAL;
+	else {
+		get_mcontext32(td, &uc.uc_mcontext, GET_MC_CLEAR_RET);
+		PROC_LOCK(td->td_proc);
+		uc.uc_sigmask = td->td_sigmask;
+		PROC_UNLOCK(td->td_proc);
+		ret = copyout(&uc, uap->oucp, UC32_COPY_SIZE);
+		if (ret == 0) {
+			ret = copyin(uap->ucp, &uc, UC32_COPY_SIZE);
+			if (ret == 0) {
+				ret = set_mcontext32(td, &uc.uc_mcontext);
+				if (ret == 0) {
+					kern_sigprocmask(td, SIG_SETMASK,
+					    &uc.uc_sigmask, NULL, 0);
+				}
+			}
+		}
+	}
+	return (ret == 0 ? EJUSTRETURN : ret);
+}
+
+#define	UCONTEXT_MAGIC	0xACEDBADE
+
+/*
+ * Send an interrupt to process.
+ *
+ * Stack is set up to allow sigcode stored
+ * at top to call routine, followed by kcall
+ * to sigreturn routine below.	After sigreturn
+ * resets the signal mask, the stack, and the
+ * frame pointer, it returns to the user
+ * specified pc, psl.
+ */
+static void
+freebsd32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
+{
+	struct proc *p;
+	struct thread *td;
+	struct fpreg32 fpregs;
+	struct reg32 regs;
+	struct sigacts *psp;
+	struct sigframe32 sf, *sfp;
+	int sig;
+	int oonstack;
+	unsigned i;
+
+	td = curthread;
+	p = td->td_proc;
+	PROC_LOCK_ASSERT(p, MA_OWNED);
+	sig = ksi->ksi_signo;
+	psp = p->p_sigacts;
+	mtx_assert(&psp->ps_mtx, MA_OWNED);
+
+	fill_regs32(td, &regs);
+	oonstack = sigonstack(td->td_frame->sp);
+
+	/* save user context */
+	bzero(&sf, sizeof sf);
+	sf.sf_uc.uc_sigmask = *mask;
+	sf.sf_uc.uc_stack.ss_sp = (int32_t)(intptr_t)td->td_sigstk.ss_sp;
+	sf.sf_uc.uc_stack.ss_size = td->td_sigstk.ss_size;
+	sf.sf_uc.uc_stack.ss_flags = td->td_sigstk.ss_flags;
+	sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
+	sf.sf_uc.uc_mcontext.mc_pc = regs.r_regs[PC];
+	sf.sf_uc.uc_mcontext.mullo = regs.r_regs[MULLO];
+	sf.sf_uc.uc_mcontext.mulhi = regs.r_regs[MULHI];
+	sf.sf_uc.uc_mcontext.mc_regs[0] = UCONTEXT_MAGIC;  /* magic number */
+	for (i = 1; i < 32; i++)
+		sf.sf_uc.uc_mcontext.mc_regs[i] = regs.r_regs[i];
+	sf.sf_uc.uc_mcontext.mc_fpused = td->td_md.md_flags & MDTD_FPUSED;
+	if (sf.sf_uc.uc_mcontext.mc_fpused) {
+		/* if FPU has current state, save it first */
+		if (td == PCPU_GET(fpcurthread))
+			MipsSaveCurFPState(td);
+		fill_fpregs32(td, &fpregs);
+		for (i = 0; i < 33; i++)
+			sf.sf_uc.uc_mcontext.mc_fpregs[i] = fpregs.r_regs[i];
+	}
+
+	/* Allocate and validate space for the signal handler context. */
+	if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack &&
+	    SIGISMEMBER(psp->ps_sigonstack, sig)) {
+		sfp = (struct sigframe32 *)((vm_offset_t)(td->td_sigstk.ss_sp +
+		    td->td_sigstk.ss_size - sizeof(struct sigframe32))
+		    & ~(sizeof(__int64_t) - 1));
+	} else
+		sfp = (struct sigframe32 *)((vm_offset_t)(td->td_frame->sp - 
+		    sizeof(struct sigframe32)) & ~(sizeof(__int64_t) - 1));
+
+	/* Translate the signal if appropriate */
+	if (p->p_sysent->sv_sigtbl) {
+		if (sig <= p->p_sysent->sv_sigsize)
+			sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
+	}
+
+	/* Build the argument list for the signal handler. */
+	td->td_frame->a0 = sig;
+	td->td_frame->a2 = (register_t)(intptr_t)&sfp->sf_uc;
+	if (SIGISMEMBER(psp->ps_siginfo, sig)) {
+		/* Signal handler installed with SA_SIGINFO. */
+		td->td_frame->a1 = (register_t)(intptr_t)&sfp->sf_si;
+		/* sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher; */
+
+		/* fill siginfo structure */
+		sf.sf_si.si_signo = sig;
+		sf.sf_si.si_code = ksi->ksi_code;
+		sf.sf_si.si_addr = td->td_frame->badvaddr;
+	} else {
+		/* Old FreeBSD-style arguments. */
+		td->td_frame->a1 = ksi->ksi_code;
+		td->td_frame->a3 = td->td_frame->badvaddr;
+		/* sf.sf_ahu.sf_handler = catcher; */
+	}
+
+	mtx_unlock(&psp->ps_mtx);
+	PROC_UNLOCK(p);
+
+	/*
+	 * Copy the sigframe out to the user's stack.
+	 */
+	if (copyout(&sf, sfp, sizeof(struct sigframe32)) != 0) {
+		/*
+		 * Something is wrong with the stack pointer.
+		 * ...Kill the process.
+		 */
+		PROC_LOCK(p);
+		sigexit(td, SIGILL);
+	}
+
+	td->td_frame->pc = (register_t)(intptr_t)catcher;
+	td->td_frame->t9 = (register_t)(intptr_t)catcher;
+	td->td_frame->sp = (register_t)(intptr_t)sfp;
+	/*
+	 * Signal trampoline code is at base of user stack.
+	 */
+	td->td_frame->ra = (register_t)(intptr_t)FREEBSD32_PS_STRINGS - *(p->p_sysent->sv_szsigcode);
+	PROC_LOCK(p);
+	mtx_lock(&psp->ps_mtx);
+}
+
+int
+freebsd32_sysarch(struct thread *td, struct freebsd32_sysarch_args *uap)
+{
+	int error;
+	int32_t tlsbase;
+
+	switch (uap->op) {
+	case MIPS_SET_TLS:
+		td->td_md.md_tls = (void *)(intptr_t)uap->parms;
+		return (0);
+	case MIPS_GET_TLS: 
+		tlsbase = (int32_t)(intptr_t)td->td_md.md_tls;
+		error = copyout(&tlsbase, uap->parms, sizeof(tlsbase));
+		return (error);
+	default:
+		break;
+	}
+	return (EINVAL);
+}
+
+void
+elf32_dump_thread(struct thread *td __unused, void *dst __unused,
+    size_t *off __unused)
+{
+}
diff -r e8744e5a2f8e -r 6fd2152eeca3 head/sys/mips/mips/genassym.c
--- a/head/sys/mips/mips/genassym.c	Fri Mar 02 17:36:33 2012 +0200
+++ b/head/sys/mips/mips/genassym.c	Sat Mar 03 12:26:05 2012 +0200
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/mips/mips/genassym.c 229677 2012-01-06 01:23:26Z gonzo $");
+__FBSDID("$FreeBSD: head/sys/mips/mips/genassym.c 232449 2012-03-03 08:19:18Z jmallett $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -92,6 +92,9 @@
 ASSYM(VM_MAX_KERNEL_ADDRESS, VM_MAX_KERNEL_ADDRESS);
 ASSYM(VM_MAXUSER_ADDRESS, VM_MAXUSER_ADDRESS);
 ASSYM(SIGF_UC, offsetof(struct sigframe, sf_uc));
+#ifdef COMPAT_FREEBSD32
+ASSYM(SIGF32_UC, offsetof(struct sigframe32, sf_uc));
+#endif
 ASSYM(SIGFPE, SIGFPE);
 ASSYM(PAGE_SHIFT, PAGE_SHIFT);
 ASSYM(PAGE_SIZE, PAGE_SIZE);
diff -r e8744e5a2f8e -r 6fd2152eeca3 head/sys/mips/mips/swtch.S
--- a/head/sys/mips/mips/swtch.S	Fri Mar 02 17:36:33 2012 +0200
+++ b/head/sys/mips/mips/swtch.S	Sat Mar 03 12:26:05 2012 +0200
@@ -47,7 +47,7 @@
  *
  *	from: @(#)locore.s	8.5 (Berkeley) 1/4/94
  *	JNPR: swtch.S,v 1.6.2.1 2007/09/10 10:36:50 girish
- * $FreeBSD: head/sys/mips/mips/swtch.S 229677 2012-01-06 01:23:26Z gonzo $
+ * $FreeBSD: head/sys/mips/mips/swtch.S 232449 2012-03-03 08:19:18Z jmallett $
  */
 
 /*
@@ -55,6 +55,7 @@
  *	assembly language support routines.
  */
 
+#include "opt_compat.h"
 #include "opt_cputype.h"
 #include <sys/syscall.h>
 #include <machine/asm.h>
@@ -636,3 +637,21 @@
 szsigcode:
 	.long	esigcode-sigcode
 	.text
+
+#if (defined(__mips_n32) || defined(__mips_n64)) && defined(COMPAT_FREEBSD32)
+	.globl	_C_LABEL(sigcode32)
+_C_LABEL(sigcode32):
+	addu		a0, sp, SIGF32_UC	# address of ucontext
+	li		v0, SYS_sigreturn
+# sigreturn (ucp)
+	syscall
+	break	0				# just in case sigreturn fails
+	.globl	_C_LABEL(esigcode32)
+_C_LABEL(esigcode32):
+
+	.data
+	.globl	szsigcode32
+szsigcode32:
+	.long	esigcode32-sigcode32
+	.text
+#endif
diff -r e8744e5a2f8e -r 6fd2152eeca3 head/sys/mips/mips/trap.c
--- a/head/sys/mips/mips/trap.c	Fri Mar 02 17:36:33 2012 +0200
+++ b/head/sys/mips/mips/trap.c	Sat Mar 03 12:26:05 2012 +0200
@@ -39,8 +39,9 @@
  *	JNPR: trap.c,v 1.13.2.2 2007/08/29 10:03:49 girish
  */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/mips/mips/trap.c 231314 2012-02-09 22:48:35Z gonzo $");
+__FBSDID("$FreeBSD: head/sys/mips/mips/trap.c 232449 2012-03-03 08:19:18Z jmallett $");
 
+#include "opt_compat.h"
 #include "opt_ddb.h"
 #include "opt_global.h"
 #include "opt_ktrace.h"
@@ -282,19 +283,30 @@
 	sa->code = locr0->v0;
 
 	switch (sa->code) {
-#if defined(__mips_n32) || defined(__mips_n64)
 	case SYS___syscall:
-		/*
-		 * Quads fit in a single register in
-		 * new ABIs.
-		 *
-		 * XXX o64?
-		 */
-#endif
 	case SYS_syscall:
 		/*
-		 * Code is first argument, followed by
-		 * actual args.
+		 * This is an indirect syscall, in which the code is the first argument.
+		 */
+#if (!defined(__mips_n32) && !defined(__mips_n64)) || defined(COMPAT_FREEBSD32)
+		if (sa->code == SYS___syscall && SV_PROC_FLAG(td->td_proc, SV_ILP32)) {
+			/*
+			 * Like syscall, but code is a quad, so as to maintain alignment
+			 * for the rest of the arguments.
+			 */
+			if (_QUAD_LOWWORD == 0)
+				sa->code = locr0->a0;
+			else
+				sa->code = locr0->a1;
+			sa->args[0] = locr0->a2;
+			sa->args[1] = locr0->a3;
+			nsaved = 2;
+			break;
+		} 
+#endif
+		/*
+		 * This is either not a quad syscall, or is a quad syscall with a
+		 * new ABI in which quads fit in a single register.
 		 */
 		sa->code = locr0->a0;
 		sa->args[0] = locr0->a1;
@@ -302,52 +314,60 @@
 		sa->args[2] = locr0->a3;
 		nsaved = 3;
 #if defined(__mips_n32) || defined(__mips_n64)
-		sa->args[3] = locr0->t4;
-		sa->args[4] = locr0->t5;
-		sa->args[5] = locr0->t6;
-		sa->args[6] = locr0->t7;
-		nsaved += 4;
+#ifdef COMPAT_FREEBSD32
+		if (!SV_PROC_FLAG(td->td_proc, SV_ILP32)) {
+#endif
+			/*
+			 * Non-o32 ABIs support more arguments in registers.
+			 */
+			sa->args[3] = locr0->t4;
+			sa->args[4] = locr0->t5;
+			sa->args[5] = locr0->t6;
+			sa->args[6] = locr0->t7;
+			nsaved += 4;
+#ifdef COMPAT_FREEBSD32
+		}
+#endif
 #endif
 		break;
-
-#if defined(__mips_o32)
-	case SYS___syscall:
+	default:
 		/*
-		 * Like syscall, but code is a quad, so as
-		 * to maintain quad alignment for the rest
-		 * of the arguments.
+		 * A direct syscall, arguments are just parameters to the syscall.
 		 */
-		if (_QUAD_LOWWORD == 0)
-			sa->code = locr0->a0;
-		else
-			sa->code = locr0->a1;
-		sa->args[0] = locr0->a2;
-		sa->args[1] = locr0->a3;
-		nsaved = 2;
-		break;
-#endif
-
-	default:
 		sa->args[0] = locr0->a0;
 		sa->args[1] = locr0->a1;
 		sa->args[2] = locr0->a2;
 		sa->args[3] = locr0->a3;
 		nsaved = 4;
 #if defined (__mips_n32) || defined(__mips_n64)
-		sa->args[4] = locr0->t4;
-		sa->args[5] = locr0->t5;
-		sa->args[6] = locr0->t6;
-		sa->args[7] = locr0->t7;
-		nsaved += 4;
+#ifdef COMPAT_FREEBSD32
+		if (!SV_PROC_FLAG(td->td_proc, SV_ILP32)) {
+#endif
+			/*
+			 * Non-o32 ABIs support more arguments in registers.
+			 */
+			sa->args[4] = locr0->t4;
+			sa->args[5] = locr0->t5;
+			sa->args[6] = locr0->t6;
+			sa->args[7] = locr0->t7;
+			nsaved += 4;
+#if defined (__mips_n32) || defined(__mips_n64)
+		}
+#endif
 #endif
 		break;
 	}
+
 #ifdef TRAP_DEBUG
 	if (trap_debug)
-		printf("SYSCALL #%d pid:%u\n", code, p->p_pid);
+		printf("SYSCALL #%d pid:%u\n", sa->code, td->td_proc->p_pid);
 #endif
 
 	se = td->td_proc->p_sysent;
+	/*
+	 * XXX
+	 * Shouldn't this go before switching on the code?
+	 */
 	if (se->sv_mask)
 		sa->code &= se->sv_mask;
 
@@ -366,8 +386,27 @@
 		 * should be 8, size there are 8 registers to skip,
 		 * not 4, but I'm not certain.
 		 */
-		printf("SYSCALL #%u pid:%u, nargs > nsaved.\n", sa->code,
-		    td->td_proc->p_pid);
+#ifdef COMPAT_FREEBSD32
+		if (!SV_PROC_FLAG(td->td_proc, SV_ILP32))
+#endif
+			printf("SYSCALL #%u pid:%u, narg (%u) > nsaved (%u).\n",
+			    sa->code, td->td_proc->p_pid, sa->narg, nsaved);
+#endif
+#if (defined(__mips_n32) || defined(__mips_n64)) && defined(COMPAT_FREEBSD32)
+		if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) {
+			unsigned i;
+			int32_t arg;
+
+			error = 0; /* XXX GCC is awful.  */
+			for (i = nsaved; i < sa->narg; i++) {
+				error = copyin((caddr_t)(intptr_t)(locr0->sp +
+				    (4 + (i - nsaved)) * sizeof(int32_t)),
+				    (caddr_t)&arg, sizeof arg);
+				if (error != 0)
+					break;
+			       sa->args[i] = arg;
+			}
+		} else
 #endif
 		error = copyin((caddr_t)(intptr_t)(locr0->sp +
 		    4 * sizeof(register_t)), (caddr_t)&sa->args[nsaved],
@@ -539,7 +578,7 @@
 			goto err;
 		}
 
-                /*
+		/*
 		 * It is an error for the kernel to access user space except
 		 * through the copyin/copyout routines.
 		 */
diff -r e8744e5a2f8e -r 6fd2152eeca3 head/sys/mips/mips/vm_machdep.c
--- a/head/sys/mips/mips/vm_machdep.c	Fri Mar 02 17:36:33 2012 +0200
+++ b/head/sys/mips/mips/vm_machdep.c	Sat Mar 03 12:26:05 2012 +0200
@@ -39,8 +39,9 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/mips/mips/vm_machdep.c 231470 2012-02-10 23:24:33Z gonzo $");
+__FBSDID("$FreeBSD: head/sys/mips/mips/vm_machdep.c 232449 2012-03-03 08:19:18Z jmallett $");
 
+#include "opt_compat.h"
 #include "opt_cputype.h"
 #include "opt_ddb.h"
 
@@ -49,6 +50,7 @@
 #include <sys/malloc.h>
 #include <sys/proc.h>
 #include <sys/syscall.h>
+#include <sys/sysent.h>
 #include <sys/buf.h>
 #include <sys/vnode.h>
 #include <sys/vmmeter.h>
@@ -301,7 +303,12 @@
 
 	code = locr0->v0;
 	quad_syscall = 0;
-#if defined(__mips_o32)
+#if defined(__mips_n32) || defined(__mips_n64)
+#ifdef COMPAT_FREEBSD32
+	if (code == SYS___syscall && SV_PROC_FLAG(td->td_proc, SV_ILP32))
+		quad_syscall = 1;
+#endif
+#else
 	if (code == SYS___syscall)
 		quad_syscall = 1;
 #endif
@@ -608,7 +615,12 @@
 	 * to make it the same way TLS base is passed to 
 	 * MIPS_SET_TLS/MIPS_GET_TLS API 
 	 */
+
 #ifdef __mips_n64
+#ifdef COMPAT_FREEBSD32
+	if (SV_PROC_FLAG(td->td_proc, SV_ILP32))
+		td->td_md.md_tls = (char*)tls_base + 0x7008;
+#endif
 	td->td_md.md_tls = (char*)tls_base + 0x7010;
 #else
 	td->td_md.md_tls = (char*)tls_base + 0x7008;


More information about the Zrouter-src-freebsd mailing list