From: NIIBE Y. <gn...@m1...> - 2001-08-03 00:45:49
|
I still see occasional (quite rare, but occurs) problem under heavy use, which I believe cache alias issue or something like that. I've protected the code which runs at P2. Here's the patch. With this, so far, so good. If possible, could Hitachi people confirm this? Is it true we should protect the interrupt when we run cache handling at P2? If it is true, I'd rather prefer it mentioned in the hardware manual. 2001-08-03 NIIBE Yutaka <gn...@m1...> * arch/sh/mm/cache-sh4.c (flush_cache_sigtramp): Protect from interrupt. (__flush_cache_page, __flush_icache_page): Likewise. (check_cache_page): Likewise. --- kernel/arch/sh/mm/cache-sh4.c Fri Aug 3 09:04:52 2001 +++ kernel/arch/sh/mm/cache-sh4.c Fri Aug 3 08:42:03 2001 @@ -192,6 +192,7 @@ void flush_icache_range(unsigned long st void flush_cache_sigtramp(unsigned long addr) { unsigned long v, index; + unsigned long flags; v = addr & ~(L1_CACHE_BYTES-1); asm volatile("ocbwb %0" @@ -199,9 +200,11 @@ void flush_cache_sigtramp(unsigned long : "m" (__m(v))); index = CACHE_IC_ADDRESS_ARRAY| (v&CACHE_IC_ENTRY_MASK); + save_and_cli(flags); jump_to_P2(); ctrl_outl(0, index); /* Clear out Valid-bit */ back_to_P1(); + restore_flags(flags); } /* @@ -211,9 +214,11 @@ void flush_cache_sigtramp(unsigned long void __flush_cache_page(unsigned long phys, int exec) { unsigned long addr, data; + unsigned long flags; phys|=CACHE_VALID; + save_and_cli(flags); jump_to_P2(); /* Loop all the D-cache */ for (addr = CACHE_OC_ADDRESS_ARRAY; @@ -236,14 +241,17 @@ void __flush_cache_page(unsigned long ph ctrl_outl(0, addr); } back_to_P1(); + save_and_cli(flags); } void __flush_icache_page(unsigned long u0, unsigned long phys) { unsigned long addr, data; + unsigned long flags; phys|=CACHE_VALID; + save_and_cli(flags); if (u0) { jump_to_P2(); /* Loop half of the I-cache */ @@ -269,6 +277,7 @@ void __flush_icache_page(unsigned long u } back_to_P1(); } + restore_flags(flags); } /* @@ -377,12 +386,14 @@ void check_cache_page(struct page *pg) unsigned long kaddr; unsigned long cache_line_index; int bingo = 0; + unsigned long flags; /* Physical address of this page */ phys = PHYSADDR(page_address(pg)); kaddr = phys + PAGE_OFFSET; cache_line_index = (kaddr&CACHE_OC_ENTRY_MASK)>>CACHE_OC_ENTRY_SHIFT; + save_and_cli(flags); jump_to_P2(); /* Loop all the D-cache */ for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) { @@ -411,14 +422,17 @@ void check_cache_page(struct page *pg) } } back_to_P1(); + restore_flags(flags); if (bingo) { extern void dump_stack(void); if (bingo&1) printk("BINGO!\n"); +#if 0 if (bingo&2) printk("Bingo!\n"); +#endif dump_stack(); printk("--------------------\n"); } -- |