Module Name:    src
Committed By:   bouyer
Date:           Sat Aug 27 13:23:52 UTC 2011

Modified Files:
        src/common/lib/libc/arch/mips/atomic: atomic_add.S atomic_and.S
            atomic_dec.S atomic_inc.S atomic_or.S atomic_swap.S
        src/common/lib/libc/arch/mips/string: bcopy.S
        src/sys/arch/mips/include: cpuregs.h
        src/sys/arch/mips/mips: lock_stubs_ras.S mipsX_subr.S mips_fixup.c

Log Message:
loongson2f support:
- Add some loongson2 definitions to cpuregs.h, from OpenBSD
- Make sure that the at register is useable before every jump register
  instruction (exept when register is k0 or k1) because -mfix-loongson2f-btb
  needs the at register for its workaround
- add code to mips_fixup.c to handle the instructions added by
  -mfix-loongson2f-btb
- Add a ls2-specific tlb miss handler: it doesn't have separate handler
  for the xtlbmiss exeption.
- Fixes for some #ifdef MIPS3_LOONGSON2 assembly code (using the wrong
  register)


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/common/lib/libc/arch/mips/atomic/atomic_add.S \
    src/common/lib/libc/arch/mips/atomic/atomic_and.S \
    src/common/lib/libc/arch/mips/atomic/atomic_dec.S \
    src/common/lib/libc/arch/mips/atomic/atomic_inc.S \
    src/common/lib/libc/arch/mips/atomic/atomic_or.S \
    src/common/lib/libc/arch/mips/atomic/atomic_swap.S
cvs rdiff -u -r1.3 -r1.4 src/common/lib/libc/arch/mips/string/bcopy.S
cvs rdiff -u -r1.85 -r1.86 src/sys/arch/mips/include/cpuregs.h
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/mips/mips/lock_stubs_ras.S
cvs rdiff -u -r1.53 -r1.54 src/sys/arch/mips/mips/mipsX_subr.S
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/mips/mips/mips_fixup.c

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

Modified files:

Index: src/common/lib/libc/arch/mips/atomic/atomic_add.S
diff -u src/common/lib/libc/arch/mips/atomic/atomic_add.S:1.2 src/common/lib/libc/arch/mips/atomic/atomic_add.S:1.3
--- src/common/lib/libc/arch/mips/atomic/atomic_add.S:1.2	Mon Dec 14 00:38:59 2009
+++ src/common/lib/libc/arch/mips/atomic/atomic_add.S	Sat Aug 27 13:23:52 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: atomic_add.S,v 1.2 2009/12/14 00:38:59 matt Exp $	*/
+/*	$NetBSD: atomic_add.S,v 1.3 2011/08/27 13:23:52 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -30,12 +30,21 @@
 #include <machine/asm.h>
 #include "atomic_op_asm.h"
 
-RCSID("$NetBSD: atomic_add.S,v 1.2 2009/12/14 00:38:59 matt Exp $")
+RCSID("$NetBSD: atomic_add.S,v 1.3 2011/08/27 13:23:52 bouyer Exp $")
 
 	.text
-	.set	noat
 	.set	noreorder
+#ifdef _KERNEL_OPT
+#include "opt_cputype.h"
+#ifndef MIPS3_LOONGSON2F
+	.set	noat
+	.set	nomacro
+#endif
+#else /* _KERNEL_OPT */
+	.set	noat
 	.set	nomacro
+#endif /* _KERNEL_OPT */
+
 
 LEAF(_atomic_add_32)
 1:	INT_LL		t0, 0(a0)
Index: src/common/lib/libc/arch/mips/atomic/atomic_and.S
diff -u src/common/lib/libc/arch/mips/atomic/atomic_and.S:1.2 src/common/lib/libc/arch/mips/atomic/atomic_and.S:1.3
--- src/common/lib/libc/arch/mips/atomic/atomic_and.S:1.2	Mon Dec 14 00:38:59 2009
+++ src/common/lib/libc/arch/mips/atomic/atomic_and.S	Sat Aug 27 13:23:52 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: atomic_and.S,v 1.2 2009/12/14 00:38:59 matt Exp $	*/
+/*	$NetBSD: atomic_and.S,v 1.3 2011/08/27 13:23:52 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -30,12 +30,21 @@
 #include <machine/asm.h>
 #include "atomic_op_asm.h"
 
-RCSID("$NetBSD: atomic_and.S,v 1.2 2009/12/14 00:38:59 matt Exp $")
+RCSID("$NetBSD: atomic_and.S,v 1.3 2011/08/27 13:23:52 bouyer Exp $")
 
 	.text
-	.set	noat
 	.set	noreorder
+#ifdef _KERNEL_OPT
+#include "opt_cputype.h"
+#ifndef MIPS3_LOONGSON2F
+	.set	noat
+	.set	nomacro
+#endif
+#else /* _KERNEL_OPT */
+	.set	noat
 	.set	nomacro
+#endif /* _KERNEL_OPT */
+
 
 LEAF(_atomic_and_32)
 1:	INT_LL		t0, 0(a0)
Index: src/common/lib/libc/arch/mips/atomic/atomic_dec.S
diff -u src/common/lib/libc/arch/mips/atomic/atomic_dec.S:1.2 src/common/lib/libc/arch/mips/atomic/atomic_dec.S:1.3
--- src/common/lib/libc/arch/mips/atomic/atomic_dec.S:1.2	Mon Dec 14 00:39:00 2009
+++ src/common/lib/libc/arch/mips/atomic/atomic_dec.S	Sat Aug 27 13:23:52 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: atomic_dec.S,v 1.2 2009/12/14 00:39:00 matt Exp $	*/
+/*	$NetBSD: atomic_dec.S,v 1.3 2011/08/27 13:23:52 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -30,12 +30,20 @@
 #include <machine/asm.h>
 #include "atomic_op_asm.h"
 
-RCSID("$NetBSD: atomic_dec.S,v 1.2 2009/12/14 00:39:00 matt Exp $")
+RCSID("$NetBSD: atomic_dec.S,v 1.3 2011/08/27 13:23:52 bouyer Exp $")
 
 	.text
-	.set	noat
 	.set	noreorder
+#ifdef _KERNEL_OPT
+#include "opt_cputype.h"
+#ifndef MIPS3_LOONGSON2F
+	.set	noat
+	.set	nomacro
+#endif
+#else /* _KERNEL_OPT */
+	.set	noat
 	.set	nomacro
+#endif /* _KERNEL_OPT */
 
 LEAF(_atomic_dec_32)
 1:	INT_LL		t0, 0(a0)
Index: src/common/lib/libc/arch/mips/atomic/atomic_inc.S
diff -u src/common/lib/libc/arch/mips/atomic/atomic_inc.S:1.2 src/common/lib/libc/arch/mips/atomic/atomic_inc.S:1.3
--- src/common/lib/libc/arch/mips/atomic/atomic_inc.S:1.2	Mon Dec 14 00:39:00 2009
+++ src/common/lib/libc/arch/mips/atomic/atomic_inc.S	Sat Aug 27 13:23:52 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: atomic_inc.S,v 1.2 2009/12/14 00:39:00 matt Exp $	*/
+/*	$NetBSD: atomic_inc.S,v 1.3 2011/08/27 13:23:52 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -30,12 +30,21 @@
 #include <machine/asm.h>
 #include "atomic_op_asm.h"
 
-RCSID("$NetBSD: atomic_inc.S,v 1.2 2009/12/14 00:39:00 matt Exp $")
+RCSID("$NetBSD: atomic_inc.S,v 1.3 2011/08/27 13:23:52 bouyer Exp $")
 
 	.text
-	.set	noat
 	.set	noreorder
+#ifdef _KERNEL_OPT
+#include "opt_cputype.h"
+#ifndef MIPS3_LOONGSON2F
+	.set	noat
+	.set	nomacro
+#endif
+#else /* _KERNEL_OPT */
+	.set	noat
 	.set	nomacro
+#endif /* _KERNEL_OPT */
+
 
 LEAF(_atomic_inc_32)
 1:	INT_LL		t0, 0(a0)
Index: src/common/lib/libc/arch/mips/atomic/atomic_or.S
diff -u src/common/lib/libc/arch/mips/atomic/atomic_or.S:1.2 src/common/lib/libc/arch/mips/atomic/atomic_or.S:1.3
--- src/common/lib/libc/arch/mips/atomic/atomic_or.S:1.2	Mon Dec 14 00:39:00 2009
+++ src/common/lib/libc/arch/mips/atomic/atomic_or.S	Sat Aug 27 13:23:52 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: atomic_or.S,v 1.2 2009/12/14 00:39:00 matt Exp $	*/
+/*	$NetBSD: atomic_or.S,v 1.3 2011/08/27 13:23:52 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -31,9 +31,17 @@
 #include "atomic_op_asm.h"
 
 	.text
-	.set	noat
 	.set	noreorder
+#ifdef _KERNEL_OPT
+#include "opt_cputype.h"
+#ifndef MIPS3_LOONGSON2F
+	.set	noat
+	.set	nomacro
+#endif
+#else /* _KERNEL_OPT */
+	.set	noat
 	.set	nomacro
