patch-2.3.48 linux/arch/mips64/kernel/r4k_genex.S

Next file: linux/arch/mips64/kernel/r4k_switch.S
Previous file: linux/arch/mips64/kernel/r4k_fpu.S
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.47/linux/arch/mips64/kernel/r4k_genex.S linux/arch/mips64/kernel/r4k_genex.S
@@ -0,0 +1,168 @@
+/* $Id: r4k_genex.S,v 1.3 2000/01/20 23:32:21 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics
+ *
+ * Low level exception handling
+ */
+#define __ASSEMBLY__
+#include <linux/init.h>
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+#include <asm/r4kcacheops.h>
+
+	.macro	__build_clear_none
+	.endm
+
+	.macro	__build_clear_sti
+	STI
+	.endm
+
+	.macro	__build_clear_cli
+	CLI
+	.endm
+
+	.macro	__build_clear_fpe
+	cfc1	a1, fcr31
+	li	a2, ~(0x3f << 13)
+	and	a2, a1
+	ctc1	a2, fcr31
+	STI
+	.endm
+
+	.macro	__build_clear_ade
+	dmfc0	t0, CP0_BADVADDR
+	sd	t0, PT_BVADDR(sp)
+	KMODE
+	.endm
+
+	.macro	__BUILD_silent exception
+	.endm
+
+	/* Gas tries to parse the PRINT argument as a string containing
+	   string escapes and emits bogus warnings if it believes to
+	   recognize an unknown escape code.  So make the arguments
+	   start with an n and gas will believe \n is ok ...  */
+	.macro	__BUILD_verbose	nexception
+	ld	a1, PT_EPC(sp)
+	PRINT("Got \nexception at %016lx\012")
+	.endm
+
+	.macro	__BUILD_count exception
+	.set	reorder
+	ld	t0,exception_count_\exception
+	daddiu	t0, 1
+	sd	t0,exception_count_\exception
+	.set	noreorder
+	.comm	exception_count\exception, 8, 8
+	.endm
+
+	.macro	BUILD_HANDLER exception handler clear verbose
+	.align	5
+	NESTED(handle_\exception, PT_SIZE, sp)
+	.set	noat
+	SAVE_ALL
+	__BUILD_clear_\clear
+	.set	at
+	__BUILD_\verbose \exception
+	move	a0, sp
+	jal	do_\handler
+	j	ret_from_sys_call
+	 nop
+	END(handle_\exception)
+	.endm
+
+	BUILD_HANDLER adel ade ade silent		/* #4  */
+	BUILD_HANDLER ades ade ade silent		/* #5  */
+	BUILD_HANDLER ibe ibe cli silent		/* #6  */
+	BUILD_HANDLER dbe dbe cli silent		/* #7  */
+	BUILD_HANDLER bp bp sti silent			/* #9  */
+	BUILD_HANDLER ri ri sti silent			/* #10 */
+	BUILD_HANDLER cpu cpu sti silent		/* #11 */
+	BUILD_HANDLER ov ov sti silent			/* #12 */
+	BUILD_HANDLER tr tr sti silent			/* #13 */
+	BUILD_HANDLER fpe fpe fpe silent		/* #15 */
+	BUILD_HANDLER watch watch sti verbose		/* #23 */
+	BUILD_HANDLER reserved reserved sti verbose	/* others */
+
+	__INIT
+
+/* General exception handler for CPUs with virtual coherency exception.
+ *
+ * Be careful when changing this, it has to be at most 128 bytes to fit
+ * into space reserved for the exception handler.
+ */
+	NESTED(except_vec3_r4000, 0, sp)
+	.set	noat
+	mfc0	k1, CP0_CAUSE
+	andi	k1, k1, 0x7c
+	li	k0, 31<<2
+	beq	k1, k0, handle_vced
+	 li	k0, 14<<2
+	beq	k1, k0, handle_vcei
+	 dsll	k1, k1, 1
+	ld	k0, exception_handlers(k1)
+	jr	k0
+
+/*
+ * Big shit, we now may have two dirty primary cache lines for the same
+ * physical address.  We can savely invalidate the line pointed to by
+ * c0_badvaddr because after return from this exception handler the load /
+ * store will be re-executed.
+ */
+handle_vced:
+	mfc0	k0, CP0_BADVADDR
+	li	k1, -4					# Is this ...
+	and	k0, k1					# ... really needed?
+	mtc0	zero, CP0_TAGLO
+	cache	Index_Store_Tag_D,(k0)
+	cache	Hit_Writeback_Inv_SD,(k0)
+	lui	k0, %hi(vced_count)
+	lw	k1, %lo(vced_count)(k0)
+	addiu	k1, 1
+	sw	k1, %lo(vced_count)(k0)
+	eret
+
+handle_vcei:
+	mfc0	k0, CP0_BADVADDR
+	cache	Hit_Writeback_Inv_SD,(k0)		# also cleans pi
+	lui	k0, %hi(vcei_count)
+	lw	k1, %lo(vcei_count)(k0)
+	addiu	k1, 1
+	sw	k1, %lo(vcei_count)(k0)
+	eret
+
+	END(except_vec3_r4000)
+	.set	at
+
+	/* General exception vector for all other CPUs. */
+	NESTED(except_vec3_generic, 0, sp)
+	.set	noat
+	mfc0	k1, CP0_CAUSE
+	andi	k1, k1, 0x7c
+	dsll	k1, k1, 1
+	ld	k0, exception_handlers(k1)
+	jr	k0
+	 nop
+	END(except_vec3_generic)
+	.set	at
+
+/*
+ * Special interrupt vector for embedded MIPS.  This is a dedicated interrupt
+ * vector which reduces interrupt processing overhead.  The jump instruction
+ * will be inserted here at initialization time.  This handler may only be 8
+ * bytes in size!
+ */
+NESTED(except_vec4, 0, sp)
+1:	j	1b			/* Dummy, will be replaced */
+	 nop
+	END(except_vec4)
+
+	__FINIT

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)