Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arch/tile: disable GX prefetcher during cache flush

Otherwise, it's possible to end up with the prefetcher pulling
data into cache that the code believes has been flushed.

Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>

+18
+18
arch/tile/lib/cacheflush.c
··· 15 15 #include <asm/page.h> 16 16 #include <asm/cacheflush.h> 17 17 #include <arch/icache.h> 18 + #include <arch/spr_def.h> 18 19 19 20 20 21 void __flush_icache_range(unsigned long start, unsigned long end) ··· 40 39 char *p, *base; 41 40 size_t step_size, load_count; 42 41 const unsigned long STRIPE_WIDTH = 8192; 42 + #ifdef __tilegx__ 43 + /* 44 + * On TILE-Gx, we must disable the dstream prefetcher before doing 45 + * a cache flush; otherwise, we could end up with data in the cache 46 + * that we don't want there. Note that normally we'd do an mf 47 + * after the SPR write to disabling the prefetcher, but we do one 48 + * below, before any further loads, so there's no need to do it 49 + * here. 50 + */ 51 + uint_reg_t old_dstream_pf = __insn_mfspr(SPR_DSTREAM_PF); 52 + __insn_mtspr(SPR_DSTREAM_PF, 0); 53 + #endif 43 54 44 55 /* 45 56 * Flush and invalidate the buffer out of the local L1/L2 ··· 135 122 136 123 /* Wait for the load+inv's (and thus finvs) to have completed. */ 137 124 __insn_mf(); 125 + 126 + #ifdef __tilegx__ 127 + /* Reenable the prefetcher. */ 128 + __insn_mtspr(SPR_DSTREAM_PF, old_dstream_pf); 129 + #endif 138 130 }