+#endif /* _KERNEL_OPT */
 
 LEAF(_atomic_or_32)
 1:	INT_LL		t0, 0(a0)
Index: src/common/lib/libc/arch/mips/atomic/atomic_swap.S
diff -u src/common/lib/libc/arch/mips/atomic/atomic_swap.S:1.2 src/common/lib/libc/arch/mips/atomic/atomic_swap.S:1.3
--- src/common/lib/libc/arch/mips/atomic/atomic_swap.S:1.2	Mon Dec 14 00:39:00 2009
+++ src/common/lib/libc/arch/mips/atomic/atomic_swap.S	Sat Aug 27 13:23:52 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: atomic_swap.S,v 1.2 2009/12/14 00:39:00 matt Exp $	*/
+/*	$NetBSD: atomic_swap.S,v 1.3 2011/08/27 13:23:52 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -30,12 +30,21 @@
 #include <machine/asm.h>
 #include "atomic_op_asm.h"
 
-RCSID("$NetBSD: atomic_swap.S,v 1.2 2009/12/14 00:39:00 matt Exp $")
+RCSID("$NetBSD: atomic_swap.S,v 1.3 2011/08/27 13:23:52 bouyer Exp $")
 
 	.text
-	.set	noat
 	.set	noreorder
+#ifdef _KERNEL_OPT
+#include "opt_cputype.h"
+#ifndef MIPS3_LOONGSON2F
+	.set	noat
+	.set	nomacro
+#endif
+#else /* _KERNEL_OPT */
+	.set	noat
 	.set	nomacro
+#endif /* _KERNEL_OPT */
+
 
 LEAF(_atomic_swap_32)
 1:	INT_LL		v0, 0(a0)

Index: src/common/lib/libc/arch/mips/string/bcopy.S
diff -u src/common/lib/libc/arch/mips/string/bcopy.S:1.3 src/common/lib/libc/arch/mips/string/bcopy.S:1.4
--- src/common/lib/libc/arch/mips/string/bcopy.S:1.3	Mon Dec 14 00:39:00 2009
+++ src/common/lib/libc/arch/mips/string/bcopy.S	Sat Aug 27 13:23:52 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: bcopy.S,v 1.3 2009/12/14 00:39:00 matt Exp $	*/
+/*	$NetBSD: bcopy.S,v 1.4 2011/08/27 13:23:52 bouyer Exp $	*/
 
 /*
  * Mach Operating System
@@ -46,7 +46,7 @@
 #if 0
 	RCSID("from: @(#)mips_bcopy.s	2.2 CMU 18/06/93")
 #else
-	RCSID("$NetBSD: bcopy.S,v 1.3 2009/12/14 00:39:00 matt Exp $")
+	RCSID("$NetBSD: bcopy.S,v 1.4 2011/08/27 13:23:52 bouyer Exp $")
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -170,8 +170,10 @@
 	PTR_ADDU	DSTREG,1
 
 4:	# copydone
+	.set at		#-mfix-loongson2f-btb
 	j	ra
 	nop
+	.set noat
 
 	/*
 	 *	Copy from unaligned source to aligned dest.
@@ -264,8 +266,10 @@
 	PTR_SUBU	DSTREG,1
 
 4:	# copydone
+	.set at		#-mfix-loongson2f-btb
 	j	ra
 	nop
+	.set noat
 
 	/*
 	 *	Copy from unaligned source to aligned dest.

Index: src/sys/arch/mips/include/cpuregs.h
diff -u src/sys/arch/mips/include/cpuregs.h:1.85 src/sys/arch/mips/include/cpuregs.h:1.86
--- src/sys/arch/mips/include/cpuregs.h:1.85	Tue Aug  2 05:12:32 2011
+++ src/sys/arch/mips/include/cpuregs.h	Sat Aug 27 13:23:52 2011
@@ -1,4 +1,20 @@
-/*	$NetBSD: cpuregs.h,v 1.85 2011/08/02 05:12:32 matt Exp $	*/
+/*	$NetBSD: cpuregs.h,v 1.86 2011/08/27 13:23:52 bouyer Exp $	*/
+
+/*
+ * Copyright (c) 2009 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
 
 /*
  * Copyright (c) 1992, 1993
@@ -970,4 +986,45 @@
 #include <mips/rmi/rmixlreg.h>
 #endif
 
+#ifdef MIPS3_LOONGSON2
+/*
+ * Loongson 2E/2F specific defines
+ */
+
+/*
+ * Address Window registers physical addresses
+ *
+ * The Loongson 2F processor has an AXI crossbar with four possible bus
+ * masters, each one having four programmable address windows.
+ *
+ * Each window is defined with three 64-bit registers:
+ * - a base address register, defining the address in the master address
+ *	space (base register).
+ * - an address mask register, defining which address bits are valid in this
+ *	window.	A given address matches a window if (addr & mask) == base.
+ * - the location of the window base in the target, as well at the target
+ *	number itself (mmap register). The lower 20 bits of the address are
+ *	forced as zeroes regardless of their value in this register.
+ *	The translated address is thus (addr & ~mask) | (mmap & ~0xfffff).
+ */
+
+#define LOONGSON_AWR_BASE_ADDRESS	0x3ff00000ULL
+
+#define LOONGSON_AWR_BASE(master, window) \
+	(LOONGSON_AWR_BASE_ADDRESS + (window) * 0x08 + (master) * 0x60 + 0x00)
+#define LOONGSON_AWR_SIZE(master, window) \
+	(LOONGSON_AWR_BASE_ADDRESS + (window) * 0x08 + (master) * 0x60 + 0x20)
+#define LOONGSON_AWR_MMAP(master, window) \
+	(LOONGSON_AWR_BASE_ADDRESS + (window) * 0x08 + (master) * 0x60 + 0x40)
+
+/*
+ * Bits in the diagnostic register
+ */
+
+#define COP_0_DIAG_ITLB_CLEAR	0x04
+#define COP_0_DIAG_BTB_CLEAR	0x02
+#define COP_0_DIAG_RAS_DISABLE	0x01
+
+#endif /* MIPS3_LOONGSON2 */
+
 #endif /* _MIPS_CPUREGS_H_ */

Index: src/sys/arch/mips/mips/lock_stubs_ras.S
diff -u src/sys/arch/mips/mips/lock_stubs_ras.S:1.3 src/sys/arch/mips/mips/lock_stubs_ras.S:1.4
--- src/sys/arch/mips/mips/lock_stubs_ras.S:1.3	Fri Apr 29 22:04:42 2011
+++ src/sys/arch/mips/mips/lock_stubs_ras.S	Sat Aug 27 13:23:52 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: lock_stubs_ras.S,v 1.3 2011/04/29 22:04:42 matt Exp $	*/
+/*	$NetBSD: lock_stubs_ras.S,v 1.4 2011/08/27 13:23:52 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -81,6 +81,20 @@
 	.set	noat
 
 /*
+ * to work around the branch prediction engine misbehavior of
+ * Loongson 2F processors we need to clear the branch target buffer before
+ * a j ra.  This requires extra instructions which don't fit in the RAS blocks,
+ * so do a PC-relative just to a block of code (this is the same size as
+ * a j ra) where we can let the assembler install the workaround.
+ */
+#ifdef MIPS3_LOONGSON2F
+#define J_RA	j loongson_return
+#else
+#define J_RA	j ra
+#endif
+
+
+/*
  * unsigned long ras_atomic_cas_ulong(volatile unsigned long *val,
  *     unsigned long old, unsigned long new);
  */
@@ -89,7 +103,7 @@
 
 EXPORT(_lock_ras_start)
 STATIC_LEAF(ras_atomic_cas_noupdate)
-	j	ra
+	J_RA
 	 move	v0, t0
 END(ras_atomic_cas_noupdate)
 
@@ -105,7 +119,7 @@
  	 nop
 	PTR_S	a2, (a0)	/* <- critical section end */
 _atomic_cas_ulong_ras_end:
-	j	ra
+	J_RA
 	 move	v0, a1
 END(ras_atomic_cas_ulong)
 
@@ -125,7 +139,7 @@
  	 nop
 	INT_S	a2, (a0)	/* <- critical section end */
 _atomic_cas_uint_ras_end:
-	j	ra
+	J_RA
 	 move	v0, a1
 END(ras_atomic_cas_uint)
 
@@ -146,7 +160,7 @@
 	LONG_S	a2, (a0)	/* <- critical section end */
 _ucas_ulong_ras_end:
 	PTR_S	zero, PCB_ONFAULT(v1)
-	j	ra
+	J_RA
 	 LONG_S	t0, 0(a3)
 END(_ucas_ulong_ras)
 
@@ -165,7 +179,7 @@
 	INT_S	a2, (a0)	/* <- critical section end */
 _ucas_uint_ras_end:
 	PTR_S	zero, PCB_ONFAULT(v1)
-	j	ra
+	J_RA
 	 INT_S	t0, 0(a3)
 END(_ucas_uint_ras)
 
@@ -184,7 +198,7 @@
 	 nop			
 	PTR_S	MIPS_CURLWP, (a0)/* <- critical section end */
 _mutex_enter_ras_end:
-	j	ra
+	J_RA
 	 nop
 END(ras_mutex_enter)
 
@@ -203,7 +217,7 @@
 	 nop			
 	PTR_S	zero, (a0)	/* <- critical section end */
 _mutex_exit_ras_exit:
-	j	ra
+	J_RA
 	 nop
 END(ras_mutex_exit)
 
@@ -223,6 +237,13 @@
 
 	.p2align LOG2_MIPS_LOCK_RAS_SIZE	/* Get out of the RAS block */
 
+	.set at
+#ifdef MIPS3_LOONGSON2F
+loongson_return:
+	j	ra
+	 nop
+#endif
+
 /*
  * Patch up the given address.  We arrive here if we might have trapped
  * within one of the critical sections above.  Do:

Index: src/sys/arch/mips/mips/mipsX_subr.S
diff -u src/sys/arch/mips/mips/mipsX_subr.S:1.53 src/sys/arch/mips/mips/mipsX_subr.S:1.54
--- src/sys/arch/mips/mips/mipsX_subr.S:1.53	Tue Aug 16 06:55:12 2011
+++ src/sys/arch/mips/mips/mipsX_subr.S	Sat Aug 27 13:23:52 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: mipsX_subr.S,v 1.53 2011/08/16 06:55:12 matt Exp $	*/
+/*	$NetBSD: mipsX_subr.S,v 1.54 2011/08/27 13:23:52 bouyer Exp $	*/
 
 /*
  * Copyright 2002 Wasabi Systems, Inc.
@@ -330,8 +330,54 @@
  *
  * Don't check for invalid pte's here. We load them as well and
  * let the processor trap to load the correct value after service.
+ *
+ * Loongson2 processors don't have separate tlbmiss and xtlbmiss handlers;
+ * so we have to check for useg addresses in tlb_miss. The good news is that
+ * we can use 64 intructions form tlbmiss instead of 32.
+ * 
  *----------------------------------------------------------------------------
  */
+#ifdef MIPS3_LOONGSON2
+/* this loongson2-specific part is almost a copy of xtlb_miss */
+VECTOR(MIPSX(tlb_miss), unknown)
+	.set	noat
+	dmfc0	k0, MIPS_COP_0_BAD_VADDR	#00: k0=bad address
+#ifdef _LP64
+	nop					#01: nop
+	bltz	k0, MIPSX(kernelfault)		#02: k0<0 -> kernel fault
+	 PTR_SRL k1, k0, 31			#03: clear useg bits
+	beqz	k1, 1f				#04: k1==0 -> useg address
+	 PTR_SRL k1,k0,2*(PGSHIFT-PTR_SCALESHIFT)+(PGSHIFT-2)+PGSHIFT #05: clear valid bits
+	bnez	k1, MIPSX(nopagetable)		#06: not legal address
+	 PTR_SRL k0, 2*(PGSHIFT-PTR_SCALESHIFT)+(PGSHIFT-2) #05: k0=seg offset (almost)
+	lui	k1, %hi(CPUVAR(PMAP_SEGTAB))	#07: k1=hi of segtab
+	andi	k0, NBPG-(1<<PTR_SCALESHIFT)	#08: k0=seg offset (mask 0x3)
+	PTR_L	k1, %lo(CPUVAR(PMAP_SEGTAB))(k1)#09: k1=segment tab
+	PTR_ADDU k1, k0				#0a: k1=seg entry address
+	dmfc0	k0, MIPS_COP_0_BAD_VADDR	#0b: k0=bad address (again)
+	PTR_L	k1, 0(k1)			#0c: k1=seg entry
+	b	MIPSX(tlb_miss_common)		#0d
+	 PTR_SRL k0, 1*(PGSHIFT-PTR_SCALESHIFT)+(PGSHIFT-2) #0e: k0=seg offset (almost)
+#endif /* LP64 */
+1: /* handle useg addresses */
+	lui	k1, %hi(CPUVAR(PMAP_SEG0TAB))	#0f: k1=hi of seg0tab
+	bltz	k0, MIPSX(kernelfault)		#10: k0<0 -> kernel fault
+	 dsrl	k0, 31				#11: clear low 31 bits
+	bnez	k0, MIPSX(nopagetable)		#12: not legal address
+	 PTR_L	k1, %lo(CPUVAR(PMAP_SEG0TAB))(k1)#13: k1=segment tab base
+	dmfc0	k0, MIPS_COP_0_BAD_VADDR	#14: k0=bad address (again)
+	nop					#15
+	b	MIPSX(tlb_miss_common)		#16
+	 PTR_SRL k0, 1*(PGSHIFT-PTR_SCALESHIFT)+(PGSHIFT-2) #17: k0=seg offset (almost)
+_VECTOR_END(MIPSX(tlb_miss))
+/* dummy xtlb_miss (also a placeholder for tlb_miss_common) */
+VECTOR(MIPSX(xtlb_miss), unknown)
+	lui	k0, %hi(_C_LABEL(panic))	#00
+	addiu	k0, %lo(_C_LABEL(panic))	#01
+	lui	a0, %hi(loongson2_xtlb_miss_str) #02
+	jr	k0				#03
+	 addiu	a0, %lo(loongson2_xtlb_miss_str) #04
+#else /* !MIPS3_LOONGSON2 */
 VECTOR(MIPSX(tlb_miss), unknown)
 	.set	noat
 #ifdef MIPS3_LOONGSON2
@@ -343,6 +389,7 @@
 	bltz	k0, MIPSX(kernelfault)		#02: k0<0 -> 4f (kernel fault)
 	 PTR_SRL k0, 1*(PGSHIFT-PTR_SCALESHIFT)+(PGSHIFT-2)#03: k0=seg offset (almost)
 	PTR_L	k1, %lo(CPUVAR(PMAP_SEG0TAB))(k1)#04: k1=seg0tab
+#endif /* !MIPS3_LOONGSON2 */
 MIPSX(tlb_miss_common):
 #ifdef _LP64
 	beqz	k1, MIPSX(nopagetable)		#05: is there a pagetable?
@@ -380,8 +427,13 @@
 #endif
 	eret					#1f: return from exception
 	.set	at
+#ifdef MIPS3_LOONGSON2
+_VECTOR_END(MIPSX(xtlb_miss))
+#else
 _VECTOR_END(MIPSX(tlb_miss))
+#endif
 
+#ifndef MIPS3_LOONGSON2
 #if defined(USE_64BIT_CP0_FUNCTIONS)
 /*
  * mipsN_xtlb_miss routine
@@ -397,6 +449,9 @@
  *
  * Don't check for invalid pte's here. We load them as well and
  * let the processor trap to load the correct value after service.
+ *
+ * Loongson2 CPUs don't have separate tlbmiss and xtlbmiss, so we have
+ * to check the address size here and branch to tlb_miss if needed.
  */
 VECTOR(MIPSX(xtlb_miss), unknown)
 	.set	noat
@@ -429,6 +484,7 @@
 #else
 	.space	128
 #endif /* USE_64BIT_CP0_FUNCTIONS */
+#endif /* !MIPS3_LOONGSON2 */
 
 /*
  * Vector to real handler in KSEG1.
@@ -1431,6 +1487,7 @@
 /*
  * Call the system call handler.
  */
+	.set	at
 	jalr	t9
 	 move	a0, MIPS_CURLWP			# 1st arg is curlwp
 
@@ -1446,7 +1503,6 @@
 	lui	ra, %hi(MIPSX(user_return))	# return directly to user return
 	j	_C_LABEL(ast)
 	 PTR_ADDIU ra, %lo(MIPSX(user_return))	# return directly to user return
-	.set	at
 END(MIPSX(systemcall))
 
 /*
@@ -1716,6 +1772,8 @@
 	.globl	_C_LABEL(MIPSX(exceptionentry_end))
 _C_LABEL(MIPSX(exceptionentry_end)):
 
+	.set	at
+
 /*--------------------------------------------------------------------------
  *
  * mipsN_tlb_set_asid --
@@ -1784,8 +1842,8 @@
 	tlbwi					# update slot found
 	COP0_SYNC
 #ifdef MIPS3_LOONGSON2
-	li	k0, MIPS_DIAG_ITLB_CLEAR
-	mtc0	v0, MIPS_COP_0_DIAG		# invalidate ITLB
+	li	t1, MIPS_DIAG_ITLB_CLEAR
+	mtc0	t1, MIPS_COP_0_DIAG		# invalidate ITLB
 #elif defined(MIPS3)
 	nop					# required for QED5230
 	nop					# required for QED5230
@@ -1806,8 +1864,8 @@
 	tlbwi					# update slot found
 	COP0_SYNC
 #ifdef MIPS3_LOONGSON2
-	li	k0, MIPS_DIAG_ITLB_CLEAR
-	mtc0	v0, MIPS_COP_0_DIAG		# invalidate ITLB
+	li	t1, MIPS_DIAG_ITLB_CLEAR
+	mtc0	t1, MIPS_COP_0_DIAG		# invalidate ITLB
 #elif defined(MIPS3)
 	nop					# required for QED5230
 	nop					# required for QED5230
@@ -1927,7 +1985,7 @@
 	tlbwi
 	COP0_SYNC
 #ifdef MIPS3_LOONGSON2
-	li	k0, MIPS_DIAG_ITLB_CLEAR
+	li	v0, MIPS_DIAG_ITLB_CLEAR
 	mtc0	v0, MIPS_COP_0_DIAG		# invalidate ITLB
 #elif defined(MIPS3)
 	nop
@@ -1997,7 +2055,7 @@
 	COP0_SYNC
 
 #ifdef MIPS3_LOONGSON2
-	li	k0, MIPS_DIAG_ITLB_CLEAR
+	li	v0, MIPS_DIAG_ITLB_CLEAR
 	mtc0	v0, MIPS_COP_0_DIAG		# invalidate ITLB
 #endif
 
@@ -2052,7 +2110,7 @@
 	COP0_SYNC
 
 #ifdef MIPS3_LOONGSON2
-	li	k0, MIPS_DIAG_ITLB_CLEAR
+	li	v0, MIPS_DIAG_ITLB_CLEAR
 	mtc0	v0, MIPS_COP_0_DIAG		# invalidate ITLB
 #endif
 
@@ -2100,7 +2158,7 @@
 	COP0_SYNC
 
 #ifdef MIPS3_LOONGSON2
-	li	k0, MIPS_DIAG_ITLB_CLEAR
+	li	v0, MIPS_DIAG_ITLB_CLEAR
 	mtc0	v0, MIPS_COP_0_DIAG		# invalidate ITLB
 #endif
 
@@ -2261,14 +2319,12 @@
 	COP0_SYNC
 
 	_MTC0	ta1, MIPS_COP_0_TLB_HI		# restore EntryHi
-
 #ifdef MIPS3_LOONGSON2
-	li	k0, MIPS_DIAG_ITLB_CLEAR
+	li	v0, MIPS_DIAG_ITLB_CLEAR
 	mtc0	v0, MIPS_COP_0_DIAG		# invalidate ITLB
 #endif
-
-	JR_HB_RA
 	.set	at
+	JR_HB_RA
 END(MIPSX(tlb_enter))
 
 /*
@@ -2502,7 +2558,7 @@
 	COP0_SYNC
 
 #ifdef MIPS3_LOONGSON2
-	li	k0, MIPS_DIAG_ITLB_CLEAR
+	li	v0, MIPS_DIAG_ITLB_CLEAR
 	mtc0	v0, MIPS_COP_0_DIAG		# invalidate ITLB
 #endif
 
@@ -2539,12 +2595,12 @@
 	cache	(CACHE_R4K_D | CACHEOP_R4K_HIT_INV), 0(k0)
 #ifdef DEBUG
 	_MFC0	k0, MIPS_COP_0_BAD_VADDR
-	PTR_LA	k1, VCED_vaddr
+	PTR_LA	k1, MIPSX(VCED_vaddr)
 	PTR_S	k0, 0(k1)
 	_MFC0	k0, MIPS_COP_0_EXC_PC
-	PTR_LA	k1, VCED_epc
+	PTR_LA	k1, MIPSX(VCED_epc)
 	PTR_S	k0, 0(k1)
-	PTR_LA	k1, VCED_count		# count number of exceptions
+	PTR_LA	k1, MIPSX(VCED_count)	# count number of exceptions
 	PTR_SRL	k0, k0, 26		# position upper 4 bits of VA
 	and	k0, k0, 0x3c		# mask it off
 	PTR_ADDU k1, k0			# get address of count table
@@ -2557,14 +2613,14 @@
 
 #ifdef DEBUG
 	.data
-	.globl	_C_LABEL(VCED_count)
-_C_LABEL(VCED_count):
+	.globl	_C_LABEL(MIPSX(VCED_count))
+_C_LABEL(MIPSX(VCED_count)):
 	LONG_WORD	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-	.globl	_C_LABEL(VCED_epc)
-_C_LABEL(VCED_epc):
+	.globl	_C_LABEL(MIPSX(VCED_epc))
+_C_LABEL(MIPSX(VCED_epc)):
 	PTR_WORD	0
-	.globl	_C_LABEL(VCED_vaddr)
-_C_LABEL(VCED_vaddr):
+	.globl	_C_LABEL(MIPSX(VCED_vaddr))
+_C_LABEL(MIPSX(VCED_vaddr)):
 	PTR_WORD	0
 	.text
 #endif
@@ -2577,9 +2633,9 @@
 	cache	(CACHE_R4K_I | CACHEOP_R4K_HIT_INV), 0(k0)
 #ifdef DEBUG
 	_MFC0	k0, MIPS_COP_0_BAD_VADDR
-	PTR_LA	k1, VCEI_vaddr
+	PTR_LA	k1, MIPSX(VCEI_vaddr)
 	PTR_S	k0, 0(k1)
-	PTR_LA	k1, VCEI_count		# count number of exceptions
+	PTR_LA	k1, MIPSX(VCEI_count)	# count number of exceptions
 	PTR_SRL	k0, k0, 26		# position upper 4 bits of VA
 	and	k0, k0, 0x3c		# mask it off
 	PTR_ADDU k1, k0			# get address of count table
@@ -2592,11 +2648,11 @@
 
 #ifdef DEBUG
 	.data
-	.globl	_C_LABEL(VCEI_count)
-_C_LABEL(VCEI_count):
+	.globl	_C_LABEL(MIPSX(VCEI_count))
+_C_LABEL(MIPSX(VCEI_count)):
 	LONG_WORD	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-	.globl	_C_LABEL(VCEI_vaddr)
-_C_LABEL(VCEI_vaddr):
+	.globl	_C_LABEL(MIPSX(VCEI_vaddr))
+_C_LABEL(MIPSX(VCEI_vaddr)):
 	PTR_WORD	0
 	.text
 #endif
@@ -2740,3 +2796,7 @@
 #else
 	PTR_WORD _C_LABEL(MIPSX(user_gen_exception))	# 31
 #endif
+#ifdef MIPS3_LOONGSON2
+loongson2_xtlb_miss_str:
+	.string "loongson2_xtlb_miss"
+#endif

Index: src/sys/arch/mips/mips/mips_fixup.c
diff -u src/sys/arch/mips/mips/mips_fixup.c:1.8 src/sys/arch/mips/mips/mips_fixup.c:1.9
--- src/sys/arch/mips/mips/mips_fixup.c:1.8	Wed Aug 24 15:11:52 2011
+++ src/sys/arch/mips/mips/mips_fixup.c	Sat Aug 27 13:23:52 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: mips_fixup.c,v 1.8 2011/08/24 15:11:52 matt Exp $	*/
+/*	$NetBSD: mips_fixup.c,v 1.9 2011/08/27 13:23:52 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mips_fixup.c,v 1.8 2011/08/24 15:11:52 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mips_fixup.c,v 1.9 2011/08/27 13:23:52 bouyer Exp $");
 
 #include "opt_mips3_wired.h"
 #include "opt_multiprocessor.h"
@@ -239,7 +239,7 @@
 	 *	jr	t9
 	 *	nop
 	 *
-	 * Or for loongson2:
+	 * Or for loongson2 (
 	 *	lui	v0, %hi(sym)
 	 *	lX	t9, %lo(sym)(v0)
 	 *	lui	at,0xcfff
@@ -247,9 +247,16 @@
 	 *	and	t9,t9,at
 	 *	jr	t9
 	 *	move	at,at
+	 *   or:
+	 *	lui	v0, %hi(sym)
+	 *	lX	t9, %lo(sym)(v0)
+	 *	li	at, 0x3
+	 *	dmtc0	at, $22
+	 *	jr	t9
+	 *	nop
 	 */
 	mips_reg_t regs[32];
-	uint32_t used = 0;
+	uint32_t used = 1;
 	size_t n;
 	const char *errstr = "mips";
 	/*
@@ -293,6 +300,23 @@
 			regs[insn.IType.rt] |= insn.IType.imm;
 			used |= (1 << insn.IType.rt);
 			break;
+		case OP_COP0:
+			switch (insn.RType.rs) {
+			case OP_DMT:
+				if (insn.RType.rd != 22) {
+					errstr = "dmtc0 dst";
+					goto out;
+				}
+				if ((used & (1 << insn.RType.rt)) == 0) {
+					errstr = "dmtc0 src";
+					goto out;
+				}
+				break;
+			default:
+				errstr = "COP0";
+				goto out;
+			}
+			break;
 		case OP_SPECIAL:
 			switch (insn.RType.func) {
 			case OP_JR:

Reply via email to