Hi,
I've found a problem with the cacheflush routines in the kernel. The
following routine from arch/mips/mm/r4xx0.c:
static void r4k_flush_cache_sigtramp(unsigned long addr)
{
addr &= ~(dc_lsize - 1);
/* These nops handle a processor errata in the R4600 silicon */
__asm__ __volatile__("nop;nop;nop;nop");
protected_writeback_dcache_line(addr);
protected_writeback_dcache_line(addr + dc_lsize);
protected_flush_icache_line(addr);
protected_flush_icache_line(addr + dc_lsize);
}
which is being compiled into the following assembler code:
0000d5a0 <r4k_flush_cache_sigtramp> lui $v1,0x0
0000d5a4 <r4k_flush_cache_sigtramp+4> lw $v1,12($v1)
0000d5a8 <r4k_flush_cache_sigtramp+8> negu $v0,$v1
0000d5ac <r4k_flush_cache_sigtramp+c> and $a0,$a0,$v0
...
0000d5c0 <r4k_flush_cache_sigtramp+20> cache Hit_Writeback_Inv_D,0($a0)
0000d5c4 <r4k_flush_cache_sigtramp+24> addu $v1,$a0,$v1
0000d5c8 <r4k_flush_cache_sigtramp+28> cache Hit_Writeback_Inv_D,0($v1)
0000d5cc <r4k_flush_cache_sigtramp+2c> cache Hit_Invalidate_I,0($a0)
0000d5d0 <r4k_flush_cache_sigtramp+30> cache Hit_Invalidate_I,0($v1)
0000d5d4 <r4k_flush_cache_sigtramp+34> jr $ra
...
... is called by setup_frame() in arch/mips/kernel/signal.c when
setting up a signal frame:
[...]
/*
* Set up the return code ...
*
* .set noreorder
* addiu sp,0x20
* li v0,__NR_sigreturn
* syscall
* .set reorder
*/
__put_user(0x27bd0000 + scc_offset, &frame->code[0]);
__put_user(0x24020000 + __NR_sigreturn, &frame->code[1]);
__put_user(0x0000000c, &frame->code[2]);
/*
* Flush caches so that the instructions will be correctly executed.
* (flush_cache_sigtramp is a function pointer)
*/
flush_cache_sigtramp((unsigned long) frame->code);
[...]
Unless I've got tomatoes of the size of a space ship on my eyes these
cache flushes do the right thing in order to guarantee the coherence
of Icache with the Dcache. Nevertheless when executing the code on a
R4600 v2.0 I get illegal instruction exceptions for the instructions
on the stack. The other MIPS processors seem not to have any problem
with this code.
Silicon problem? Anybody seen this before?
Ralf
|