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_>
