[patch] MIPS64 R4k general exception handler

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




Hello,

 Similarly to the refill handlers, the R4k (VCEI/VCED) general exception
handler no longer fits in 128 bytes.  I decided the simplest effective
solution is to remove the special case and use only a single generic
handler and only install pointers for VCEI and VCED in the exception
vector table.  Here is a patch.

 There is a small update to the VCEI and VCED handlers included as well --
a dmfc0 is required to properly fetch BadVAddr. 

 While fiddling with trap_init() I decided to rearrange it a bit more
consistently with the MIPS version.  Specifically vectors unspecific to
any particular processor are now installed outside the switch statement.

 OK to apply?

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

patch-mips-2.4.19-rc1-20020821-mips64-vec3_r4000-5
diff -up --recursive --new-file linux-mips-2.4.19-rc1-20020821.macro/arch/mips64/kernel/r4k_genex.S linux-mips-2.4.19-rc1-20020821/arch/mips64/kernel/r4k_genex.S
--- linux-mips-2.4.19-rc1-20020821.macro/arch/mips64/kernel/r4k_genex.S	2002-07-15 02:57:48.000000000 +0000
+++ linux-mips-2.4.19-rc1-20020821/arch/mips64/kernel/r4k_genex.S	2002-08-25 22:48:31.000000000 +0000
@@ -5,6 +5,7 @@
  *
  * Copyright (C) 1994 - 1999 by Ralf Baechle
  * Copyright (C) 1999 Silicon Graphics
+ * Copyright (C) 2002  Maciej W. Rozycki
  *
  * Low level exception handling
  */
@@ -31,69 +32,60 @@
 	BUILD_HANDLER mcheck mcheck cli verbose		/* #24 */
 	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
-#if defined(R5432_CP0_INTERRUPT_WAR)
-	mfc0    k0, CP0_INDEX
-#endif
-	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
+	.set	noat
+	.align	5
+LEAF(handle_vced)
+	dmfc0	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)
+	dla	k0, vced_count
+	lw	k1, (k0)
 	addiu	k1, 1
-	sw	k1, %lo(vced_count)(k0)
+	sw	k1, (k0)
 	eret
+END(handle_vced)
+	.set	at
 
-handle_vcei:
-	mfc0	k0, CP0_BADVADDR
+	.set	noat
+	.align	5
+LEAF(handle_vcei)
+	dmfc0	k0, CP0_BADVADDR
 	cache	Hit_Writeback_Inv_SD,(k0)		# also cleans pi
-	lui	k0, %hi(vcei_count)
-	lw	k1, %lo(vcei_count)(k0)
+	dla	k0, vcei_count
+	lw	k1, (k0)
 	addiu	k1, 1
-	sw	k1, %lo(vcei_count)(k0)
+	sw	k1, (k0)
 	eret
-
-	END(except_vec3_r4000)
+END(handle_vcei)
 	.set	at
 
-	/* General exception vector for all other CPUs. */
-	NESTED(except_vec3_generic, 0, sp)
+	__INIT
+
+/* General exception vector.
+ *
+ * Be careful when changing this, it has to be at most 128 bytes
+ * to fit into space reserved for the exception handler.
+ */
 	.set	noat
+NESTED(except_vec3, 0, sp)
+#if defined(R5432_CP0_INTERRUPT_WAR)
+	mfc0    k0, CP0_INDEX
+#endif
 	mfc0	k1, CP0_CAUSE
 	andi	k1, k1, 0x7c
 	dsll	k1, k1, 1
 	ld	k0, exception_handlers(k1)
 	jr	k0
-	 nop
-	END(except_vec3_generic)
+END(except_vec3)
 	.set	at
 
 /*
@@ -104,7 +96,6 @@ handle_vcei:
  */
 NESTED(except_vec4, 0, sp)
 1:	j	1b			/* Dummy, will be replaced */
-	 nop
-	END(except_vec4)
+END(except_vec4)
 
 	__FINIT
diff -up --recursive --new-file linux-mips-2.4.19-rc1-20020821.macro/arch/mips64/kernel/traps.c linux-mips-2.4.19-rc1-20020821/arch/mips64/kernel/traps.c
--- linux-mips-2.4.19-rc1-20020821.macro/arch/mips64/kernel/traps.c	2002-08-06 02:57:36.000000000 +0000
+++ linux-mips-2.4.19-rc1-20020821/arch/mips64/kernel/traps.c	2002-08-25 19:21:22.000000000 +0000
@@ -46,9 +46,11 @@ extern asmlinkage void handle_ri(void);
 extern asmlinkage void handle_cpu(void);
 extern asmlinkage void handle_ov(void);
 extern asmlinkage void handle_tr(void);
+extern asmlinkage void handle_vcei(void);
 extern asmlinkage void handle_fpe(void);
 extern asmlinkage void handle_watch(void);
 extern asmlinkage void handle_mcheck(void);
+extern asmlinkage void handle_vced(void);
 extern asmlinkage void handle_reserved(void);
 
 extern int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp,
@@ -627,13 +629,15 @@ asmlinkage void do_watch(struct pt_regs 
 	 * We use the watch exception where available to detect stack
 	 * overflows.
 	 */
-	dump_tlb_all();
 	show_regs(regs);
+	dump_tlb_all();
 	panic("Caught WATCH exception - probably caused by stack overflow.");
 }
 
 asmlinkage void do_mcheck(struct pt_regs *regs)
 {
+	extern void dump_tlb_all(void);
+
 	show_regs(regs);
 	dump_tlb_all();
 	/*
@@ -729,7 +733,7 @@ void __init trap_init(void)
 	extern char except_vec1_r4k;
 	extern char except_vec1_r10k;
 	extern char except_vec2_generic;
-	extern char except_vec3_generic, except_vec3_r4000;
+	extern char except_vec3;
 	extern char except_vec4;
 	unsigned long i;
 	int dummy;
@@ -738,7 +742,8 @@ void __init trap_init(void)
 
 	/* Copy the generic exception handlers to their final destination. */
 	memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80);
-	memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x80);
+	memcpy((void *)(KSEG0 + 0x180), &except_vec3, 0x80);
+	memcpy((void *)(KSEG0 + 0x200), &except_vec4, 8);
 
 	/*
 	 * Setup default vectors
@@ -753,21 +758,34 @@ void __init trap_init(void)
 	watch_init(mips_cpu.cputype);
 
 	/*
-	 * Some MIPS CPUs have a dedicated interrupt vector which reduces the
-	 * interrupt processing overhead.  Use it where available.
-	 */
-	memcpy((void *)(KSEG0 + 0x200), &except_vec4, 8);
-
-	if (mips_cpu.options & MIPS_CPU_MCHECK)
-		set_except_vector(24, handle_mcheck);
-
-	/*
 	 * The Data Bus Errors / Instruction Bus Errors are signaled
 	 * by external hardware.  Therefore these two exceptions
 	 * may have board specific handlers.
 	 */
 	bus_error_init();
 
+	set_except_vector(4, handle_adel);
+	set_except_vector(5, handle_ades);
+
+	set_except_vector(6, handle_ibe);
+	set_except_vector(7, handle_dbe);
+
+	set_except_vector(8, handle_sys);
+	set_except_vector(9, handle_bp);
+	set_except_vector(10, handle_ri);
+	set_except_vector(11, handle_cpu);
+	set_except_vector(12, handle_ov);
+	set_except_vector(13, handle_tr);
+	set_except_vector(15, handle_fpe);
+
+	if (mips_cpu.options & MIPS_CPU_VCE) {
+		set_except_vector(14, handle_vcei);
+		set_except_vector(31, handle_vced);
+	}
+
+	if (mips_cpu.options & MIPS_CPU_MCHECK)
+		set_except_vector(24, handle_mcheck);
+
 	/*
 	 * Handling the following exceptions depends mostly of the cpu type
 	 */
@@ -809,30 +827,11 @@ void __init trap_init(void)
 		} else {
 			memcpy((void *)KSEG0 + 0x080, &except_vec1_r10k, 0x80);
 		}
-		if (mips_cpu.options & MIPS_CPU_VCE) {
-			memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000,
-			       0x80);
-		} else {
-			memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic,
-			       0x80);
-		}
 
 		set_except_vector(1, __xtlb_mod);
 		set_except_vector(2, __xtlb_tlbl);
 		set_except_vector(3, __xtlb_tlbs);
-		set_except_vector(4, handle_adel);
-		set_except_vector(5, handle_ades);
-
-		set_except_vector(6, handle_ibe);
-		set_except_vector(7, handle_dbe);
 
-		set_except_vector(8, handle_sys);
-		set_except_vector(9, handle_bp);
-		set_except_vector(10, handle_ri);
-		set_except_vector(11, handle_cpu);
-		set_except_vector(12, handle_ov);
-		set_except_vector(13, handle_tr);
-		set_except_vector(15, handle_fpe);
 		break;
 
 	case CPU_R8000:



[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux