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: