Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 15 Jun 2010 19:06:16 +0530
From:      "Jayachandran C." <c.jayachandran@gmail.com>
To:        Randall Stewart <rrs@lakerest.net>, Juli Mallett <jmallett@freebsd.org>,  "M. Warner Losh" <imp@bsdimp.com>, freebsd-mips@freebsd.org
Subject:   Merging 64 bit changes to -HEAD
Message-ID:  <AANLkTik8jFkB7FTIIhyjalkfv1c0yXqse57Jzz527uf_@mail.gmail.com>

next in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]
I have volunteered to merge Juli's 64-bit work into HEAD,  and
hopefully get it to work on XLR too. The tree
(http://svn.freebsd.org/base/user/jmallett/octeon) has quite a bit of
changes, so I would like to do this over multiple changesets and
without breaking the current o32 code.

The first batch of changes are attached (also at
http://people.freebsd.org/~jchandra/jmallett-merge/), the patches are:

libc-asm.patch - change libc assembly code to use macros which work on o32/n64
libc-other.patch - makecontext implemenation, and other cleanup
ld.so.patch - change dynamic loader assembly code to use macros
tlb-to-c.patch - move TLB operations to C, update TLB operations API

I've tested this on XLR, but there is a chance that this might break
other platforms. So please let me know your comments on both the
patches and the merge process.

The future patches (if everything goes well), will do the PTE_ flag to
PG_ flag renaming in Juli's tree, then the actual n32/n64 changes.

Thanks,
JC.

[-- Attachment #2 --]
Index: lib/libc/mips/SYS.h
===================================================================
--- lib/libc/mips/SYS.h	(revision 209040)
+++ lib/libc/mips/SYS.h	(working copy)
@@ -1,4 +1,4 @@
-/*	$NetBSD: SYS.h,v 1.18 2003/10/29 12:28:33 pooka Exp $ */
+/*	$NetBSD: SYS.h,v 1.19 2009/12/14 01:07:41 matt Exp $ */
 /* $FreeBSD$ */
 
 /*-
@@ -79,14 +79,22 @@
  */
 #ifdef __ABICALLS__
 	.abicalls
-# define PIC_PROLOGUE(x,sr)	.set noreorder; .cpload sr; .set reorder
-# define PIC_CALL(l,sr)		la sr, _C_LABEL(l); jr sr
+# if defined(__mips_o32) || defined(__mips_o64)
+#  define PIC_PROLOGUE(x)	SETUP_GP
+#  define PIC_TAILCALL(l)	PTR_LA t9, _C_LABEL(l); jr t9
+#  define PIC_RETURN()		j ra
+# else
+#  define PIC_PROLOGUE(x)	SETUP_GP64(t3, x)
+#  define PIC_TAILCALL(l)	PTR_LA t9, _C_LABEL(l); RESTORE_GP64; jr t9
+#  define PIC_RETURN()		RESTORE_GP64; j ra
+# endif
 #else
-# define PIC_PROLOGUE(x,sr)
-# define PIC_CALL(l,sr)		j  _C_LABEL(l)
-#endif
+# define PIC_PROLOGUE(x)
+# define PIC_TAILCALL(l)	j  _C_LABEL(l)
+# define PIC_RETURN()
+#endif /* __ABICALLS__ */
 
-# define SYSTRAP(x)	li v0, SYS_ ## x; syscall;
+# define SYSTRAP(x)	li v0,SYS_ ## x; syscall;
 
 /*
  * Do a syscall that cannot fail (sync, get{p,u,g,eu,eg)id)
@@ -106,7 +114,7 @@
  */
 #define PSEUDO_NOERROR(x)						\
 LEAF(__sys_ ## x);							\
-        .weak _C_LABEL(x);						\
+	.weak _C_LABEL(x);						\
 	_C_LABEL(x) = _C_LABEL(__CONCAT(__sys_,x));			\
 	.weak _C_LABEL(__CONCAT(_,x));					\
 	_C_LABEL(__CONCAT(_,x)) = _C_LABEL(__CONCAT(__sys_,x));		\
@@ -116,14 +124,14 @@
 
 #define PSEUDO(x)							\
 LEAF(__sys_ ## x);							\
-        .weak _C_LABEL(x);						\
+	.weak _C_LABEL(x);						\
 	_C_LABEL(x) = _C_LABEL(__CONCAT(__sys_,x));			\
 	.weak _C_LABEL(__CONCAT(_,x));					\
 	_C_LABEL(__CONCAT(_,x)) = _C_LABEL(__CONCAT(__sys_,x));		\
-	PIC_PROLOGUE(x,t9);						\
+	PIC_PROLOGUE(__sys_ ## x);					\
 	SYSTRAP(x);							\
 	bne a3,zero,err;						\
-	j ra;								\
+	PIC_RETURN();							\
 err:									\
-	PIC_CALL(__cerror,t9);						\
-	END(__sys_ ## x)
+	PIC_TAILCALL(__cerror);						\
+END(__sys_ ## x)
Index: lib/libc/mips/string/ffs.S
===================================================================
--- lib/libc/mips/string/ffs.S	(revision 209040)
+++ lib/libc/mips/string/ffs.S	(working copy)
@@ -1,4 +1,4 @@
-/*	$NetBSD: ffs.S,v 1.1 2005/12/20 19:28:49 christos Exp $	*/
+/*	$NetBSD: ffs.S,v 1.2 2009/12/14 00:39:00 matt Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 
 #if defined(LIBC_SCCS) && !defined(lint)
 	ASMSTR("from: @(#)ffs.s	8.1 (Berkeley) 6/4/93")
-	ASMSTR("$NetBSD: ffs.S,v 1.1 2005/12/20 19:28:49 christos Exp $")
+	ASMSTR("$NetBSD: ffs.S,v 1.2 2009/12/14 00:39:00 matt Exp $")
 #endif /* LIBC_SCCS and not lint */
 
 #ifdef __ABICALLS__
Index: lib/libc/mips/string/bcmp.S
===================================================================
--- lib/libc/mips/string/bcmp.S	(revision 209040)
+++ lib/libc/mips/string/bcmp.S	(working copy)
@@ -1,4 +1,4 @@
-/*	$NetBSD: bcmp.S,v 1.8 2003/08/07 16:42:16 agc Exp $	*/
+/*	$NetBSD: bcmp.S,v 1.9 2009/12/14 01:07:42 matt Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -35,9 +35,15 @@
 #include <machine/asm.h>
 __FBSDID("$FreeBSD$");
 
+#define _LOCORE		/* XXX not really, just assembly-code source */
+#include <machine/endian.h>	/* LWLO/LWHI, SWLO/SWHI */
+
 #if defined(LIBC_SCCS) && !defined(lint)
+#if 0
 	ASMSTR("from: @(#)bcmp.s	8.1 (Berkeley) 6/4/93")
-	ASMSTR("$NetBSD: bcmp.S,v 1.8 2003/08/07 16:42:16 agc Exp $")
+#else
+	ASMSTR("$NetBSD: bcmp.S,v 1.9 2009/12/14 01:07:42 matt Exp $")
+#endif
 #endif /* LIBC_SCCS and not lint */
 
 #ifdef __ABICALLS__
@@ -49,86 +55,76 @@
 
 LEAF(bcmp)
 	.set	noreorder
-	blt	a2, 16, small		# is it worth any trouble?
-	xor	v0, a0, a1		# compare low two bits of addresses
-	and	v0, v0, 3
-	subu	a3, zero, a1		# compute # bytes to word align address
-	bne	v0, zero, unaligned	# not possible to align addresses
-	and	a3, a3, 3
+	blt		a2, 16, small	# is it worth any trouble?
+	xor		v0, a0, a1	# compare low two bits of addresses
+	and		v0, v0, 3
+	PTR_SUBU	a3, zero, a1	# compute # bytes to word align address
+	bne		v0, zero, unaligned # not possible to align addresses
+	and		a3, a3, 3
 
-	beq	a3, zero, 1f
-	subu	a2, a2, a3		# subtract from remaining count
-	move	v0, v1			# init v0,v1 so unmodified bytes match
-#ifdef __MIPSEB__
-	lwl	v0, 0(a0)		# read 1, 2, or 3 bytes
-	lwl	v1, 0(a1)
-#else
-	lwr	v0, 0(a0)		# read 1, 2, or 3 bytes
-	lwr	v1, 0(a1)
-#endif
-	addu	a1, a1, a3
-	bne	v0, v1, nomatch
-	addu	a0, a0, a3
+	beq		a3, zero, 1f
+	PTR_SUBU	a2, a2, a3	# subtract from remaining count
+	move		v0, v1		# init v0,v1 so unmodified bytes match
+	LWHI		v0, 0(a0)	# read 1, 2, or 3 bytes
+	LWHI		v1, 0(a1)
+	PTR_ADDU	a1, a1, a3
+	bne		v0, v1, nomatch
+	PTR_ADDU	a0, a0, a3
 1:
-	and	a3, a2, ~3		# compute number of whole words left
-	subu	a2, a2, a3		#   which has to be >= (16-3) & ~3
-	addu	a3, a3, a0		# compute ending address
+	and		a3, a2, ~3	# compute number of whole words left
+	PTR_SUBU	a2, a2, a3	#   which has to be >= (16-3) & ~3
+	PTR_ADDU	a3, a3, a0	# compute ending address
 2:
-	lw	v0, 0(a0)		# compare words
-	lw	v1, 0(a1)
-	addu	a0, a0, 4
-	bne	v0, v1, nomatch
-	addu	a1, a1, 4
-	bne	a0, a3, 2b
+	lw		v0, 0(a0)	# compare words
+	lw		v1, 0(a1)
+	PTR_ADDU	a0, a0, 4
+	bne		v0, v1, nomatch
+	PTR_ADDU	a1, a1, 4
+	bne		a0, a3, 2b
 	nop
-	b	small			# finish remainder
+	b		small		# finish remainder
 	nop
 unaligned:
-	beq	a3, zero, 2f
-	subu	a2, a2, a3		# subtract from remaining count
-	addu	a3, a3, a0		# compute ending address
+	beq		a3, zero, 2f
+	PTR_SUBU	a2, a2, a3	# subtract from remaining count
+	PTR_ADDU	a3, a3, a0	# compute ending address
 1:
-	lbu	v0, 0(a0)		# compare bytes until a1 word aligned
-	lbu	v1, 0(a1)
-	addu	a0, a0, 1
-	bne	v0, v1, nomatch
-	addu	a1, a1, 1
-	bne	a0, a3, 1b
+	lbu		v0, 0(a0)	# compare bytes until a1 word aligned
+	lbu		v1, 0(a1)
+	PTR_ADDU	a0, a0, 1
+	bne		v0, v1, nomatch
+	PTR_ADDU	a1, a1, 1
+	bne		a0, a3, 1b
 	nop
 2:
-	and	a3, a2, ~3		# compute number of whole words left
-	subu	a2, a2, a3		#   which has to be >= (16-3) & ~3
-	addu	a3, a3, a0		# compute ending address
+	and		a3, a2, ~3	# compute number of whole words left
+	PTR_SUBU	a2, a2, a3	#   which has to be >= (16-3) & ~3
+	PTR_ADDU	a3, a3, a0	# compute ending address
 3:
-#ifdef __MIPSEB__
-	lwl	v0, 0(a0)		# compare words a0 unaligned, a1 aligned
-	lwr	v0, 3(a0)
-#else
-	lwr	v0, 0(a0)		# compare words a0 unaligned, a1 aligned
-	lwl	v0, 3(a0)
-#endif
-	lw	v1, 0(a1)
-	addu	a0, a0, 4
-	bne	v0, v1, nomatch
-	addu	a1, a1, 4
-	bne	a0, a3, 3b
+	LWHI		v0, 0(a0)	# compare words a0 unaligned, a1 aligned
+	LWLO		v0, 3(a0)
+	lw		v1, 0(a1)
+	PTR_ADDU	a0, a0, 4
+	bne		v0, v1, nomatch
+	PTR_ADDU	a1, a1, 4
+	bne		a0, a3, 3b
 	nop
 small:
-	ble	a2, zero, match
-	addu	a3, a2, a0		# compute ending address
+	ble		a2, zero, match
+	PTR_ADDU	a3, a2, a0		# compute ending address
 1:
-	lbu	v0, 0(a0)
-	lbu	v1, 0(a1)
-	addu	a0, a0, 1
-	bne	v0, v1, nomatch
-	addu	a1, a1, 1
-	bne	a0, a3, 1b
+	lbu		v0, 0(a0)
+	lbu		v1, 0(a1)
+	PTR_ADDU	a0, a0, 1
+	bne		v0, v1, nomatch
+	PTR_ADDU	a1, a1, 1
+	bne		a0, a3, 1b
 	nop
 match:
-	j	ra
-	move	v0, zero
+	j		ra
+	move		v0, zero
 nomatch:
-	j	ra
-	li	v0, 1
+	j		ra
+	li		v0, 1
 	.set	reorder
 END(bcmp)
Index: lib/libc/mips/string/bzero.S
===================================================================
--- lib/libc/mips/string/bzero.S	(revision 209040)
+++ lib/libc/mips/string/bzero.S	(working copy)
@@ -1,4 +1,4 @@
-/*	$NetBSD: bzero.S,v 1.8 2003/08/07 16:42:16 agc Exp $	*/
+/*	$NetBSD: bzero.S,v 1.10 2009/12/14 02:53:52 matt Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -36,10 +36,15 @@
 __FBSDID("$FreeBSD$");
 
 #if defined(LIBC_SCCS) && !defined(lint)
+#if 0
 	ASMSTR("from: @(#)bzero.s	8.1 (Berkeley) 6/4/93")
-	ASMSTR("$NetBSD: bzero.S,v 1.8 2003/08/07 16:42:16 agc Exp $")
+#else
+	ASMSTR("$NetBSD: bzero.S,v 1.10 2009/12/14 02:53:52 matt Exp $")
+#endif
 #endif /* LIBC_SCCS and not lint */
 
+#define _LOCORE		/* XXX not really, just assembly-code source */
+#include <machine/endian.h>
 
 #ifdef __ABICALLS__
 	.abicalls
@@ -49,34 +54,48 @@
 
 LEAF(bzero)
 	.set	noreorder
-	blt	a1, 12, smallclr	# small amount to clear?
-	subu	a3, zero, a0		# compute # bytes to word align address
-	and	a3, a3, 3
-	beq	a3, zero, 1f		# skip if word aligned
-	subu	a1, a1, a3		# subtract from remaining count
-#ifdef __MIPSEB__
-	swl	zero, 0(a0)		# clear 1, 2, or 3 bytes to align
-#else
-	swr	zero, 0(a0)		# clear 1, 2, or 3 bytes to align
+	blt		a1, 3*SZREG, smallclr # small amount to clear?
+	PTR_SUBU	a3, zero, a0	# compute # bytes to word align address
+	and		a3, a3, SZREG-1
+	beq		a3, zero, 1f	# skip if word aligned
+#if SZREG == 4
+	PTR_SUBU	a1, a1, a3	# subtract from remaining count
+	SWHI		zero, 0(a0)	# clear 1, 2, or 3 bytes to align
+	PTR_ADDU	a0, a0, a3
 #endif
-	addu	a0, a0, a3
+#if SZREG == 8
+	PTR_SUBU	a1, a1, a3	# subtract from remaining count
+	PTR_ADDU	a0, a0, a3	# align dst to next word
+	sll		a3, a3, 3	# bits to bytes
+	li		a2, -1		# make a mask
+#if _BYTE_ORDER == _BIG_ENDIAN
+	REG_SRLV	a2, a2, a3	# we want to keep the MSB bytes
+#endif
+#if _BYTE_ORDER == _LITTLE_ENDIAN
+	REG_SLLV	a2, a2, a3	# we want to keep the LSB bytes
+#endif
+	nor		a2, zero, a2	# complement the mask
+	REG_L		v0, -SZREG(a0)	# load the word to partially clear
+	and		v0, v0, a2	# clear the bytes
+	REG_S		v0, -SZREG(a0)	# store it back
+#endif
 1:
-	and	v0, a1, 3		# compute number of words left
-	subu	a3, a1, v0
-	move	a1, v0
-	addu	a3, a3, a0		# compute ending address
+	and		v0, a1, SZREG-1	# compute number of words left
+	PTR_SUBU	a3, a1, v0
+	move		a1, v0
+	PTR_ADDU	a3, a3, a0	# compute ending address
 2:
-	addu	a0, a0, 4		# clear words
-	bne	a0, a3, 2b		#   unrolling loop doesnt help
-	sw	zero, -4(a0)		#   since we are limited by memory speed
+	PTR_ADDU	a0, a0, SZREG	# clear words
+	bne		a0, a3, 2b	#  unrolling loop doesnt help
+	REG_S		zero, -SZREG(a0) # since we are limited by memory speed
 smallclr:
-	ble	a1, zero, 2f
-	addu	a3, a1, a0		# compute ending address
+	ble		a1, zero, 2f
+	PTR_ADDU	a3, a1, a0	# compute ending address
 1:
-	addu	a0, a0, 1		# clear bytes
-	bne	a0, a3, 1b
-	sb	zero, -1(a0)
+	PTR_ADDU	a0, a0, 1	# clear bytes
+	bne		a0, a3, 1b
+	sb		zero, -1(a0)
 2:
-	j	ra
+	j		ra
 	nop
 END(bzero)
Index: lib/libc/mips/string/index.S
===================================================================
--- lib/libc/mips/string/index.S	(revision 209040)
+++ lib/libc/mips/string/index.S	(working copy)
@@ -46,14 +46,14 @@
 
 LEAF(index)
 1:
-	lbu	a2, 0(a0)		# get a byte
-	addu	a0, a0, 1
-	beq	a2, a1, fnd
-	bne	a2, zero, 1b
+	lbu		a2, 0(a0)		# get a byte
+	PTR_ADDU	a0, a0, 1
+	beq		a2, a1, fnd
+	bne		a2, zero, 1b
 notfnd:
-	move	v0, zero
-	j	ra
+	move		v0, zero
+	j		ra
 fnd:
-	subu	v0, a0, 1
-	j	ra
+	PTR_SUBU	v0, a0, 1
+	j		ra
 END(index)
Index: lib/libc/mips/string/strlen.S
===================================================================
--- lib/libc/mips/string/strlen.S	(revision 209040)
+++ lib/libc/mips/string/strlen.S	(working copy)
@@ -1,4 +1,4 @@
-/*	$NetBSD: strlen.S,v 1.1 2005/12/20 19:28:50 christos Exp $	*/
+/*	$NetBSD: strlen.S,v 1.2 2009/12/14 00:39:00 matt Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 
 #if defined(LIBC_SCCS) && !defined(lint)
 	ASMSTR("from: @(#)strlen.s	8.1 (Berkeley) 6/4/93")
-	ASMSTR("$NetBSD: strlen.S,v 1.1 2005/12/20 19:28:50 christos Exp $")
+	ASMSTR("$NetBSD: strlen.S,v 1.2 2009/12/14 00:39:00 matt Exp $")
 #endif /* LIBC_SCCS and not lint */
 
 #ifdef __ABICALLS__
@@ -45,11 +45,11 @@
 #endif
 
 LEAF(strlen)
-	addu	v1, a0, 1
+	PTR_ADDU	v1, a0, 1
 1:
-	lb	v0, 0(a0)		# get byte from string
-	addu	a0, a0, 1		# increment pointer
-	bne	v0, zero, 1b		# continue if not end
-	subu	v0, a0, v1		# compute length - 1 for '\0' char
-	j	ra
+	lb		v0, 0(a0)	# get byte from string
+	PTR_ADDU	a0, a0, 1	# increment pointer
+	bne		v0, zero, 1b	# continue if not end
+	PTR_SUBU 	v0, a0, v1	# compute length - 1 for '\0' char
+	j		ra
 END(strlen)
Index: lib/libc/mips/string/strcmp.S
===================================================================
--- lib/libc/mips/string/strcmp.S	(revision 209040)
+++ lib/libc/mips/string/strcmp.S	(working copy)
@@ -1,4 +1,4 @@
-/*	$NetBSD: strcmp.S,v 1.1 2005/12/20 19:28:50 christos Exp $	*/
+/*	$NetBSD: strcmp.S,v 1.2 2009/12/14 00:39:00 matt Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 
 #if defined(LIBC_SCCS) && !defined(lint)
 	ASMSTR("from: @(#)strcmp.s	8.1 (Berkeley) 6/4/93")
-	ASMSTR("$NetBSD: strcmp.S,v 1.1 2005/12/20 19:28:50 christos Exp $")
+	ASMSTR("$NetBSD: strcmp.S,v 1.2 2009/12/14 00:39:00 matt Exp $")
 #endif /* LIBC_SCCS and not lint */
 
 #ifdef __ABICALLS__
@@ -55,9 +55,9 @@
 	bne	t0, t1, NotEq
 	lbu	t0, 1(a0)		# unroll loop
 	lbu	t1, 1(a1)
-	add	a0, a0, 2
+	PTR_ADD	a0, a0, 2
 	beq	t0, zero, LessOrEq	# end of first string?
-	add	a1, a1, 2
+	PTR_ADD	a1, a1, 2
 	beq	t0, t1, 1b
 NotEq:
 	subu	v0, t0, t1
Index: lib/libc/mips/string/rindex.S
===================================================================
--- lib/libc/mips/string/rindex.S	(revision 209040)
+++ lib/libc/mips/string/rindex.S	(working copy)
@@ -45,13 +45,13 @@
 #endif
 
 LEAF(rindex)
-	move	v0, zero		# default if not found
+	move		v0, zero		# default if not found
 1:
-	lbu	a3, 0(a0)		# get a byte
-	addu	a0, a0, 1
-	bne	a3, a1, 2f
-	subu	v0, a0, 1		# save address of last match
+	lbu		a3, 0(a0)		# get a byte
+	PTR_ADDU	a0, a0, 1
+	bne		a3, a1, 2f
+	PTR_SUBU	v0, a0, 1		# save address of last match
 2:
-	bne	a3, zero, 1b		# continue if not end
-	j	ra
+	bne		a3, zero, 1b		# continue if not end
+	j		ra
 END(rindex)
Index: lib/libc/mips/string/bcopy.S
===================================================================
--- lib/libc/mips/string/bcopy.S	(revision 209040)
+++ lib/libc/mips/string/bcopy.S	(working copy)
@@ -1,4 +1,4 @@
-/*	$NetBSD: bcopy.S,v 1.2 2005/12/27 11:23:53 tsutsui Exp $	*/
+/*	$NetBSD: bcopy.S,v 1.3 2009/12/14 00:39:00 matt Exp $	*/
 
 /*
  * Mach Operating System
@@ -38,9 +38,15 @@
 #include <machine/asm.h>
 __FBSDID("$FreeBSD$");
 
+#define _LOCORE		/* XXX not really, just assembly-code source */
+#include <machine/endian.h>
+
 #if defined(LIBC_SCCS) && !defined(lint)
+#if 0
 	ASMSTR("from: @(#)mips_bcopy.s	2.2 CMU 18/06/93")
-	ASMSTR("$NetBSD: bcopy.S,v 1.2 2005/12/27 11:23:53 tsutsui Exp $")
+#else
+	ASMSTR("$NetBSD: bcopy.S,v 1.3 2009/12/14 00:39:00 matt Exp $")
+#endif
 #endif /* LIBC_SCCS and not lint */
 
 #ifdef __ABICALLS__
@@ -99,71 +105,72 @@
 	 *	copy is alignable.  eg if src and dest are both
 	 *	on a halfword boundary.
 	 */
-	andi	t1,DSTREG,3		# get last 3 bits of dest
-	bne	t1,zero,3f
-	andi	t0,SRCREG,3		# get last 3 bits of src
-	bne	t0,zero,5f
+	andi		t1,DSTREG,(SZREG-1)	# get last bits of dest
+	bne		t1,zero,3f		# dest unaligned
+	andi		t0,SRCREG,(SZREG-1)	# get last bits of src
+	bne		t0,zero,5f
 
 	/*
-	 *	Forward aligned->aligned copy, 8*4 bytes at a time.
+	 *	Forward aligned->aligned copy, 8 words at a time.
 	 */
-	li	AT,-32
-	and	t0,SIZEREG,AT		# count truncated to multiple of 32 */
-	addu	a3,SRCREG,t0		# run fast loop up to this address
-	sltu	AT,SRCREG,a3		# any work to do?
-	beq	AT,zero,2f
-	subu	SIZEREG,t0
+98:
+	li		AT,-(SZREG*8)
+	and		t0,SIZEREG,AT		# count truncated to multiples
+	PTR_ADDU	a3,SRCREG,t0		# run fast loop up to this addr
+	sltu		AT,SRCREG,a3		# any work to do?
+	beq		AT,zero,2f
+	PTR_SUBU	SIZEREG,t0
 
 	/*
 	 *	loop body
 	 */
 1:	# cp
-	lw	t3,0(SRCREG)
-	lw	v1,4(SRCREG)
-	lw	t0,8(SRCREG)
-	lw	t1,12(SRCREG)
-	addu	SRCREG,32
-	sw	t3,0(DSTREG)
-	sw	v1,4(DSTREG)
-	sw	t0,8(DSTREG)
-	sw	t1,12(DSTREG)
-	lw	t1,-4(SRCREG)
-	lw	t0,-8(SRCREG)
-	lw	v1,-12(SRCREG)
-	lw	t3,-16(SRCREG)
-	addu	DSTREG,32
-	sw	t1,-4(DSTREG)
-	sw	t0,-8(DSTREG)
-	sw	v1,-12(DSTREG)
-	bne	SRCREG,a3,1b
-	sw	t3,-16(DSTREG)
+	REG_L		t3,(0*SZREG)(SRCREG)
+	REG_L		v1,(1*SZREG)(SRCREG)
+	REG_L		t0,(2*SZREG)(SRCREG)
+	REG_L		t1,(3*SZREG)(SRCREG)
+	PTR_ADDU	SRCREG,SZREG*8
+	REG_S		t3,(0*SZREG)(DSTREG)
+	REG_S		v1,(1*SZREG)(DSTREG)
+	REG_S		t0,(2*SZREG)(DSTREG)
+	REG_S		t1,(3*SZREG)(DSTREG)
+	REG_L		t1,(-1*SZREG)(SRCREG)
+	REG_L		t0,(-2*SZREG)(SRCREG)
+	REG_L		v1,(-3*SZREG)(SRCREG)
+	REG_L		t3,(-4*SZREG)(SRCREG)
+	PTR_ADDU	DSTREG,SZREG*8
+	REG_S		t1,(-1*SZREG)(DSTREG)
+	REG_S		t0,(-2*SZREG)(DSTREG)
+	REG_S		v1,(-3*SZREG)(DSTREG)
+	bne		SRCREG,a3,1b
+	REG_S		t3,(-4*SZREG)(DSTREG)
 
 	/*
 	 *	Copy a word at a time, no loop unrolling.
 	 */
 2:	# wordcopy
-	andi	t2,SIZEREG,3		# get byte count / 4
-	subu	t2,SIZEREG,t2		# t2 = number of words to copy * 4
-	beq	t2,zero,3f
-	addu	t0,SRCREG,t2		# stop at t0
-	subu	SIZEREG,SIZEREG,t2
+	andi		t2,SIZEREG,(SZREG-1)	# get byte count / SZREG
+	PTR_SUBU	t2,SIZEREG,t2		# t2 = words to copy * SZREG
+	beq		t2,zero,3f
+	PTR_ADDU	t0,SRCREG,t2		# stop at t0
+	PTR_SUBU	SIZEREG,SIZEREG,t2
 1:
-	lw	t3,0(SRCREG)
-	addu	SRCREG,4
-	sw	t3,0(DSTREG)
-	bne	SRCREG,t0,1b
-	addu	DSTREG,4
+	REG_L		t3,0(SRCREG)
+	PTR_ADDU	SRCREG,SZREG
+	REG_S		t3,0(DSTREG)
+	bne		SRCREG,t0,1b
+	PTR_ADDU	DSTREG,SZREG
 
 3:	# bytecopy
-	beq	SIZEREG,zero,4f	# nothing left to do?
+	beq		SIZEREG,zero,4f		# nothing left to do?
 	nop
 1:
-	lb	t3,0(SRCREG)
-	addu	SRCREG,1
-	sb	t3,0(DSTREG)
-	subu	SIZEREG,1
-	bgtz	SIZEREG,1b
-	addu	DSTREG,1
+	lb		t3,0(SRCREG)
+	PTR_ADDU	SRCREG,1
+	sb		t3,0(DSTREG)
+	PTR_SUBU	SIZEREG,1
+	bgtz		SIZEREG,1b
+	PTR_ADDU	DSTREG,1
 
 4:	# copydone
 	j	ra
@@ -173,96 +180,91 @@
 	 *	Copy from unaligned source to aligned dest.
 	 */
 5:	# destaligned
-	andi	t0,SIZEREG,3		# t0 = bytecount mod 4
-	subu	a3,SIZEREG,t0		# number of words to transfer
-	beq	a3,zero,3b
+	andi		t0,SIZEREG,(SZREG-1)	# t0 = bytecount mod SZREG
+	PTR_SUBU	a3,SIZEREG,t0		# number of words to transfer
+	beq		a3,zero,3b
 	nop
-	move	SIZEREG,t0		# this many to do after we are done
-	addu	a3,SRCREG,a3		# stop point
+	move		SIZEREG,t0		# this many to do after we are done
+	PTR_ADDU	a3,SRCREG,a3		# stop point
 
 1:
-#ifdef __MIPSEB__
-	lwl	t3,0(SRCREG)
-	lwr	t3,3(SRCREG)
-#else
-	lwr	t3,0(SRCREG)
-	lwl	t3,3(SRCREG)
-#endif
-	addi	SRCREG,4
-	sw	t3,0(DSTREG)
-	bne	SRCREG,a3,1b
-	addi	DSTREG,4
+	REG_LHI		t3,0(SRCREG)
+	REG_LLO		t3,SZREG-1(SRCREG)
+	PTR_ADDI	SRCREG,SZREG
+	REG_S		t3,0(DSTREG)
+	bne		SRCREG,a3,1b
+	PTR_ADDI	DSTREG,SZREG
 
-	j	3b
+	b		3b
 	nop
 
 6:	# backcopy -- based on above
-	addu	SRCREG,SIZEREG
-	addu	DSTREG,SIZEREG
-	andi	t1,DSTREG,3		# get last 3 bits of dest
-	bne	t1,zero,3f
-	andi	t0,SRCREG,3		# get last 3 bits of src
-	bne	t0,zero,5f
+	PTR_ADDU	SRCREG,SIZEREG
+	PTR_ADDU	DSTREG,SIZEREG
+	andi		t1,DSTREG,SZREG-1	# get last 3 bits of dest
+	bne		t1,zero,3f
+	andi		t0,SRCREG,SZREG-1	# get last 3 bits of src
+	bne		t0,zero,5f
 
 	/*
 	 *	Forward aligned->aligned copy, 8*4 bytes at a time.
 	 */
-	li	AT,-32
-	and	t0,SIZEREG,AT		# count truncated to multiple of 32
-	beq	t0,zero,2f		# any work to do?
-	subu	SIZEREG,t0
-	subu	a3,SRCREG,t0
+	li		AT,(-8*SZREG)
+	and		t0,SIZEREG,AT		# count truncated to multiple of 32
+	beq		t0,zero,2f		# any work to do?
+	PTR_SUBU	SIZEREG,t0
+	PTR_SUBU	a3,SRCREG,t0
 
 	/*
 	 *	loop body
 	 */
 1:	# cp
-	lw	t3,-16(SRCREG)
-	lw	v1,-12(SRCREG)
-	lw	t0,-8(SRCREG)
-	lw	t1,-4(SRCREG)
-	subu	SRCREG,32
-	sw	t3,-16(DSTREG)
-	sw	v1,-12(DSTREG)
-	sw	t0,-8(DSTREG)
-	sw	t1,-4(DSTREG)
-	lw	t1,12(SRCREG)
-	lw	t0,8(SRCREG)
-	lw	v1,4(SRCREG)
-	lw	t3,0(SRCREG)
-	subu	DSTREG,32
-	sw	t1,12(DSTREG)
-	sw	t0,8(DSTREG)
-	sw	v1,4(DSTREG)
-	bne	SRCREG,a3,1b
-	sw	t3,0(DSTREG)
+	REG_L		t3,(-4*SZREG)(SRCREG)
+	REG_L		v1,(-3*SZREG)(SRCREG)
+	REG_L		t0,(-2*SZREG)(SRCREG)
+	REG_L		t1,(-1*SZREG)(SRCREG)
+	PTR_SUBU	SRCREG,8*SZREG
+	REG_S		t3,(-4*SZREG)(DSTREG)
+	REG_S		v1,(-3*SZREG)(DSTREG)
+	REG_S		t0,(-2*SZREG)(DSTREG)
+	REG_S		t1,(-1*SZREG)(DSTREG)
+	REG_L		t1,(3*SZREG)(SRCREG)
+	REG_L		t0,(2*SZREG)(SRCREG)
+	REG_L		v1,(1*SZREG)(SRCREG)
+	REG_L		t3,(0*SZREG)(SRCREG)
+	PTR_SUBU	DSTREG,8*SZREG
+	REG_S		t1,(3*SZREG)(DSTREG)
+	REG_S		t0,(2*SZREG)(DSTREG)
+	REG_S		v1,(1*SZREG)(DSTREG)
+	bne		SRCREG,a3,1b
+	REG_S		t3,(0*SZREG)(DSTREG)
 
 	/*
 	 *	Copy a word at a time, no loop unrolling.
 	 */
 2:	# wordcopy
-	andi	t2,SIZEREG,3		# get byte count / 4
-	subu	t2,SIZEREG,t2		# t2 = number of words to copy * 4
-	beq	t2,zero,3f
-	subu	t0,SRCREG,t2		# stop at t0
-	subu	SIZEREG,SIZEREG,t2
+	andi		t2,SIZEREG,SZREG-1	# get byte count / 4
+	PTR_SUBU	t2,SIZEREG,t2		# t2 = number of words to copy
+	beq		t2,zero,3f
+	PTR_SUBU	t0,SRCREG,t2		# stop at t0
+	PTR_SUBU	SIZEREG,SIZEREG,t2
 1:
-	lw	t3,-4(SRCREG)
-	subu	SRCREG,4
-	sw	t3,-4(DSTREG)
-	bne	SRCREG,t0,1b
-	subu	DSTREG,4
+	REG_L		t3,-SZREG(SRCREG)
+	PTR_SUBU	SRCREG,SZREG
+	REG_S		t3,-SZREG(DSTREG)
+	bne		SRCREG,t0,1b
+	PTR_SUBU	DSTREG,SZREG
 
 3:	# bytecopy
-	beq	SIZEREG,zero,4f		# nothing left to do?
+	beq		SIZEREG,zero,4f		# nothing left to do?
 	nop
 1:
-	lb	t3,-1(SRCREG)
-	subu	SRCREG,1
-	sb	t3,-1(DSTREG)
-	subu	SIZEREG,1
-	bgtz	SIZEREG,1b
-	subu	DSTREG,1
+	lb		t3,-1(SRCREG)
+	PTR_SUBU	SRCREG,1
+	sb		t3,-1(DSTREG)
+	PTR_SUBU	SIZEREG,1
+	bgtz		SIZEREG,1b
+	PTR_SUBU	DSTREG,1
 
 4:	# copydone
 	j	ra
@@ -272,27 +274,22 @@
 	 *	Copy from unaligned source to aligned dest.
 	 */
 5:	# destaligned
-	andi	t0,SIZEREG,3		# t0 = bytecount mod 4
-	subu	a3,SIZEREG,t0		# number of words to transfer
-	beq	a3,zero,3b
+	andi		t0,SIZEREG,SZREG-1	# t0 = bytecount mod 4
+	PTR_SUBU	a3,SIZEREG,t0		# number of words to transfer
+	beq		a3,zero,3b
 	nop
-	move	SIZEREG,t0		# this many to do after we are done
-	subu	a3,SRCREG,a3		# stop point
+	move		SIZEREG,t0		# this many to do after we are done
+	PTR_SUBU	a3,SRCREG,a3		# stop point
 
 1:
-#ifdef __MIPSEB__
-	lwl	t3,-4(SRCREG)
-	lwr	t3,-1(SRCREG)
-#else
-	lwr	t3,-4(SRCREG)
-	lwl	t3,-1(SRCREG)
-#endif
-	subu	SRCREG,4
-	sw	t3,-4(DSTREG)
-	bne	SRCREG,a3,1b
-	subu	DSTREG,4
+	REG_LHI		t3,-SZREG(SRCREG)
+	REG_LLO		t3,-1(SRCREG)
+	PTR_SUBU	SRCREG,SZREG
+	REG_S		t3,-SZREG(DSTREG)
+	bne		SRCREG,a3,1b
+	PTR_SUBU	DSTREG,SZREG
 
-	j	3b
+	b		3b
 	nop
 
 	.set	reorder
Index: lib/libc/mips/gen/_setjmp.S
===================================================================
--- lib/libc/mips/gen/_setjmp.S	(revision 209040)
+++ lib/libc/mips/gen/_setjmp.S	(working copy)
@@ -1,4 +1,4 @@
-/*	$NetBSD: _setjmp.S,v 1.20 2005/10/07 17:16:40 tsutsui Exp $	*/
+/*	$NetBSD: _setjmp.S,v 1.20.34.5 2010/02/03 23:46:47 matt Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -36,15 +36,16 @@
 __FBSDID("$FreeBSD$");
 #include <machine/regnum.h>
 
+#include "SYS.h"
+
 #if defined(LIBC_SCCS) && !defined(lint)
-	ASMSTR("from: @(#)_setjmp.s	8.1 (Berkeley) 6/4/93")
-	ASMSTR("$NetBSD: _setjmp.S,v 1.20 2005/10/07 17:16:40 tsutsui Exp $")
+#if 0
+	RCSID("from: @(#)_setjmp.s	8.1 (Berkeley) 6/4/93")
+#else
+	RCSID("$NetBSD: _setjmp.S,v 1.20.34.5 2010/02/03 23:46:47 matt Exp $")
+#endif
 #endif /* LIBC_SCCS and not lint */
 
-#ifdef __ABICALLS__
-	.abicalls
-#endif
-
 /*
  * C library -- _setjmp, _longjmp
  *
@@ -56,62 +57,70 @@
  * The previous signal state is NOT restored.
  */
 
+	.set	noreorder
 
 LEAF(_setjmp)
-#ifdef __ABICALLS__ 
-	.set	noreorder
-	.cpload t9
-	subu	sp, sp, CALLFRAME_SIZ	# allocate stack frame
-	.cprestore 16
+	REG_PROLOGUE
+	REG_LI	v0, _JB_MAGIC__SETJMP
+	REG_S	v0, (_JB_MAGIC  * SZREG)(a0)
+	REG_S	ra, (_JB_REG_RA * SZREG)(a0)
+	REG_S	s0, (_JB_REG_S0 * SZREG)(a0)
+	REG_S	s1, (_JB_REG_S1 * SZREG)(a0)
+	REG_S	s2, (_JB_REG_S2 * SZREG)(a0)
+	REG_S	s3, (_JB_REG_S3 * SZREG)(a0)
+	REG_S	s4, (_JB_REG_S4 * SZREG)(a0)
+	REG_S	s5, (_JB_REG_S5 * SZREG)(a0)
+	REG_S	s6, (_JB_REG_S6 * SZREG)(a0)
+	REG_S	s7, (_JB_REG_S7 * SZREG)(a0)
+	REG_S	s8, (_JB_REG_S8 * SZREG)(a0)
+#if defined(__mips_n32) || defined(__mips_n64)
+	REG_S	gp, (_JB_REG_GP * SZREG)(a0)	# newabi gp is callee-saved
 #endif
-	li	v0, _JB_MAGIC__SETJMP
-	sw	v0, (_JB_MAGIC  * SZREG)(a0)
-	sw	ra, (_JB_REG_RA * SZREG)(a0)
-	sw	s0, (_JB_REG_S0 * SZREG)(a0)
-	sw	s1, (_JB_REG_S1 * SZREG)(a0)
-	sw	s2, (_JB_REG_S2 * SZREG)(a0)
-	sw	s3, (_JB_REG_S3 * SZREG)(a0)
-	sw	s4, (_JB_REG_S4 * SZREG)(a0)
-	sw	s5, (_JB_REG_S5 * SZREG)(a0)
-	sw	s6, (_JB_REG_S6 * SZREG)(a0)
-	sw	s7, (_JB_REG_S7 * SZREG)(a0)
-	sw	s8, (_JB_REG_S8 * SZREG)(a0)
-#ifdef __ABICALLS__
-	addu	sp, sp, CALLFRAME_SIZ	# un-allocate the stack frame
-#endif	
-	sw	sp, (_JB_REG_SP * SZREG)(a0)
+	REG_S	sp, (_JB_REG_SP * SZREG)(a0)
+	REG_EPILOGUE
+
 	j	ra
 	move	v0, zero
 END(_setjmp)
 
 LEAF(_longjmp)
-#ifdef __ABICALLS__ 
-	.set	noreorder
-	.cpload t9
-	subu	sp, sp, CALLFRAME_SIZ	# allocate stack frame
-	.cprestore 16
-#endif  
-	lw	v0, (_JB_MAGIC  * SZREG)(a0)
-	lw	ra, (_JB_REG_RA * SZREG)(a0)
-	li	t0, _JB_MAGIC__SETJMP
-	bne	v0, t0, botch		# jump if error
-	lw	s0, (_JB_REG_S0 * SZREG)(a0)
-	lw	s1, (_JB_REG_S1 * SZREG)(a0)
-	lw	s2, (_JB_REG_S2 * SZREG)(a0)
-	lw	s3, (_JB_REG_S3 * SZREG)(a0)
-	lw	s4, (_JB_REG_S4 * SZREG)(a0)
-	lw	s5, (_JB_REG_S5 * SZREG)(a0)
-	lw	s6, (_JB_REG_S6 * SZREG)(a0)
-	lw	s7, (_JB_REG_S7 * SZREG)(a0)
-	lw	sp, (_JB_REG_SP * SZREG)(a0)
-	lw	s8, (_JB_REG_S8 * SZREG)(a0)
+	PIC_PROLOGUE(_longjmp)
+	PTR_SUBU	sp, sp, CALLFRAME_SIZ
+	SAVE_GP(CALLFRAME_GP)
 
+	REG_PROLOGUE
+	REG_L		v0, (_JB_MAGIC  * SZREG)(a0)	# get magic number
+	REG_L		ra, (_JB_REG_RA * SZREG)(a0)
+	REG_LI		t0, _JB_MAGIC__SETJMP
+	bne		v0, t0, botch		# jump if error
+	PTR_ADDU	sp, sp, CALLFRAME_SIZ	# does not matter, sanity
+	REG_L		s0, (_JB_REG_S0 * SZREG)(a0)
+	REG_L		s1, (_JB_REG_S1 * SZREG)(a0)
+	REG_L		s2, (_JB_REG_S2 * SZREG)(a0)
+	REG_L		s3, (_JB_REG_S3 * SZREG)(a0)
+	REG_L		s4, (_JB_REG_S4 * SZREG)(a0)
+	REG_L		s5, (_JB_REG_S5 * SZREG)(a0)
+	REG_L		s6, (_JB_REG_S6 * SZREG)(a0)
+	REG_L		s7, (_JB_REG_S7 * SZREG)(a0)
+#if defined(__mips_n32) || defined(__mips_n64)
+	REG_L		gp, (_JB_REG_GP * SZREG)(a0)
+#endif
+	REG_L		sp, (_JB_REG_SP * SZREG)(a0)
+	REG_L		s8, (_JB_REG_S8 * SZREG)(a0)
+
+	REG_EPILOGUE
+	move	v0, a1			# get return value in 1st arg
 	j	ra
-	move	v0, a1
+	nop
 
 botch:
-	jal	_C_LABEL(longjmperror)
+	/*
+	 * We know we aren't returning so we don't care about restoring
+	 * our caller's GP.
+	 */
+	PTR_LA	t9, _C_LABEL(longjmperror)
+	jalr	t9
 	nop
-	jal	_C_LABEL(abort)
-	nop
+
+	PIC_TAILCALL(abort)
 END(_longjmp)
Index: lib/libc/mips/gen/setjmp.S
===================================================================
--- lib/libc/mips/gen/setjmp.S	(revision 209040)
+++ lib/libc/mips/gen/setjmp.S	(working copy)
@@ -41,6 +41,8 @@
 	ASMSTR("$NetBSD: setjmp.S,v 1.17 2005/09/17 11:49:39 tsutsui Exp $")
 #endif /* LIBC_SCCS and not lint */
 
+#include "SYS.h"
+
 #ifdef __ABICALLS__
 	.abicalls
 #endif
@@ -61,100 +63,102 @@
 
 NESTED(setjmp, SETJMP_FRAME_SIZE, ra)
 	.mask	0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ)
-	.set	noreorder
-#ifdef __ABICALLS__
-	.cpload	t9
-#endif
-	subu	sp, sp, SETJMP_FRAME_SIZE	# allocate stack frame
-#ifdef __ABICALLS__
-	.cprestore 16
-#endif
-	sw	ra, CALLFRAME_RA(sp)		# save RA
-	sw	a0, CALLFRAME_SIZ(sp)		# store env
+	SETUP_GP
+	PTR_SUBU sp, sp, SETJMP_FRAME_SIZE	# allocate stack frame
+	SAVE_GP(CALLFRAME_GP)
+	SETUP_GP64(CALLFRAME_GP, setjmp)
 
+	REG_S	ra, CALLFRAME_RA(sp)		# save RA
+	REG_S	a0, CALLFRAME_SIZ(sp)		# store env
+
 	/* Get the signal mask. */
-	addu	a2, a0, _JB_SIGMASK * SZREG	# &oenv
+	PTR_ADDU a2, a0, _JB_SIGMASK * SZREG	# &oenv
 	li	a0, 1				# SIG_SETBLOCK
 	move	a1, zero			# &env == 0
-	la	t9, _C_LABEL(sigprocmask)	# get current signal mask
-	jal	t9
-	nop
+	PTR_LA	t9, _C_LABEL(sigprocmask)	# get current signal mask
+	jalr	t9
 
-	lw	a0, CALLFRAME_SIZ(sp)		# restore env pointer
-	lw	ra, CALLFRAME_RA(sp)		# restore RA
-	addu	sp, sp, SETJMP_FRAME_SIZE	# pop stack frame
+	RESTORE_GP64
+	REG_L	a0, CALLFRAME_SIZ(sp)		# restore env pointer
+	REG_L	ra, CALLFRAME_RA(sp)		# restore RA
+	PTR_ADDU sp, sp, SETJMP_FRAME_SIZE	# pop stack frame
 
-	li	v0, _JB_MAGIC_SETJMP
-	sw	v0, (_JB_MAGIC  * SZREG)(a0)
-	sw	ra, (_JB_REG_RA * SZREG)(a0)
-	sw	s0, (_JB_REG_S0 * SZREG)(a0)
-	sw	s1, (_JB_REG_S1 * SZREG)(a0)
-	sw	s2, (_JB_REG_S2 * SZREG)(a0)
-	sw	s3, (_JB_REG_S3 * SZREG)(a0)
-	sw	s4, (_JB_REG_S4 * SZREG)(a0)
-	sw	s5, (_JB_REG_S5 * SZREG)(a0)
-	sw	s6, (_JB_REG_S6 * SZREG)(a0)
-	sw	s7, (_JB_REG_S7 * SZREG)(a0)
-	sw	sp, (_JB_REG_SP * SZREG)(a0)
-	sw	s8, (_JB_REG_S8 * SZREG)(a0)
+	REG_LI	v0, _JB_MAGIC_SETJMP
+	REG_S	v0, (_JB_MAGIC  * SZREG)(a0)
+	REG_S	ra, (_JB_REG_RA * SZREG)(a0)
+	REG_S	s0, (_JB_REG_S0 * SZREG)(a0)
+	REG_S	s1, (_JB_REG_S1 * SZREG)(a0)
+	REG_S	s2, (_JB_REG_S2 * SZREG)(a0)
+	REG_S	s3, (_JB_REG_S3 * SZREG)(a0)
+	REG_S	s4, (_JB_REG_S4 * SZREG)(a0)
+	REG_S	s5, (_JB_REG_S5 * SZREG)(a0)
+	REG_S	s6, (_JB_REG_S6 * SZREG)(a0)
+	REG_S	s7, (_JB_REG_S7 * SZREG)(a0)
+	REG_S	sp, (_JB_REG_SP * SZREG)(a0)
+	REG_S	s8, (_JB_REG_S8 * SZREG)(a0)
+#if defined(__mips_n32) || defined(__mips_n64)
+	REG_S	gp, (_JB_REG_GP * SZREG)(a0)
+#endif
 
 	move	v0, zero
-	j	ra
+	jr	ra
 END(setjmp)
 
 #define LONGJMP_FRAME_SIZE	(CALLFRAME_SIZ + (SZREG * 2))
 
 NESTED(longjmp, LONGJMP_FRAME_SIZE, ra)
 	.mask	0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ)
-	.set	noreorder
-#ifdef __ABICALLS__
-	.cpload	t9
-#endif
-	subu	sp, sp, LONGJMP_FRAME_SIZE	# allocate stack frame
-#ifdef __ABICALLS__
-	.cprestore 16
-#endif
-	sw	ra, CALLFRAME_RA(sp)		# save RA
-	lw	v0, (_JB_MAGIC  * SZREG)(a0)
-	li	t0, _JB_MAGIC_SETJMP
+	PIC_PROLOGUE(longjmp)
+	PTR_SUBU sp, sp, LONGJMP_FRAME_SIZE	# allocate stack frame
+	SAVE_GP(CALLFRAME_GP)
+
+	REG_S	ra, CALLFRAME_RA(sp)		# save RA
+	REG_L	v0, (_JB_MAGIC  * SZREG)(a0)
+	REG_LI	t0, _JB_MAGIC_SETJMP
 	bne	v0, t0, botch		# jump if error
 	nop
 
-	sw	a0, CALLFRAME_SIZ(sp)		# save env
-	sw	a1, (CALLFRAME_SIZ + SZREG)(sp)	# save return value
+	REG_S	a0, CALLFRAME_SIZ(sp)		# save env
+	REG_S	a1, (CALLFRAME_SIZ + SZREG)(sp)	# save return value
 
 	# set sigmask
-	addu	a1, a0, _JB_SIGMASK * SZREG	# &set
+	PTR_ADDU a1, a0, _JB_SIGMASK * SZREG	# &set
 	move	a2, zero			# &oset == NULL
 	li	a0, 3				# SIG_SETMASK
-	la	t9,_C_LABEL(sigprocmask)	# set current signal mask
+	PTR_LA	t9,_C_LABEL(sigprocmask)	# set current signal mask
 	jal	t9
 	nop
 
-	lw	a0, CALLFRAME_SIZ(sp)		# restore env
-	lw	a1, (CALLFRAME_SIZ + SZREG)(sp)	# restore return value
+	REG_L	a0, CALLFRAME_SIZ(sp)		# restore env
+	REG_L	a1, (CALLFRAME_SIZ + SZREG)(sp)	# restore return value
 
-	lw	ra, (_JB_REG_RA * SZREG)(a0)
-	lw	s0, (_JB_REG_S0 * SZREG)(a0)
-	lw	s1, (_JB_REG_S1 * SZREG)(a0)
-	lw	s2, (_JB_REG_S2 * SZREG)(a0)
-	lw	s3, (_JB_REG_S3 * SZREG)(a0)
-	lw	s4, (_JB_REG_S4 * SZREG)(a0)
-	lw	s5, (_JB_REG_S5 * SZREG)(a0)
-	lw	s6, (_JB_REG_S6 * SZREG)(a0)
-	lw	s7, (_JB_REG_S7 * SZREG)(a0)
-	lw	sp, (_JB_REG_SP * SZREG)(a0)
-	lw	s8, (_JB_REG_S8 * SZREG)(a0)
+	REG_L	ra, (_JB_REG_RA * SZREG)(a0)
+	REG_L	s0, (_JB_REG_S0 * SZREG)(a0)
+	REG_L	s1, (_JB_REG_S1 * SZREG)(a0)
+	REG_L	s2, (_JB_REG_S2 * SZREG)(a0)
+	REG_L	s3, (_JB_REG_S3 * SZREG)(a0)
+	REG_L	s4, (_JB_REG_S4 * SZREG)(a0)
+	REG_L	s5, (_JB_REG_S5 * SZREG)(a0)
+	REG_L	s6, (_JB_REG_S6 * SZREG)(a0)
+	REG_L	s7, (_JB_REG_S7 * SZREG)(a0)
+	REG_L	sp, (_JB_REG_SP * SZREG)(a0)
+	REG_L	s8, (_JB_REG_S8 * SZREG)(a0)
+#if defined(__mips_n32) || defined(__mips_n64)
+	REG_L	gp, (_JB_REG_GP * SZREG)(a0)
+#endif
+
 	move	v0, a1
 	j	ra
 	nop
 
 botch:
-	la	t9, _C_LABEL(longjmperror)
-	jal	t9
+	/*
+	 * We know we aren't returning so we don't care about restoring
+	 * our caller's GP.
+	 */
+	PTR_LA	t9, _C_LABEL(longjmperror)
+	jalr	t9
 	nop
 
-	la	t9, _C_LABEL(abort)
-	jal	t9
-	nop
+	PIC_TAILCALL(abort)
 END(longjmp)
Index: lib/libc/mips/gen/sigsetjmp.S
===================================================================
--- lib/libc/mips/gen/sigsetjmp.S	(revision 209040)
+++ lib/libc/mips/gen/sigsetjmp.S	(working copy)
@@ -40,6 +40,8 @@
 	ASMSTR("$NetBSD: sigsetjmp.S,v 1.8 2005/09/17 11:49:39 tsutsui Exp $")
 #endif /* LIBC_SCCS and not lint */
 
+#include "SYS.h"
+
 #ifdef __ABICALLS__
 	.abicalls
 #endif
@@ -57,30 +59,19 @@
  */
 
 LEAF(sigsetjmp)
-#ifdef __ABICALLS__
-	.set	noreorder
-	.cpload	t9
-	.set	reorder
-#endif
+	PIC_PROLOGUE(sigsetjmp)
+
 	bne	a1, 0x0, 1f			# do saving of signal mask?
-	la	t9, _setjmp
-	jr t9
+	PIC_TAILCALL(_setjmp)
 
-1:	la	t9, setjmp
-	jr t9
+1:	PIC_TAILCALL(setjmp)
 END(sigsetjmp)
 
 LEAF(siglongjmp)
-#ifdef __ABICALLS__
-	.set	noreorder
-	.cpload	t9
-	.set	reorder
-#endif
-	lw	t0, (_JB_MAGIC  * SZREG)(a0)
-	li	t1, _JB_MAGIC__SETJMP
+	PIC_PROLOGUE(siglongjmp)
+	REG_L	t0, (_JB_MAGIC  * SZREG)(a0)
+	REG_LI	t1, _JB_MAGIC__SETJMP
 	bne	t0, t1, 1f			# setjmp or _setjmp magic?
-	la	t9, _longjmp
-	jr	t9
-1:	la	t9, longjmp
-	jr	t9
+	PIC_TAILCALL(_longjmp)
+1:	PIC_TAILCALL(longjmp)
 END(siglongjmp)
Index: lib/libc/mips/sys/brk.S
===================================================================
--- lib/libc/mips/sys/brk.S	(revision 209040)
+++ lib/libc/mips/sys/brk.S	(working copy)
@@ -49,25 +49,23 @@
 _C_LABEL(minbrk):
 	.word	_C_LABEL(_end)
 
+	.text
 LEAF(__sys_brk)
 	WEAK_ALIAS(brk, __sys_brk)
 	WEAK_ALIAS(_brk, __sys_brk)
-#ifdef __ABICALLS__
-	.set	noreorder
-	.cpload	t9
-	.set	reorder
-#endif
-	lw	v0, _C_LABEL(minbrk)
+	PIC_PROLOGUE(__sys_brk)
+	PTR_LA	v0, _C_LABEL(minbrk)
+	PTR_L	v0, 0(v0)
 	bgeu	a0, v0, 1f
 	move	a0, v0		# dont allow break < minbrk
 1:
 	li	v0, SYS_break
 	syscall
 	bne	a3, zero, 2f
-	sw	a0, _C_LABEL(__curbrk)
+	PTR_LA	t0, _C_LABEL(__curbrk)
+	PTR_S	a0, 0(t0)
 	move	v0, zero
-	j	ra
+	PIC_RETURN()
 2:
-	la	t9, _C_LABEL(__cerror)
-	jr	t9
+	PIC_TAILCALL(__cerror)
 END(__sys_brk)
Index: lib/libc/mips/sys/ptrace.S
===================================================================
--- lib/libc/mips/sys/ptrace.S	(revision 209040)
+++ lib/libc/mips/sys/ptrace.S	(working copy)
@@ -41,32 +41,31 @@
 	ASMSTR("$NetBSD: ptrace.S,v 1.9 2003/08/07 16:42:17 agc Exp $")
 #endif /* LIBC_SCCS and not lint */
 
-LEAF(ptrace)
-	.frame	sp, 40, ra
-	.mask	0x80000000, -8
-#ifdef __ABICALLS__
-	.set    noreorder
-	.cpload t9
-	.set    reorder
-#endif
-	subu	sp, sp, 40
-	sw	ra,  32(sp)
-#ifdef __ABICALLS__
-	.cprestore 16
-#endif
-	la	t9, _C_LABEL(__error)	# locate address of errno
-	jalr	t9
-#ifdef __ABICALLS__
-	lw	gp, 16(sp)
-#endif
-	sw	zero, 0(v0)
-	lw	ra, 32(sp)
-	addu	sp, sp, 40
-	li	v0, SYS_ptrace
+NESTED_NOPROFILE(ptrace, CALLFRAME_SIZ, ra)
+	.mask	0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ)
+	SETUP_GP
+	PTR_SUBU	sp, sp, CALLFRAME_SIZ
+	SETUP_GP64(CALLFRAME_GP, ptrace)
+	SAVE_GP(CALLFRAME_GP)
+
+	PTR_S		ra, CALLFRAME_RA(sp)
+
+	PTR_LA		t9, _C_LABEL(__error)	# locate address of errno
+	jalr		t9
+
+	PTR_L		ra, CALLFRAME_RA(sp)
+	INT_S		zero, 0(v0)		# update errno value
+
+	li		v0, SYS_ptrace
 	syscall
-	bne	a3, zero, 1f
-	j	ra
-1:
-	la	t9, _C_LABEL(__cerror)
-	jr	t9
+
+	# Load __cerror's address using our gp, then restore it.
+	PTR_LA		t9, __cerror
+	RESTORE_GP64
+	PTR_ADDU	sp, sp, CALLFRAME_SIZ
+
+	bne		a3, zero, 1f
+
+	j		ra
+1:	j		t9
 END(ptrace)
Index: lib/libc/mips/sys/fork.S
===================================================================
--- lib/libc/mips/sys/fork.S	(revision 209040)
+++ lib/libc/mips/sys/fork.S	(working copy)
@@ -44,20 +44,14 @@
 LEAF(__sys_fork)
 	WEAK_ALIAS(fork, __sys_fork)
 	WEAK_ALIAS(_fork, __sys_fork)
-#ifdef __ABICALLS__
-	.set    noreorder
-	.cpload t9
-	.set    reorder
-#endif
-	fork = __sys_fork
+	PIC_PROLOGUE(__sys_fork)
 	li	v0, SYS_fork	# pid = fork()
 	syscall
 	bne	a3, zero, 2f
 	beq	v1, zero, 1f	# v1 == 0 in parent, 1 in child
 	move	v0, zero
 1:
-	j	ra
+	PIC_RETURN()
 2:
-	la	t9, _C_LABEL(__cerror)
-	jr	t9
+	PIC_TAILCALL(__cerror)
 END(__sys_fork)
Index: lib/libc/mips/sys/sbrk.S
===================================================================
--- lib/libc/mips/sys/sbrk.S	(revision 209040)
+++ lib/libc/mips/sys/sbrk.S	(working copy)
@@ -52,34 +52,22 @@
 LEAF(__sys_sbrk)
 	WEAK_ALIAS(sbrk, __sys_sbrk)
 	WEAK_ALIAS(_sbrk, __sys_sbrk)
-#ifdef __ABICALLS__
-	.set	noreorder
-	.cpload	t9
-	.set	reorder
-#endif
-	addu	sp, sp, -16
-	sw	s0, 0(sp)		# Preserve s0 value in stack
-					# it should be the same on return
-					# We can't use v1 as temporary
-					# register since syscall uses it
-					# to return 64-bit values
-	lw	s0, _C_LABEL(__curbrk)
-	li	v0, SYS_break
-	addu	a0, a0, s0		# compute current break
+	PIC_PROLOGUE(__sys_sbrk)
+	PTR_LA	t0, _C_LABEL(__curbrk)
+	PTR_L	t0, 0(t0)
+	PTR_ADDU a0, a0, t0
 
+	li	v0, SYS_break
 	syscall
 
 	bne	a3, zero, 1f
 	nop
-	move	v0, s0			# return old val of curbrk from above
-	lw	s0, 0(sp)
-	addu	sp, sp, 16
-	sw	a0, _C_LABEL(__curbrk)	# save current val of curbrk from above
+	move	v0, t0			# return old val of curbrk from above
+	PTR_LA	t0, _C_LABEL(__curbrk)
+	PTR_S	a0, 0(t0)		# save current val of curbrk from above
+	PIC_RETURN()
 	j	ra
 
 1:
-	lw	s0, 0(sp)
-	addu	sp, sp, 16
-	la	t9, _C_LABEL(__cerror)
-	jr	t9
+	PIC_TAILCALL(__cerror)
 END(__sys_sbrk)
Index: lib/libc/mips/sys/Ovfork.S
===================================================================
--- lib/libc/mips/sys/Ovfork.S	(revision 209040)
+++ lib/libc/mips/sys/Ovfork.S	(working copy)
@@ -49,21 +49,16 @@
  */
 
 LEAF(__sys_vfork)
-#ifdef __ABICALLS__
-	.set	noreorder
-	.cpload	t9
-	.set	reorder
-#endif
 	WEAK_ALIAS(vfork, __sys_vfork)
 	WEAK_ALIAS(_vfork, __sys_vfork)
+	PIC_PROLOGUE(__sys_vfork)
 	li	v0, SYS_vfork		# system call number for vfork
 	syscall
 	beq	a3, zero, 1f		# jump if no errors
-	la	t9, __cerror
-	jr	t9
+	PIC_TAILCALL(__cerror)
 1:
 	beq	v1, zero, 2f		# parent process ?
 	move	v0, zero		# return zero in child
 2:
-	j	ra
+	PIC_RETURN()
 END(__sys_vfork)
Index: lib/libc/mips/sys/exect.S
===================================================================
--- lib/libc/mips/sys/exect.S	(revision 209040)
+++ lib/libc/mips/sys/exect.S	(working copy)
@@ -41,16 +41,11 @@
 #endif /* LIBC_SCCS and not lint */
 
 LEAF(exect)
-#ifdef __ABICALLS__
-	.set    noreorder
-	.cpload t9
-	.set    reorder
-#endif
+	PIC_PROLOGUE(exect)
 	li	v0, SYS_execve
 	syscall
 	bne	a3, zero, 1f
-	j	ra
+	PIC_RETURN()
 1:
-	la      t9, _C_LABEL(__cerror)
-	jr      t9
+	PIC_TAILCALL(__cerror)
 END(exect)
Index: lib/libc/mips/sys/cerror.S
===================================================================
--- lib/libc/mips/sys/cerror.S	(revision 209040)
+++ lib/libc/mips/sys/cerror.S	(working copy)
@@ -1,4 +1,4 @@
-/*	$NetBSD: cerror.S,v 1.13 2003/08/07 16:42:17 agc Exp $	*/
+/*	$NetBSD: cerror.S,v 1.14 2009/12/14 01:07:42 matt Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,35 +37,36 @@
 #include "SYS.h"
 
 #if defined(LIBC_SCCS) && !defined(lint)
-	ASMSTR("from: @(#)cerror.s	8.1 (Berkeley) 6/16/93")
-	ASMSTR("$NetBSD: cerror.S,v 1.13 2003/08/07 16:42:17 agc Exp $")
+#if 0
+	RCSID("from: @(#)cerror.s	8.1 (Berkeley) 6/16/93")
+#else
+	RCSID("$NetBSD: cerror.S,v 1.14 2009/12/14 01:07:42 matt Exp $")
+#endif
 #endif /* LIBC_SCCS and not lint */
 
+	.globl	_C_LABEL(__error)
+NESTED_NOPROFILE(__cerror, CALLFRAME_SIZ, ra)
+	.mask	0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ)
+	SETUP_GP
+	PTR_SUBU	sp, sp, CALLFRAME_SIZ
+	SETUP_GP64(CALLFRAME_GP, __cerror)
+	SAVE_GP(CALLFRAME_GP)
 
-	/*
-	 * The __error() function is thread aware. For non-threaded
-	 * programs and the initial threaded in threaded programs,
-	 * it returns a pointer to the global errno variable.
-	 */
-	.globl  _C_LABEL(__error)
-	.type   _C_LABEL(__error),%function
+	PTR_S		ra, CALLFRAME_RA(sp)
+	REG_S		v0, CALLFRAME_S0(sp)	# save errno value
 
-LEAF(__cerror)
-	.frame sp, CALLFRAME_SIZ, ra
-	PIC_PROLOGUE(__cerror, t9)
-	subu	sp, sp, CALLFRAME_SIZ
-	.mask	0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ)
-	sw	ra, CALLFRAME_RA(sp)
-	sw	v0, 12(sp)		# save errno value
+	PTR_LA		t9, _C_LABEL(__error)	# locate address of errno
+	jalr		t9
 
-	la	t9, _C_LABEL(__error)	# locate address of errno
-	jalr	t9
+	REG_L		t0, CALLFRAME_S0(sp)
+	PTR_L		ra, CALLFRAME_RA(sp)
+	INT_S		t0, 0(v0)		# update errno value
 
-	lw	t0, 12(sp)
-	lw	ra, CALLFRAME_RA(sp)
-	sw	t0, 0(v0)		# update errno value
-	addiu	sp, sp, CALLFRAME_SIZ
-	li	v0, -1
-	li	v1, -1
-	j	ra
+	RESTORE_GP64
+	PTR_ADDU	sp, sp, CALLFRAME_SIZ
+
+	li		v0, -1
+	li		v1, -1
+
+	j		ra
 END(__cerror)
Index: lib/libc/mips/sys/pipe.S
===================================================================
--- lib/libc/mips/sys/pipe.S	(revision 209040)
+++ lib/libc/mips/sys/pipe.S	(working copy)
@@ -44,19 +44,14 @@
 LEAF(__sys_pipe)
 	WEAK_ALIAS(pipe, __sys_pipe)
 	WEAK_ALIAS(_pipe, __sys_pipe)
-#ifdef __ABICALLS__
-	.set    noreorder
-	.cpload t9
-	.set    reorder
-#endif
+	PIC_PROLOGUE(__sys_pipe)
 	li	v0, SYS_pipe	# pipe(fildes) int fildes[2];
 	syscall
 	bne	a3, zero, 1f
 	sw	v0, 0(a0)	# store the two file descriptors
 	sw	v1, 4(a0)
 	move	v0, zero
-	j	ra
+	PIC_RETURN()
 1:
-	la	t9, _C_LABEL(__cerror)
-	jr	t9
+	PIC_TAILCALL(__cerror)
 END(__sys_pipe)

[-- Attachment #3 --]
Index: lib/libc/mips/Symbol.map
===================================================================
--- lib/libc/mips/Symbol.map	(revision 209040)
+++ lib/libc/mips/Symbol.map	(working copy)
@@ -24,13 +24,9 @@
 	sigsetjmp;
 	siglongjmp;
 	htonl;
-	__htonl;
 	htons;
-	__htons;
 	ntohl;
-	__ntohl;
 	ntohs;
-	__ntohs;
 	vfork;
 	brk;
 	cerror;		/* XXX - Should this be .cerror (see sys/cerror.S)? */
Index: lib/libc/mips/Makefile.inc
===================================================================
--- lib/libc/mips/Makefile.inc	(revision 209040)
+++ lib/libc/mips/Makefile.inc	(working copy)
@@ -1,8 +1,6 @@
 #	$NetBSD: Makefile.inc,v 1.7 2005/09/17 11:49:39 tsutsui Exp $
 # $FreeBSD$
 
-SOFTFLOAT_BITS=32
-
 CFLAGS+=-DSOFTFLOAT
 
 MDSRCS+= machdep_ldisd.c
Index: lib/libc/mips/gen/Makefile.inc
===================================================================
--- lib/libc/mips/gen/Makefile.inc	(revision 209040)
+++ lib/libc/mips/gen/Makefile.inc	(working copy)
@@ -6,4 +6,4 @@
 # SRCS+=	flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \
 #	fpsetround.c fpsetsticky.c
 
-SRCS+=	_set_tp.c _setjmp.S makecontext.c setjmp.S signalcontext.c sigsetjmp.S
+SRCS+=	_ctx_start.S _set_tp.c _setjmp.S makecontext.c setjmp.S signalcontext.c sigsetjmp.S
Index: lib/libc/mips/gen/makecontext.c
===================================================================
--- lib/libc/mips/gen/makecontext.c	(revision 209040)
+++ lib/libc/mips/gen/makecontext.c	(working copy)
@@ -1,4 +1,4 @@
-/*	$NetBSD: makecontext.c,v 1.3 2003/01/19 08:53:36 matt Exp $	*/
+/*	$NetBSD: makecontext.c,v 1.5 2009/12/14 01:07:42 matt Exp $	*/
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -15,13 +15,6 @@
  * 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.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *        This product includes software developed by the NetBSD
- *        Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -39,48 +32,92 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 #if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: makecontext.c,v 1.3 2003/01/19 08:53:36 matt Exp $");
+__RCSID("$NetBSD: makecontext.c,v 1.5 2009/12/14 01:07:42 matt Exp $");
 #endif
 
-#include <sys/types.h>
+#include <sys/param.h>
+#include <machine/regnum.h>
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
 #include <ucontext.h>
-#include <stdarg.h>
 
+__weak_reference(__makecontext, makecontext);
+
+void _ctx_done(ucontext_t *);
+void _ctx_start(void);
+
 void
-makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
+__makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
 {
-	/* XXXMIPS: Implement me */
-#if 0
-	__greg_t *gr = ucp->uc_mcontext.__gregs;
-	uintptr_t *sp;
+	mcontext_t *mc;
+	register_t *sp;
 	int i;
 	va_list ap;
 
-	void __resumecontext(void);
+	/*
+	 * XXX/juli
+	 * We need an mc_len or mc_flags like other architectures
+	 * so that we can mark a context as invalid.  Store it in
+	 * mc->mc_regs[ZERO] perhaps?
+	 */
+	if (argc < 0 || argc > 6 || ucp == NULL ||
+	    ucp->uc_stack.ss_sp == NULL ||
+	    ucp->uc_stack.ss_size < MINSIGSTKSZ)
+		return;
+	mc = &ucp->uc_mcontext;
 
-	/* LINTED uintptr_t is safe */
-	sp  = (uintptr_t *)
+	sp  = (register_t *)
 	    ((uintptr_t)ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
-	/* LINTED uintptr_t is safe */
+#if defined(__mips_o32) || defined(__mips_o64)
 	sp -= (argc >= 4 ? argc : 4);	/* Make room for >=4 arguments. */
-	sp  = (uintptr_t *)
-	      ((uintptr_t)sp & ~0x7);	/* Align on double-word boundary. */
+	sp  = (register_t *)
+	    ((uintptr_t)sp & ~0x7);	/* Align on double-word boundary. */
+#elif defined(__mips_n32) || defined(__mips_n64)
+	sp -= (argc > 8 ? argc - 8 : 0); /* Make room for > 8 arguments. */
+	sp  = (register_t *)
+	    ((uintptr_t)sp & ~0xf);	/* Align on quad-word boundary. */
+#endif
 
-	gr[_REG_SP]  = (__greg_t)sp;
-	gr[_REG_RA]  = (__greg_t)__resumecontext;
-	gr[_REG_T9]  = (__greg_t)func;	/* required for .abicalls */
-	gr[_REG_EPC] = (__greg_t)func;
+	mc->mc_regs[SP] = (intptr_t)sp;
+	mc->mc_regs[S0] = (intptr_t)ucp;
+	mc->mc_regs[T9] = (intptr_t)func;
+	mc->mc_pc = (intptr_t)_ctx_start;
 
 	/* Construct argument list. */
 	va_start(ap, argc);
+#if defined(__mips_o32) || defined(__mips_o64)
 	/* Up to the first four arguments are passed in $a0-3. */
 	for (i = 0; i < argc && i < 4; i++)
-		/* LINTED uintptr_t is safe */
-		gr[_REG_A0 + i] = va_arg(ap, uintptr_t);
+		/* LINTED register_t is safe */
+		mc->mc_regs[A0 + i] = va_arg(ap, register_t);
 	/* Pass remaining arguments on the stack above the $a0-3 gap. */
-	for (sp += 4; i < argc; i++)
+	sp += i;
+#endif
+#if defined(__mips_n32) || defined(__mips_n64)
+	/* Up to the first 8 arguments are passed in $a0-7. */
+	for (i = 0; i < argc && i < 8; i++)
+		/* LINTED register_t is safe */
+		mc->mc_regs[A0 + i] = va_arg(ap, register_t);
+	/* Pass remaining arguments on the stack above the $a0-3 gap. */
+#endif
+	/* Pass remaining arguments on the stack above the $a0-3 gap. */
+	for (; i < argc; i++)
 		/* LINTED uintptr_t is safe */
-		*sp++ = va_arg(ap, uintptr_t);
+		*sp++ = va_arg(ap, register_t);
 	va_end(ap);
-#endif
 }
+
+void
+_ctx_done(ucontext_t *ucp)
+{
+
+	if (ucp->uc_link == NULL)
+		exit(0);
+	else {
+		setcontext((const ucontext_t *)ucp->uc_link);
+		abort();
+	}
+}
Index: lib/libc/mips/sys/Makefile.inc
===================================================================
--- lib/libc/mips/sys/Makefile.inc	(revision 209040)
+++ lib/libc/mips/sys/Makefile.inc	(working copy)
@@ -1,7 +1,7 @@
 # $FreeBSD$
 
 MDASM=  Ovfork.S brk.S cerror.S exect.S \
-	fork.S pipe.S ptrace.S sbrk.S shmat.S syscall.S
+	fork.S pipe.S ptrace.S sbrk.S syscall.S
 
 # Don't generate default code for these syscalls:
 NOASM=	break.o exit.o ftruncate.o getlogin.o lseek.o mmap.o \
Index: lib/libc/Makefile
===================================================================
--- lib/libc/Makefile	(revision 209040)
+++ lib/libc/Makefile	(working copy)
@@ -51,9 +51,14 @@
 .include "${.CURDIR}/posix1e/Makefile.inc"
 .if ${MACHINE_ARCH} != "amd64" && \
     ${MACHINE_ARCH} != "ia64" && \
-    ${MACHINE_ARCH} != "sparc64"
+    ${MACHINE_ARCH} != "sparc64" && \
+    ${MACHINE_ARCH} != "mips"
 .include "${.CURDIR}/quad/Makefile.inc"
 .endif
+.if ${MACHINE_ARCH} == "mips" && \
+    (!defined(TARGET_ABI) || ${TARGET_ABI} == "o32")
+.include "${.CURDIR}/quad/Makefile.inc"
+.endif
 .include "${.CURDIR}/regex/Makefile.inc"
 .include "${.CURDIR}/resolv/Makefile.inc"
 .include "${.CURDIR}/stdio/Makefile.inc"

[-- Attachment #4 --]
Index: libexec/rtld-elf/mips/rtld_start.S
===================================================================
--- libexec/rtld-elf/mips/rtld_start.S	(revision 209193)
+++ libexec/rtld-elf/mips/rtld_start.S	(working copy)
@@ -68,7 +68,8 @@
 	move	a0, s0			/* sp */
 	PTR_ADDU a1, sp, 2*PTR_SIZE	/* &our atexit function */
 	PTR_ADDU a2, sp, 3*PTR_SIZE	/* obj_main entry */
-	jal	_C_LABEL(_rtld)		/* v0 = _rtld(sp, cleanup, objp) */
+	PTR_LA	t9, _C_LABEL(_rtld)
+	jalr	t9			/* v0 = _rtld(sp, cleanup, objp) */
 	 nop
 
 	PTR_L	a1, 2*PTR_SIZE(sp)	/* our atexit function */
@@ -123,7 +124,7 @@
 	move	s0, sp
 
 	move	a0, v1			/* old GP */
-	subu	a0, a0, 0x7ff0		/* The offset of $gp from the	*/
+	PTR_SUBU	a0, a0, 0x7ff0		/* The offset of $gp from the	*/
        					/* beginning of the .got section: */
 					/* $gp = .got + 0x7ff0, so	*/
 					/* .got = $gp - 0x7ff0		*/
@@ -136,7 +137,8 @@
 	and	a0, a0, 0x7fffffff
 	move	a1, t8			/* symbol index */
 
-	jal	_C_LABEL(_mips_rtld_bind)
+	PTR_LA	t9, _C_LABEL(_mips_rtld_bind)
+	jalr	t9
 	 nop
 
 	move	sp, s0

[-- Attachment #5 --]
Index: sys/conf/files.mips
===================================================================
--- sys/conf/files.mips	(revision 209193)
+++ sys/conf/files.mips	(working copy)
@@ -44,7 +44,7 @@
 mips/mips/fp.S			standard
 mips/mips/pm_machdep.c		standard
 mips/mips/swtch.S		standard
-mips/mips/tlb.S			standard
+mips/mips/tlb.c			standard
 
 mips/mips/bus_space_generic.c 	standard
 mips/mips/busdma_machdep.c 	standard
Index: sys/mips/include/tlb.h
===================================================================
--- sys/mips/include/tlb.h	(revision 0)
+++ sys/mips/include/tlb.h	(revision 0)
@@ -0,0 +1,39 @@
+/*-
+ * Copyright (c) 2004-2010 Juli Mallett <jmallett@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$
+ */
+
+#ifndef	_MACHINE_TLB_H_
+#define	_MACHINE_TLB_H_
+
+void tlb_insert_wired(unsigned, vm_offset_t, pt_entry_t, pt_entry_t);
+void tlb_invalidate_address(struct pmap *, vm_offset_t);
+void tlb_invalidate_all(void);
+void tlb_invalidate_all_user(struct pmap *);
+void tlb_save(void);
+void tlb_update(struct pmap *, vm_offset_t, pt_entry_t);
+
+#endif /* !_MACHINE_TLB_H_ */
Index: sys/mips/include/cpu.h
===================================================================
--- sys/mips/include/cpu.h	(revision 209193)
+++ sys/mips/include/cpu.h	(working copy)
@@ -274,27 +274,6 @@
 #define	OPCODE_C1		0x11
 
 /*
- * The low part of the TLB entry.
- */
-#define	VMTLB_PF_NUM		0x3fffffc0
-#define	VMTLB_ATTR_MASK		0x00000038
-#define	VMTLB_MOD_BIT		0x00000004
-#define	VMTLB_VALID_BIT		0x00000002
-#define	VMTLB_GLOBAL_BIT	0x00000001
-
-#define	VMTLB_PHYS_PAGE_SHIFT	6
-
-/*
- * The high part of the TLB entry.
- */
-#define	VMTLB_VIRT_PAGE_NUM		0xffffe000
-#define	VMTLB_PID			0x000000ff
-#define	VMTLB_PID_R9K			0x00000fff
-#define	VMTLB_PID_SHIFT			0
-#define	VMTLB_VIRT_PAGE_SHIFT		12
-#define	VMTLB_VIRT_PAGE_SHIFT_R9K	13
-
-/*
  * The first TLB entry that write random hits.
  * TLB entry 0 maps the kernel stack of the currently running thread
  * TLB entry 1 maps the pcpu area of processor (only for SMP builds)
@@ -313,14 +292,6 @@
 #define	VMNUM_PIDS		256
 
 /*
- * TLB probe return codes.
- */
-#define	VMTLB_NOT_FOUND		0
-#define	VMTLB_FOUND		1
-#define	VMTLB_FOUND_WITH_PATCH	2
-#define	VMTLB_PROBE_ERROR	3
-
-/*
  * Exported definitions unique to mips cpu support.
  */
 
@@ -335,6 +306,7 @@
 #ifndef _LOCORE
 #include <machine/cpufunc.h>
 #include <machine/frame.h>
+
 /*
  * Arguments to hardclock and gatherstats encapsulate the previous
  * machine state in an opaque clockframe.
@@ -455,12 +427,9 @@
 #if defined(_KERNEL) && !defined(_LOCORE)
 extern union cpuprid fpu_id;
 
-struct tlb;
 struct user;
 
 int Mips_ConfigCache(void);
-void Mips_SetWIRED(int);
-void Mips_SetPID(int);
 
 void Mips_SyncCache(void);
 void Mips_SyncDCache(vm_offset_t, int);
@@ -471,12 +440,6 @@
 void Mips_SyncICache(vm_offset_t, int);
 void Mips_InvalidateICache(vm_offset_t, int);
 
-void Mips_TLBFlush(int);
-void Mips_TLBFlushAddr(vm_offset_t);
-void Mips_TLBWriteIndexed(int, struct tlb *);
-void Mips_TLBUpdate(vm_offset_t, unsigned);
-void Mips_TLBRead(int, struct tlb *);
-void mips_TBIAP(int);
 void wbflush(void);
 
 extern u_int32_t cpu_counter_interval;	/* Number of counter ticks/tick */
@@ -516,16 +479,6 @@
 			: "r" (func), "r" (arg0), "r" (arg1), "r" (arg2)  /* inputs */ \
 			: "$31", "$4", "$5", "$6");
 
-#define	MachSetPID			Mips_SetPID
-#define	MachTLBUpdate   		Mips_TLBUpdate
-#define	mips_TBIS			Mips_TLBFlushAddr
-#define	MIPS_TBIAP()			mips_TBIAP(num_tlbentries)
-#define	MachSetWIRED(index)		Mips_SetWIRED(index)
-#define	MachTLBFlush(count)		Mips_TLBFlush(count)
-#define	MachTLBGetPID(pid)		(pid = Mips_TLBGetPID())
-#define	MachTLBRead(tlbno, tlbp)	Mips_TLBRead(tlbno, tlbp)
-#define	MachFPTrap(sr, cause, pc)	MipsFPTrap(sr, cause, pc)
-
 /*
  * Enable realtime clock (always enabled).
  */
@@ -542,8 +495,6 @@
  *  Low level access routines to CPU registers
  */
 
-int Mips_TLBGetPID(void);
-
 void swi_vm(void *);
 void cpu_halt(void);
 void cpu_reset(void);
Index: sys/mips/include/pte.h
===================================================================
--- sys/mips/include/pte.h	(revision 209193)
+++ sys/mips/include/pte.h	(working copy)
@@ -1,14 +1,7 @@
-/*	$OpenBSD: pte.h,v 1.4 1998/01/28 13:46:25 pefo Exp $	*/
-
 /*-
- * Copyright (c) 1988 University of Utah.
- * Copyright (c) 1992, 1993
- *	The Regents of the University of California.  All rights reserved.
+ * Copyright (c) 2004-2010 Juli Mallett <jmallett@FreeBSD.org>
+ * All rights reserved.
  *
- * This code is derived from software contributed to Berkeley by
- * the Systems Programming Group of the University of Utah Computer
- * Science Department and Ralph Campbell.
- *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -17,18 +10,11 @@
  * 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.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * 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 REGENTS OR CONTRIBUTORS BE LIABLE
+ * 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)
@@ -37,60 +23,66 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	from: Utah Hdr: pte.h 1.11 89/09/03
- *	from: @(#)pte.h 8.1 (Berkeley) 6/10/93
- *	JNPR: pte.h,v 1.1.4.1 2007/09/10 06:20:19 girish
  * $FreeBSD$
  */
 
-#ifndef _MACHINE_PTE_H_
+#ifndef	_MACHINE_PTE_H_
 #define	_MACHINE_PTE_H_
 
-#include <machine/endian.h>
+/*
+ * TLB and PTE management.  Most things operate within the context of
+ * EntryLo0,1, and begin with TLBLO_.  Things which work with EntryHi
+ * start with TLBHI_.  PTE bits begin with PG_.
+ *
+ * Note that we use the same size VM and TLB pages.
+ */
+#define	TLB_PAGE_SHIFT	(PAGE_SHIFT)
+#define	TLB_PAGE_SIZE	(1 << TLB_PAGE_SHIFT)
+#define	TLB_PAGE_MASK	(TLB_PAGE_SIZE - 1)
 
 /*
- * MIPS hardware page table entry
+ * TLB PageMask register.  Has mask bits set above the default, 4K, page mask.
  */
+#define	TLBMASK_SHIFT	(13)
+#define	TLBMASK_MASK	((PAGE_MASK >> TLBMASK_SHIFT) << TLBMASK_SHIFT)
 
-#ifndef _LOCORE
-struct pte {
-#if BYTE_ORDER == BIG_ENDIAN
-unsigned int	pg_prot:2,		/* SW: access control */
-		pg_pfnum:24,		/* HW: core page frame number or 0 */
-		pg_attr:3,		/* HW: cache attribute */
-		pg_m:1,			/* HW: modified (dirty) bit */
-		pg_v:1,			/* HW: valid bit */
-		pg_g:1;			/* HW: ignore pid bit */
-#endif
-#if BYTE_ORDER == LITTLE_ENDIAN
-unsigned int	pg_g:1,			/* HW: ignore pid bit */
-		pg_v:1,			/* HW: valid bit */
-		pg_m:1,			/* HW: modified (dirty) bit */
-		pg_attr:3,		/* HW: cache attribute */
-		pg_pfnum:24,		/* HW: core page frame number or 0 */
-		pg_prot:2;		/* SW: access control */
-#endif
-};
-
 /*
- * Structure defining an tlb entry data set.
+ * PFN for EntryLo register.  Upper bits are 0, which is to say that
+ * bit 29 is the last hardware bit;  Bits 30 and upwards (EntryLo is
+ * 64 bit though it can be referred to in 32-bits providing 2 software
+ * bits safely.  We use it as 64 bits to get many software bits, and
+ * god knows what else.) are unacknowledged by hardware.  They may be
+ * written as anything, but otherwise they have as much meaning as
+ * other 0 fields.
  */
+#define	TLBLO_SWBITS_SHIFT	(30)
+#define	TLBLO_SWBITS_MASK	(0x3U << TLBLO_SWBITS_SHIFT)
+#define	TLBLO_PFN_SHIFT		(6)
+#define	TLBLO_PFN_MASK		(0x3FFFFFC0)
+#define	TLBLO_PA_TO_PFN(pa)	((((pa) >> TLB_PAGE_SHIFT) << TLBLO_PFN_SHIFT) & TLBLO_PFN_MASK)
+#define	TLBLO_PFN_TO_PA(pfn)	((vm_paddr_t)((pfn) >> TLBLO_PFN_SHIFT) << TLB_PAGE_SHIFT)
+#define	TLBLO_PTE_TO_PFN(pte)	((pte) & TLBLO_PFN_MASK)
+#define	TLBLO_PTE_TO_PA(pte)	(TLBLO_PFN_TO_PA(TLBLO_PTE_TO_PFN((pte))))
+  
+/*
+ * VPN for EntryHi register.  Upper two bits select user, supervisor,
+ * or kernel.  Bits 61 to 40 copy bit 63.  VPN2 is bits 39 and down to
+ * as low as 13, down to PAGE_SHIFT, to index 2 TLB pages*.  From bit 12
+ * to bit 8 there is a 5-bit 0 field.  Low byte is ASID.
+ *
+ * Note that in FreeBSD, we map 2 TLB pages is equal to 1 VM page.
+ */
+#define	TLBHI_ASID_MASK		(0xff)
+#define	TLBHI_ENTRY(va, asid)	(((va) & ~PAGE_MASK) | ((asid) & TLBHI_ASID_MASK))
 
-struct tlb {
-	int	tlb_mask;
-	int	tlb_hi;
-	int	tlb_lo0;
-	int	tlb_lo1;
-};
-
+#ifndef _LOCORE
 typedef unsigned int pt_entry_t;
 typedef pt_entry_t *pd_entry_t;
+#endif
 
 #define	PDESIZE		sizeof(pd_entry_t)	/* for assembly files */
 #define	PTESIZE		sizeof(pt_entry_t)	/* for assembly files */
 
-#endif /* _LOCORE */
-
 #define	PT_ENTRY_NULL	((pt_entry_t *) 0)
 
 #define	PTE_WIRED	0x80000000	/* SW */
@@ -119,11 +111,6 @@
 #define PTE_HVPN        0xffffe000      /* Hardware page no mask */
 #define PTE_ASID        0x000000ff      /* Address space ID */
 
-#define	PTE_SHIFT	6
-#define	pfn_is_ext(x)	((x) & 0x3c000000)
-#define	vad_to_pfn(x)	(((unsigned)(x) >> PTE_SHIFT) & PTE_FRAME)
-#define	vad_to_pfn64(x)	((quad_t)(x) >> PTE_SHIFT) & PTE_FRAME)
-#define	pfn_to_vad(x)	(((x) & PTE_FRAME) << PTE_SHIFT)
 
 /* User virtual to pte offset in page table */
 #define	vad_to_pte_offset(adr)	(((adr) >> PAGE_SHIFT) & (NPTEPG -1))
@@ -138,16 +125,5 @@
 #define	mips_pg_cwpage_bit()	(PTE_CWPAGE)
 #define	mips_pg_global_bit()	(PTE_G)
 #define	mips_pg_wired_bit()	(PTE_WIRED)
-#define	mips_tlbpfn_to_paddr(x)	pfn_to_vad((x))
-#define	mips_paddr_to_tlbpfn(x)	vad_to_pfn((x))
 
-/* These are not used */
-#define	PTE_SIZE_4K	0x00000000
-#define	PTE_SIZE_16K	0x00006000
-#define	PTE_SIZE_64K	0x0001e000
-#define	PTE_SIZE_256K	0x0007e000
-#define	PTE_SIZE_1M	0x001fe000
-#define	PTE_SIZE_4M	0x007fe000
-#define	PTE_SIZE_16M	0x01ffe000
-
-#endif	/* !_MACHINE_PTE_H_ */
+#endif /* !_MACHINE_PTE_H_ */
Index: sys/mips/include/pmap.h
===================================================================
--- sys/mips/include/pmap.h	(revision 209193)
+++ sys/mips/include/pmap.h	(working copy)
@@ -49,15 +49,7 @@
 #include <machine/vmparam.h>
 #include <machine/pte.h>
 
-#define	VADDR(pdi, pti)	((vm_offset_t)(((pdi)<<PDRSHIFT)|((pti)<<PAGE_SHIFT)))
-
 #define	NKPT		120	/* actual number of kernel page tables */
-
-#ifndef NKPDE
-#define	NKPDE		255	/* addressable number of page tables/pde's */
-#endif
-
-#define	KPTDI		(VM_MIN_KERNEL_ADDRESS >> SEGSHIFT)
 #define	NUSERPGTBLS	(VM_MAXUSER_ADDRESS >> SEGSHIFT)
 
 #ifndef LOCORE
@@ -109,6 +101,7 @@
 vm_offset_t pmap_kextract(vm_offset_t va);
 
 #define	vtophys(va)	pmap_kextract(((vm_offset_t) (va)))
+#define	pmap_asid(pmap)	(pmap)->pm_asid[PCPU_GET(cpuid)].asid
 
 extern struct pmap	kernel_pmap_store;
 #define kernel_pmap	(&kernel_pmap_store)
@@ -122,9 +115,8 @@
 #define	PMAP_MTX(pmap)		(&(pmap)->pm_mtx)
 #define	PMAP_TRYLOCK(pmap)	mtx_trylock(&(pmap)->pm_mtx)
 #define	PMAP_UNLOCK(pmap)	mtx_unlock(&(pmap)->pm_mtx)
-
 #define PMAP_LGMEM_LOCK_INIT(sysmap) mtx_init(&(sysmap)->lock, "pmap-lgmem", \
-				    "per-cpu-map", (MTX_DEF| MTX_DUPOK))
+			     "per-cpu-map", (MTX_DEF| MTX_DUPOK))
 #define PMAP_LGMEM_LOCK(sysmap) mtx_lock(&(sysmap)->lock)
 #define PMAP_LGMEM_UNLOCK(sysmap) mtx_unlock(&(sysmap)->lock)
 #define PMAP_LGMEM_DESTROY(sysmap) mtx_destroy(&(sysmap)->lock)
@@ -183,11 +175,6 @@
 void pmap_update_page(pmap_t pmap, vm_offset_t va, pt_entry_t pte);
 void pmap_flush_pvcache(vm_page_t m);
 
-/*
- * Function to save TLB contents so that they may be inspected in the debugger.
- */
-extern void pmap_save_tlb(void);
-
 #endif				/* _KERNEL */
 
 #endif				/* !LOCORE */
Index: sys/mips/mips/tlb.c
===================================================================
--- sys/mips/mips/tlb.c	(revision 0)
+++ sys/mips/mips/tlb.c	(revision 0)
@@ -0,0 +1,311 @@
+/*-
+ * Copyright (c) 2004-2010 Juli Mallett <jmallett@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$
+ */
+
+#include "opt_ddb.h"
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/pcpu.h>
+#include <sys/smp.h>
+
+#include <vm/vm.h>
+#include <vm/vm_page.h>
+
+#include <machine/pte.h>
+#include <machine/tlb.h>
+
+struct tlb_state {
+	unsigned wired;
+	struct tlb_entry {
+		register_t entryhi;
+		register_t entrylo0;
+		register_t entrylo1;
+	} entry[MIPS_MAX_TLB_ENTRIES];
+};
+
+static struct tlb_state tlb_state[MAXCPU];
+
+#if 0
+/*
+ * PageMask must increment in steps of 2 bits.
+ */
+COMPILE_TIME_ASSERT(POPCNT(TLBMASK_MASK) % 2 == 0);
+#endif
+
+static inline void
+tlb_probe(void)
+{
+	__asm __volatile ("tlbp" : : : "memory");
+	mips_cp0_sync();
+}
+
+static inline void
+tlb_read(void)
+{
+	__asm __volatile ("tlbr" : : : "memory");
+	mips_cp0_sync();
+}
+
+static inline void
+tlb_write_indexed(void)
+{
+	__asm __volatile ("tlbwi" : : : "memory");
+	mips_cp0_sync();
+}
+
+static inline void
+tlb_write_random(void)
+{
+	__asm __volatile ("tlbwr" : : : "memory");
+	mips_cp0_sync();
+}
+
+static void tlb_invalidate_one(unsigned);
+
+void
+tlb_insert_wired(unsigned i, vm_offset_t va, pt_entry_t pte0, pt_entry_t pte1)
+{
+	register_t mask, asid;
+	register_t s;
+
+	va &= ~PAGE_MASK;
+
+	s = intr_disable();
+	mask = mips_rd_pagemask();
+	asid = mips_rd_entryhi() & TLBHI_ASID_MASK;
+
+	mips_wr_index(i);
+	mips_wr_pagemask(0);
+	mips_wr_entryhi(TLBHI_ENTRY(va, 0));
+	mips_wr_entrylo0(pte0);
+	mips_wr_entrylo1(pte1);
+	tlb_write_indexed();
+
+	mips_wr_entryhi(asid);
+	mips_wr_pagemask(mask);
+	intr_restore(s);
+}
+
+void
+tlb_invalidate_address(struct pmap *pmap, vm_offset_t va)
+{
+	register_t mask, asid;
+	register_t s;
+	int i;
+
+	va &= ~PAGE_MASK;
+
+	s = intr_disable();
+	mask = mips_rd_pagemask();
+	asid = mips_rd_entryhi() & TLBHI_ASID_MASK;
+
+	mips_wr_pagemask(0);
+	mips_wr_entryhi(TLBHI_ENTRY(va, pmap_asid(pmap)));
+	tlb_probe();
+	i = mips_rd_index();
+	if (i >= 0)
+		tlb_invalidate_one(i);
+
+	mips_wr_entryhi(asid);
+	mips_wr_pagemask(mask);
+	intr_restore(s);
+}
+
+void
+tlb_invalidate_all(void)
+{
+	register_t mask, asid;
+	register_t s;
+	unsigned i;
+
+	s = intr_disable();
+	mask = mips_rd_pagemask();
+	asid = mips_rd_entryhi() & TLBHI_ASID_MASK;
+
+	for (i = mips_rd_wired(); i < num_tlbentries; i++)
+		tlb_invalidate_one(i);
+
+	mips_wr_entryhi(asid);
+	mips_wr_pagemask(mask);
+	intr_restore(s);
+}
+
+void
+tlb_invalidate_all_user(struct pmap *pmap)
+{
+	register_t mask, asid;
+	register_t s;
+	unsigned i;
+
+	s = intr_disable();
+	mask = mips_rd_pagemask();
+	asid = mips_rd_entryhi() & TLBHI_ASID_MASK;
+
+	for (i = mips_rd_wired(); i < num_tlbentries; i++) {
+		register_t uasid;
+
+		mips_wr_index(i);
+		tlb_read();
+
+		uasid = mips_rd_entryhi() & TLBHI_ASID_MASK;
+		if (pmap == NULL) {
+			/*
+			 * Invalidate all non-kernel entries.
+			 */
+			if (uasid == 0)
+				continue;
+		} else {
+			/*
+			 * Invalidate this pmap's entries.
+			 */
+			if (uasid != pmap_asid(pmap))
+				continue;
+		}
+		tlb_invalidate_one(i);
+	}
+
+	mips_wr_entryhi(asid);
+	mips_wr_pagemask(mask);
+	intr_restore(s);
+}
+
+/* XXX Only if DDB?  */
+void
+tlb_save(void)
+{
+	unsigned i, cpu;
+
+	cpu = PCPU_GET(cpuid);
+
+	tlb_state[cpu].wired = mips_rd_wired();
+	for (i = 0; i < num_tlbentries; i++) {
+		mips_wr_index(i);
+		tlb_read();
+
+		tlb_state[cpu].entry[i].entryhi = mips_rd_entryhi();
+		tlb_state[cpu].entry[i].entrylo0 = mips_rd_entrylo0();
+		tlb_state[cpu].entry[i].entrylo1 = mips_rd_entrylo1();
+	}
+}
+
+void
+tlb_update(struct pmap *pmap, vm_offset_t va, pt_entry_t pte)
+{
+	register_t mask, asid;
+	register_t s;
+	int i;
+
+	va &= ~PAGE_MASK;
+	pte &= ~TLBLO_SWBITS_MASK;
+
+	s = intr_disable();
+	mask = mips_rd_pagemask();
+	asid = mips_rd_entryhi() & TLBHI_ASID_MASK;
+
+	mips_wr_pagemask(0);
+	mips_wr_entryhi(TLBHI_ENTRY(va, pmap_asid(pmap)));
+	tlb_probe();
+	i = mips_rd_index();
+	if (i >= 0) {
+		tlb_read();
+
+		if ((va & PAGE_SIZE) == 0) {
+			mips_wr_entrylo0(pte);
+		} else {
+			mips_wr_entrylo1(pte);
+		}
+		tlb_write_indexed();
+	}
+
+	mips_wr_entryhi(asid);
+	mips_wr_pagemask(mask);
+	intr_restore(s);
+}
+
+static void
+tlb_invalidate_one(unsigned i)
+{
+	/* XXX an invalid ASID? */
+	mips_wr_entryhi(TLBHI_ENTRY(MIPS_KSEG0_START + (2 * i * PAGE_SIZE), 0));
+	mips_wr_entrylo0(0);
+	mips_wr_entrylo1(0);
+	mips_wr_pagemask(0);
+	mips_wr_index(i);
+	tlb_write_indexed();
+}
+
+#ifdef DDB
+#include <ddb/ddb.h>
+
+DB_SHOW_COMMAND(tlb, ddb_dump_tlb)
+{
+	register_t ehi, elo0, elo1;
+	unsigned i, cpu;
+
+	/*
+	 * XXX
+	 * The worst conversion from hex to decimal ever.
+	 */
+	if (have_addr)
+		cpu = ((addr >> 4) % 16) * 10 + (addr % 16);
+	else
+		cpu = PCPU_GET(cpuid);
+
+	if (cpu < 0 || cpu >= mp_ncpus) {
+		db_printf("Invalid CPU %u\n", cpu);
+		return;
+	}
+
+	if (cpu == PCPU_GET(cpuid))
+		tlb_save();
+
+	db_printf("Beginning TLB dump for CPU %u...\n", cpu);
+	for (i = 0; i < num_tlbentries; i++) {
+		if (i == tlb_state[cpu].wired) {
+			if (i != 0)
+				db_printf("^^^ WIRED ENTRIES ^^^\n");
+			else
+				db_printf("(No wired entries.)\n");
+		}
+
+		/* XXX PageMask.  */
+		ehi = tlb_state[cpu].entry[i].entryhi;
+		elo0 = tlb_state[cpu].entry[i].entrylo0;
+		elo1 = tlb_state[cpu].entry[i].entrylo1;
+
+		if (elo0 == 0 && elo1 == 0)
+			continue;
+
+		db_printf("#%u\t=> %jx\n", i, (intmax_t)ehi);
+		db_printf(" Lo0\t%jx\t(%#jx)\n", (intmax_t)elo0, (intmax_t)TLBLO_PTE_TO_PA(elo0));
+		db_printf(" Lo1\t%jx\t(%#jx)\n", (intmax_t)elo1, (intmax_t)TLBLO_PTE_TO_PA(elo1));
+	}
+	db_printf("Finished.\n");
+}
+#endif
Index: sys/mips/mips/cpu.c
===================================================================
--- sys/mips/mips/cpu.c	(revision 209193)
+++ sys/mips/mips/cpu.c	(working copy)
@@ -49,6 +49,7 @@
 #include <machine/intr_machdep.h>
 #include <machine/locore.h>
 #include <machine/pte.h>
+#include <machine/tlb.h>
 #include <machine/hwfunc.h>
 
 struct mips_cpuinfo cpuinfo;
@@ -135,9 +136,9 @@
 	platform_cpu_init();
 	mips_get_identity(&cpuinfo);
 	num_tlbentries = cpuinfo.tlb_nentries;
-	Mips_SetWIRED(0);
-	Mips_TLBFlush(num_tlbentries);
-	Mips_SetWIRED(VMWIRED_ENTRIES);
+	mips_wr_wired(0);
+	tlb_invalidate_all();
+	mips_wr_wired(VMWIRED_ENTRIES);
 	mips_config_cache(&cpuinfo);
 	mips_vector_init();
 
Index: sys/mips/mips/pmap.c
===================================================================
--- sys/mips/mips/pmap.c	(revision 209193)
+++ sys/mips/mips/pmap.c	(working copy)
@@ -99,6 +99,7 @@
 
 #include <machine/cache.h>
 #include <machine/md_var.h>
+#include <machine/tlb.h>
 
 #if defined(DIAGNOSTIC)
 #define	PMAP_DIAGNOSTIC
@@ -150,8 +151,6 @@
 
 vm_offset_t kernel_vm_end;
 
-static struct tlb tlbstash[MAXCPU][MIPS_MAX_TLB_ENTRIES];
-
 static void pmap_asid_alloc(pmap_t pmap);
 
 /*
@@ -182,8 +181,6 @@
 static vm_page_t _pmap_allocpte(pmap_t pmap, unsigned ptepindex, int flags);
 static int pmap_unuse_pt(pmap_t, vm_offset_t, vm_page_t);
 static int init_pte_prot(vm_offset_t va, vm_page_t m, vm_prot_t prot);
-static void pmap_TLB_invalidate_kernel(vm_offset_t);
-static void pmap_TLB_update_kernel(vm_offset_t, pt_entry_t);
 static vm_page_t pmap_alloc_pte_page(pmap_t, unsigned int, int, vm_offset_t *);
 static void pmap_release_pte_page(vm_page_t);
 
@@ -223,7 +220,7 @@
 	intr = intr_disable();						\
 	sched_pin();							\
 	va = sysm->base;						\
-	npte = mips_paddr_to_tlbpfn(phys) |				\
+	npte = TLBLO_PA_TO_PFN(phys) |					\
 	    PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE;			\
 	pte = pmap_pte(kernel_pmap, va);				\
 	*pte = npte;							\
@@ -241,11 +238,11 @@
 	sched_pin();							\
 	va1 = sysm->base;						\
 	va2 = sysm->base + PAGE_SIZE;					\
-	npte = mips_paddr_to_tlbpfn(phys1) |				\
+	npte = TLBLO_PA_TO_PFN(phys1) |					\
 	    PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE;			\
 	pte = pmap_pte(kernel_pmap, va1);				\
 	*pte = npte;							\
-	npte = mips_paddr_to_tlbpfn(phys2) |				\
+	npte =  TLBLO_PA_TO_PFN(phys2) |				\
 	    PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE;			\
 	pte = pmap_pte(kernel_pmap, va2);				\
 	*pte = npte;							\
@@ -255,11 +252,11 @@
 #define	PMAP_LMEM_UNMAP()						\
 	pte = pmap_pte(kernel_pmap, sysm->base);			\
 	*pte = PTE_G;							\
-	pmap_TLB_invalidate_kernel(sysm->base);				\
+	tlb_invalidate_address(kernel_pmap, sysm->base);		\
 	sysm->valid1 = 0;						\
 	pte = pmap_pte(kernel_pmap, sysm->base + PAGE_SIZE);		\
 	*pte = PTE_G;							\
-	pmap_TLB_invalidate_kernel(sysm->base + PAGE_SIZE);		\
+	tlb_invalidate_address(kernel_pmap, sysm->base + PAGE_SIZE);	\
 	sysm->valid2 = 0;						\
 	sched_unpin();							\
 	intr_restore(intr);						\
@@ -499,7 +496,7 @@
 	kernel_pmap->pm_asid[0].asid = PMAP_ASID_RESERVED;
 	kernel_pmap->pm_asid[0].gen = 0;
 	pmap_max_asid = VMNUM_PIDS;
-	MachSetPID(0);
+	mips_wr_entryhi(0);
 }
 
 /*
@@ -576,9 +573,14 @@
 
 #endif
 
-	if (pmap->pm_active & PCPU_GET(cpumask)) {
-		pmap_TLB_invalidate_all();
-	} else
+	if (pmap == kernel_pmap) {
+		tlb_invalidate_all();
+		return;
+	}
+
+	if (pmap->pm_active & PCPU_GET(cpumask))
+		tlb_invalidate_all_user(pmap);
+	else
 		pmap->pm_asid[PCPU_GET(cpuid)].gen = 0;
 }
 
@@ -608,7 +610,7 @@
 #endif
 
 	if (is_kernel_pmap(pmap)) {
-		pmap_TLB_invalidate_kernel(va);
+		tlb_invalidate_address(pmap, va);
 		return;
 	}
 	if (pmap->pm_asid[PCPU_GET(cpuid)].gen != PCPU_GET(asid_generation))
@@ -617,20 +619,9 @@
 		pmap->pm_asid[PCPU_GET(cpuid)].gen = 0;
 		return;
 	}
-	va = pmap_va_asid(pmap, (va & ~PAGE_MASK));
-	mips_TBIS(va);
+	tlb_invalidate_address(pmap, va);
 }
 
-static void
-pmap_TLB_invalidate_kernel(vm_offset_t va)
-{
-	u_int32_t pid;
-
-	MachTLBGetPID(pid);
-	va = va | (pid << VMTLB_PID_SHIFT);
-	mips_TBIS(va);
-}
-
 struct pmap_update_page_arg {
 	pmap_t pmap;
 	vm_offset_t va;
@@ -659,7 +650,7 @@
 
 #endif
 	if (is_kernel_pmap(pmap)) {
-		pmap_TLB_update_kernel(va, pte);
+		tlb_update(pmap, va, pte);
 		return;
 	}
 	if (pmap->pm_asid[PCPU_GET(cpuid)].gen != PCPU_GET(asid_generation))
@@ -668,23 +659,9 @@
 		pmap->pm_asid[PCPU_GET(cpuid)].gen = 0;
 		return;
 	}
-	va = pmap_va_asid(pmap, (va & ~PAGE_MASK));
-	MachTLBUpdate(va, pte);
+	tlb_update(pmap, va, pte);
 }
 
-static void
-pmap_TLB_update_kernel(vm_offset_t va, pt_entry_t pte)
-{
-	u_int32_t pid;
-
-	va &= ~PAGE_MASK;
-
-	MachTLBGetPID(pid);
-	va = va | (pid << VMTLB_PID_SHIFT);
-
-	MachTLBUpdate(va, pte);
-}
-
 /*
  *	Routine:	pmap_extract
  *	Function:
@@ -700,7 +677,7 @@
 	PMAP_LOCK(pmap);
 	pte = pmap_pte(pmap, va);
 	if (pte) {
-		retval = mips_tlbpfn_to_paddr(*pte) | (va & PAGE_MASK);
+		retval = TLBLO_PTE_TO_PA(*pte) | (va & PAGE_MASK);
 	}
 	PMAP_UNLOCK(pmap);
 	return retval;
@@ -727,10 +704,10 @@
 	pte = *pmap_pte(pmap, va);
 	if (pte != 0 && pmap_pte_v(&pte) &&
 	    ((pte & PTE_RW) || (prot & VM_PROT_WRITE) == 0)) {
-		if (vm_page_pa_tryrelock(pmap, mips_tlbpfn_to_paddr(pte), &pa))
+		if (vm_page_pa_tryrelock(pmap, TLBLO_PTE_TO_PA(pte), &pa))
 			goto retry;
 
-		m = PHYS_TO_VM_PAGE(mips_tlbpfn_to_paddr(pte));
+		m = PHYS_TO_VM_PAGE(TLBLO_PTE_TO_PA(pte));
 		vm_page_hold(m);
 	}
 	PA_UNLOCK_COND(pa);
@@ -754,7 +731,7 @@
 #ifdef PMAP_DEBUG
 	printf("pmap_kenter:  va: 0x%08x -> pa: 0x%08x\n", va, pa);
 #endif
-	npte = mips_paddr_to_tlbpfn(pa) | PTE_RW | PTE_V | PTE_G | PTE_W;
+	npte = TLBLO_PA_TO_PFN(pa) | PTE_RW | PTE_V | PTE_G | PTE_W;
 
 	if (is_cacheable_mem(pa))
 		npte |= PTE_CACHE;
@@ -1484,7 +1461,7 @@
 		pmap->pm_stats.wired_count -= 1;
 
 	pmap->pm_stats.resident_count -= 1;
-	pa = mips_tlbpfn_to_paddr(oldpte);
+	pa = TLBLO_PTE_TO_PA(oldpte);
 
 	if (page_is_managed(pa)) {
 		m = PHYS_TO_VM_PAGE(pa);
@@ -1700,7 +1677,7 @@
 		}
 retry:
 		obits = pbits = *pte;
-		pa = mips_tlbpfn_to_paddr(pbits);
+		pa = TLBLO_PTE_TO_PA(pbits);
 
 		if (page_is_managed(pa) && (pbits & PTE_M) != 0) {
 			m = PHYS_TO_VM_PAGE(pa);
@@ -1776,7 +1753,7 @@
 	pa = VM_PAGE_TO_PHYS(m);
 	om = NULL;
 	origpte = *pte;
-	opa = mips_tlbpfn_to_paddr(origpte);
+	opa = TLBLO_PTE_TO_PA(origpte);
 
 	/*
 	 * Mapping has not changed, must be protection or wiring change.
@@ -1873,7 +1850,7 @@
 	/*
 	 * Now validate mapping with desired protection/wiring.
 	 */
-	newpte = mips_paddr_to_tlbpfn(pa) | rw | PTE_V;
+	newpte = TLBLO_PA_TO_PFN(pa) | rw | PTE_V;
 
 	if (is_cacheable_mem(pa))
 		newpte |= PTE_CACHE;
@@ -2039,7 +2016,7 @@
 	/*
 	 * Now validate mapping with RO protection
 	 */
-	*pte = mips_paddr_to_tlbpfn(pa) | PTE_V;
+	*pte = TLBLO_PA_TO_PFN(pa) | PTE_V;
 
 	if (is_cacheable_mem(pa))
 		*pte |= PTE_CACHE;
@@ -2092,7 +2069,7 @@
 		cpu = PCPU_GET(cpuid);
 		sysm = &sysmap_lmem[cpu];
 		/* Since this is for the debugger, no locks or any other fun */
-		npte = mips_paddr_to_tlbpfn(pa) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE;
+		npte = TLBLO_PA_TO_PFN(pa) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE;
 		pte = pmap_pte(kernel_pmap, sysm->base);
 		*pte = npte;
 		sysm->valid1 = 1;
@@ -2407,7 +2384,7 @@
 		}
 		*pte = is_kernel_pmap(pmap) ? PTE_G : 0;
 
-		m = PHYS_TO_VM_PAGE(mips_tlbpfn_to_paddr(tpte));
+		m = PHYS_TO_VM_PAGE(TLBLO_PTE_TO_PA(tpte));
 		KASSERT(m != NULL,
 		    ("pmap_remove_pages: bad tpte %x", tpte));
 
@@ -2814,7 +2791,7 @@
 	val = MINCORE_INCORE;
 	if ((pte & PTE_M) != 0)
 		val |= MINCORE_MODIFIED | MINCORE_MODIFIED_OTHER;
-	pa = mips_tlbpfn_to_paddr(pte);
+	pa = TLBLO_PTE_TO_PA(pte);
 	managed = page_is_managed(pa);
 	if (managed) {
 		/*
@@ -2856,7 +2833,7 @@
 	pmap_asid_alloc(pmap);
 	if (td == curthread) {
 		PCPU_SET(segbase, pmap->pm_segtab);
-		MachSetPID(pmap->pm_asid[PCPU_GET(cpuid)].asid);
+		mips_wr_entryhi(pmap->pm_asid[PCPU_GET(cpuid)].asid);
 	}
 
 	PCPU_SET(curpmap, pmap);
@@ -2948,7 +2925,7 @@
 							vm_offset_t pa;
 							vm_page_t m;
 
-							pa = mips_tlbpfn_to_paddr(*pte);
+							pa = TLBLO_PFN_TO_PA(*pte);
 							m = PHYS_TO_VM_PAGE(pa);
 							printf("va: %p, pt: %p, h: %d, w: %d, f: 0x%x",
 							    (void *)va,
@@ -3044,7 +3021,7 @@
 	    pmap->pm_asid[PCPU_GET(cpuid)].gen == PCPU_GET(asid_generation));
 	else {
 		if (PCPU_GET(next_asid) == pmap_max_asid) {
-			MIPS_TBIAP();
+			tlb_invalidate_all_user(NULL);
 			PCPU_SET(asid_generation,
 			    (PCPU_GET(asid_generation) + 1) & ASIDGEN_MASK);
 			if (PCPU_GET(asid_generation) == 0) {
@@ -3124,7 +3101,7 @@
 		if (curproc && curproc->p_vmspace) {
 			ptep = pmap_pte(&curproc->p_vmspace->vm_pmap, va);
 			if (ptep)
-				pa = mips_tlbpfn_to_paddr(*ptep) |
+				pa = TLBLO_PTE_TO_PA(*ptep) |
 				    (va & PAGE_MASK);
 		}
 	} else if (va >= MIPS_KSEG0_START &&
@@ -3140,9 +3117,11 @@
 		if (kernel_pmap->pm_active) {
 			/* Its inside the virtual address range */
 			ptep = pmap_pte(kernel_pmap, va);
-			if (ptep)
-				pa = mips_tlbpfn_to_paddr(*ptep) |
-				    (va & PAGE_MASK);
+			if (ptep) {
+				return (TLBLO_PTE_TO_PA(*ptep) |
+				    (va & PAGE_MASK));
+			}
+			return (0);
 		}
 	}
 	return pa;
@@ -3160,61 +3139,3 @@
 		}
 	}
 }
