Ralf, The following patch is needed for the whole except_vec3_r4000 handler to be copied to its ultimate destination. It also fixes a number of obvious bugs within the handler (most notably the BadVaddr truncation). Plus minor consistency fixes. Updated to take your recent trap setup changes into account. 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.20-pre6-20021001-mips64-vec3_r4000-8 diff -up --recursive --new-file linux-mips-2.4.20-pre6-20021001.macro/arch/mips64/kernel/r4k_genex.S linux-mips-2.4.20-pre6-20021001/arch/mips64/kernel/r4k_genex.S --- linux-mips-2.4.20-pre6-20021001.macro/arch/mips64/kernel/r4k_genex.S 2002-10-01 02:56:55.000000000 +0000 +++ linux-mips-2.4.20-pre6-20021001/arch/mips64/kernel/r4k_genex.S 2002-10-01 16:18:17.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,25 +32,28 @@ 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. + * Be careful when changing this, it has to be at most 256 (as a special + * exception) bytes to fit into space reserved for the exception handler. */ - NESTED(except_vec3_r4000, 0, sp) + .set push .set noat -#if defined(R5432_CP0_INTERRUPT_WAR) - mfc0 k0, CP0_INDEX -#endif +NESTED(except_vec3_r4000, 0, sp) mfc0 k1, CP0_CAUSE - andi k1, k1, 0x7c li k0, 31<<2 + andi k1, k1, 0x7c + .set push + .set noreorder + .set nomacro beq k1, k0, handle_vced li k0, 14<<2 beq k1, k0, handle_vcei dsll k1, k1, 1 + .set pop ld k0, exception_handlers(k1) jr k0 @@ -60,51 +64,61 @@ * store will be re-executed. */ handle_vced: - mfc0 k0, CP0_BADVADDR + 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 handle_vcei: - mfc0 k0, CP0_BADVADDR + 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) + .set pop - END(except_vec3_r4000) - .set at - /* General exception vector for all other CPUs. */ - NESTED(except_vec3_generic, 0, sp) +/* General exception vector for all other CPUs. + * + * Be careful when changing this, it has to be at most 128 bytes + * to fit into space reserved for the exception handler. + */ + .set push .set noat +NESTED(except_vec3_generic, 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) - .set at +END(except_vec3_generic) + .set pop + /* - * 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! + * Special interrupt vector for MIPS64 ISA & embedded MIPS processors. + * This is a dedicated interrupt exception vector which reduces the + * interrupt processing overhead. The jump instruction will be replaced + * at the initialization time. + * + * Be careful when changing this, it has to be at most 128 bytes + * to fit into space reserved for the exception handler. */ 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.20-pre6-20021001.macro/arch/mips64/kernel/traps.c linux-mips-2.4.20-pre6-20021001/arch/mips64/kernel/traps.c --- linux-mips-2.4.20-pre6-20021001.macro/arch/mips64/kernel/traps.c 2002-10-01 02:56:55.000000000 +0000 +++ linux-mips-2.4.20-pre6-20021001/arch/mips64/kernel/traps.c 2002-10-01 16:20:50.000000000 +0000 @@ -625,8 +625,8 @@ 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."); } @@ -657,8 +657,8 @@ asmlinkage void do_reserved(struct pt_re static inline void watch_init(void) { if (mips_cpu.options & MIPS_CPU_WATCH) { - set_except_vector(23, handle_watch); - watch_available = 1; + set_except_vector(23, handle_watch); + watch_available = 1; } } @@ -742,7 +742,7 @@ void __init trap_init(void) * interrupt processing overhead. Use it where available. */ if (mips_cpu.options & MIPS_CPU_DIVEC) { - memcpy((void *)(KSEG0 + 0x200), &except_vec4, 8); + memcpy((void *)(KSEG0 + 0x200), &except_vec4, 0x80); set_cp0_cause(CAUSEF_IV); } @@ -776,9 +776,12 @@ void __init trap_init(void) if (mips_cpu.options & MIPS_CPU_MCHECK) set_except_vector(24, handle_mcheck); - if (mips_cpu.options & MIPS_CPU_VCE) + if (mips_cpu.options & MIPS_CPU_VCE) { + /* VCE and DIVEC are mutually exclusive. */ + if (mips_cpu.options & MIPS_CPU_DIVEC) + BUG(); memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000, 0x80); - else if (mips_cpu.options & MIPS_CPU_4KEX) + } else if (mips_cpu.options & MIPS_CPU_4KEX) memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x80); else memcpy((void *)(KSEG0 + 0x080), &except_vec3_generic, 0x80);