Skip to content

Commit

Permalink
arch/tile: disable GX prefetcher during cache flush
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
cmetcalf-tilera committed May 4, 2011
1 parent 43d9ebb commit dbb4342
Showing 1 changed file with 18 additions and 0 deletions.
18 changes: 18 additions & 0 deletions arch/tile/lib/cacheflush.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <asm/page.h>
#include <asm/cacheflush.h>
#include <arch/icache.h>
#include <arch/spr_def.h>


void __flush_icache_range(unsigned long start, unsigned long end)
Expand All @@ -39,6 +40,18 @@ void finv_buffer_remote(void *buffer, size_t size, int hfh)
char *p, *base;
size_t step_size, load_count;
const unsigned long STRIPE_WIDTH = 8192;
#ifdef __tilegx__
/*
* On TILE-Gx, we must disable the dstream prefetcher before doing
* a cache flush; otherwise, we could end up with data in the cache
* that we don't want there. Note that normally we'd do an mf
* after the SPR write to disabling the prefetcher, but we do one
* below, before any further loads, so there's no need to do it
* here.
*/
uint_reg_t old_dstream_pf = __insn_mfspr(SPR_DSTREAM_PF);
__insn_mtspr(SPR_DSTREAM_PF, 0);
#endif

/*
* Flush and invalidate the buffer out of the local L1/L2
Expand Down Expand Up @@ -122,4 +135,9 @@ void finv_buffer_remote(void *buffer, size_t size, int hfh)

/* Wait for the load+inv's (and thus finvs) to have completed. */
__insn_mf();

#ifdef __tilegx__
/* Reenable the prefetcher. */
__insn_mtspr(SPR_DSTREAM_PF, old_dstream_pf);
#endif
}

0 comments on commit dbb4342

Please sign in to comment.