-
-void
-pmap_save_tlb(void)
-{
-	int tlbno, cpu;
-
-	cpu = PCPU_GET(cpuid);
-
-	for (tlbno = 0; tlbno < num_tlbentries; ++tlbno)
-		MachTLBRead(tlbno, &tlbstash[cpu][tlbno]);
-}
-
-#ifdef DDB
-#include <ddb/ddb.h>
-
-DB_SHOW_COMMAND(tlb, ddb_dump_tlb)
-{
-	int cpu, tlbno;
-	struct tlb *tlb;
-
-	if (have_addr)
-		cpu = ((addr >> 4) % 16) * 10 + (addr % 16);
-	else
-		cpu = PCPU_GET(cpuid);
-
-	if (cpu < 0 || cpu >= mp_ncpus) {
-		db_printf("Invalid CPU %d\n", cpu);
-		return;
-	} else
-		db_printf("CPU %d:\n", cpu);
-
-	if (cpu == PCPU_GET(cpuid))
-		pmap_save_tlb();
-
-	for (tlbno = 0; tlbno < num_tlbentries; ++tlbno) {
-		tlb = &tlbstash[cpu][tlbno];
-		if (tlb->tlb_lo0 & PTE_V || tlb->tlb_lo1 & PTE_V) {
-			printf("TLB %2d vad 0x%0lx ",
-				tlbno, (long)(tlb->tlb_hi & 0xffffff00));
-		} else {
-			printf("TLB*%2d vad 0x%0lx ",
-				tlbno, (long)(tlb->tlb_hi & 0xffffff00));
-		}
-		printf("0=0x%0lx ", pfn_to_vad((long)tlb->tlb_lo0));
-		printf("%c", tlb->tlb_lo0 & PTE_V ? 'V' : '-');
-		printf("%c", tlb->tlb_lo0 & PTE_M ? 'M' : '-');
-		printf("%c", tlb->tlb_lo0 & PTE_G ? 'G' : '-');
-		printf(" atr %x ", (tlb->tlb_lo0 >> 3) & 7);
-		printf("1=0x%0lx ", pfn_to_vad((long)tlb->tlb_lo1));
-		printf("%c", tlb->tlb_lo1 & PTE_V ? 'V' : '-');
-		printf("%c", tlb->tlb_lo1 & PTE_M ? 'M' : '-');
-		printf("%c", tlb->tlb_lo1 & PTE_G ? 'G' : '-');
-		printf(" atr %x ", (tlb->tlb_lo1 >> 3) & 7);
-		printf(" sz=%x pid=%x\n", tlb->tlb_mask,
-		       (tlb->tlb_hi & 0x000000ff));
-	}
-}
-#endif	/* DDB */
Index: sys/mips/mips/mp_machdep.c
===================================================================
--- sys/mips/mips/mp_machdep.c	(revision 209193)
+++ sys/mips/mips/mp_machdep.c	(working copy)
@@ -49,6 +49,7 @@
 #include <machine/hwfunc.h>
 #include <machine/intr_machdep.h>
 #include <machine/cache.h>
+#include <machine/tlb.h>
 
 struct pcb stoppcbs[MAXCPU];
 
@@ -128,7 +129,7 @@
 			CTR0(KTR_SMP, "IPI_STOP or IPI_STOP_HARD");
 
 			savectx(&stoppcbs[cpu]);
-			pmap_save_tlb();
+			tlb_save();
 
 			/* Indicate we are stopped */
 			atomic_set_int(&stopped_cpus, cpumask);
@@ -238,9 +239,9 @@
 smp_init_secondary(u_int32_t cpuid)
 {
 	/* TLB */
-	Mips_SetWIRED(0);
-	Mips_TLBFlush(num_tlbentries);
-	Mips_SetWIRED(VMWIRED_ENTRIES);
+	mips_wr_wired(0);
+	tlb_invalidate_all();
+	mips_wr_wired(VMWIRED_ENTRIES);
 
 	/*
 	 * We assume that the L1 cache on the APs is identical to the one
@@ -251,7 +252,7 @@
 
 	mips_sync();
 
-	MachSetPID(0);
+	mips_wr_entryhi(0);
 
 	pcpu_init(PCPU_ADDR(cpuid), cpuid, sizeof(struct pcpu));
 	dpcpu_init(dpcpu, cpuid);
Index: sys/mips/mips/machdep.c
===================================================================
--- sys/mips/mips/machdep.c	(revision 209193)
+++ sys/mips/mips/machdep.c	(working copy)
@@ -89,6 +89,7 @@
 #include <machine/hwfunc.h>
 #include <machine/intr_machdep.h>
 #include <machine/md_var.h>
+#include <machine/tlb.h>
 #ifdef DDB
 #include <sys/kdb.h>
 #include <ddb/ddb.h>
@@ -118,7 +119,7 @@
 /*
  * Each entry in the pcpu_space[] array is laid out in the following manner:
  * struct pcpu for cpu 'n'	pcpu_space[n]
- * boot stack for cpu 'n'	pcpu_space[n] + PAGE_SIZE * 2 - START_FRAME
+ * boot stack for cpu 'n'	pcpu_space[n] + PAGE_SIZE * 2 - CALLFRAME_SIZ
  *
  * Note that the boot stack grows downwards and we assume that we never
  * use enough stack space to trample over the 'struct pcpu' that is at
@@ -413,20 +414,17 @@
 mips_pcpu_tlb_init(struct pcpu *pcpu)
 {
 	vm_paddr_t pa;
-	struct tlb tlb;
-	int lobits;
+	pt_entry_t pte;
 
 	/*
 	 * Map the pcpu structure at the virtual address 'pcpup'.
 	 * We use a wired tlb index to do this one-time mapping.
 	 */
-	memset(&tlb, 0, sizeof(tlb));
 	pa = vtophys(pcpu);
-	lobits = PTE_RW | PTE_V | PTE_G | PTE_CACHE;
-	tlb.tlb_hi = (vm_offset_t)pcpup;
-	tlb.tlb_lo0 = mips_paddr_to_tlbpfn(pa) | lobits;
-	tlb.tlb_lo1 = mips_paddr_to_tlbpfn(pa + PAGE_SIZE) | lobits;
-	Mips_TLBWriteIndexed(PCPU_TLB_ENTRY, &tlb);
+	pte = PTE_RW | PTE_V | PTE_G | PTE_CACHE;
+	tlb_insert_wired(PCPU_TLB_ENTRY, (vm_offset_t)pcpup,
+			 TLBLO_PA_TO_PFN(pa) | pte,
+			 TLBLO_PA_TO_PFN(pa + PAGE_SIZE) | pte);
 }
 #endif
 
Index: sys/mips/mips/trap.c
===================================================================
--- sys/mips/mips/trap.c	(revision 209193)
+++ sys/mips/mips/trap.c	(working copy)
@@ -396,7 +396,7 @@
 			}
 			*pte |= mips_pg_m_bit();
 			pmap_update_page(kernel_pmap, trapframe->badvaddr, *pte);
-			pa = mips_tlbpfn_to_paddr(*pte);
+			pa = TLBLO_PTE_TO_PA(*pte);
 			if (!page_is_managed(pa))
 				panic("trap: ktlbmod: unmanaged page");
 			pmap_set_modified(pa);
@@ -435,7 +435,7 @@
 			}
 			*pte |= mips_pg_m_bit();
 			pmap_update_page(pmap, trapframe->badvaddr, *pte);
-			pa = mips_tlbpfn_to_paddr(*pte);
+			pa = TLBLO_PTE_TO_PA(*pte);
 			if (!page_is_managed(pa))
 				panic("trap: utlbmod: unmanaged page");
 			pmap_set_modified(pa);

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?AANLkTik8jFkB7FTIIhyjalkfv1c0yXqse57Jzz527uf_>