aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Hao <haokexin@gmail.com>2013-08-21 21:30:35 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-12-01 22:13:47 -0500
commit0ce636700c5bad54eda0e62903a1803f6d67b31d (patch)
treeb3302187e8e314de7c7cef55f1147c755de8e8f6
parentdfee0efe3ec8d4099c69e8234e4e4306619b9ba6 (diff)
powerpc: purge all the prefetched instructions for the coherent icache flush
As Benjamin Herrenschmidt has indicated, we still need a dummy icbi to purge all the prefetched instructions from the ifetch buffers for the snooping icache. We also need a sync before the icbi to order the actual stores to memory that might have modified instructions with the icbi. Signed-off-by: Kevin Hao <haokexin@gmail.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--arch/powerpc/include/asm/cache.h14
-rw-r--r--arch/powerpc/kernel/misc_32.S4
-rw-r--r--arch/powerpc/kernel/misc_64.S6
3 files changed, 22 insertions, 2 deletions
diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h
index 9e495c9a6a88..ed0afc1e44a4 100644
--- a/arch/powerpc/include/asm/cache.h
+++ b/arch/powerpc/include/asm/cache.h
@@ -41,8 +41,20 @@ struct ppc64_caches {
41extern struct ppc64_caches ppc64_caches; 41extern struct ppc64_caches ppc64_caches;
42#endif /* __powerpc64__ && ! __ASSEMBLY__ */ 42#endif /* __powerpc64__ && ! __ASSEMBLY__ */
43 43
44#if !defined(__ASSEMBLY__) 44#if defined(__ASSEMBLY__)
45/*
46 * For a snooping icache, we still need a dummy icbi to purge all the
47 * prefetched instructions from the ifetch buffers. We also need a sync
48 * before the icbi to order the the actual stores to memory that might
49 * have modified instructions with the icbi.
50 */
51#define PURGE_PREFETCHED_INS \
52 sync; \
53 icbi 0,r3; \
54 sync; \
55 isync
45 56
57#else
46#define __read_mostly __attribute__((__section__(".data..read_mostly"))) 58#define __read_mostly __attribute__((__section__(".data..read_mostly")))
47 59
48#ifdef CONFIG_6xx 60#ifdef CONFIG_6xx
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index e47d268727a4..879f09620f83 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -344,7 +344,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_UNIFIED_ID_CACHE)
344 */ 344 */
345_KPROBE(flush_icache_range) 345_KPROBE(flush_icache_range)
346BEGIN_FTR_SECTION 346BEGIN_FTR_SECTION
347 isync 347 PURGE_PREFETCHED_INS
348 blr /* for 601, do nothing */ 348 blr /* for 601, do nothing */
349END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) 349END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
350 li r5,L1_CACHE_BYTES-1 350 li r5,L1_CACHE_BYTES-1
@@ -448,6 +448,7 @@ _GLOBAL(invalidate_dcache_range)
448 */ 448 */
449_GLOBAL(__flush_dcache_icache) 449_GLOBAL(__flush_dcache_icache)
450BEGIN_FTR_SECTION 450BEGIN_FTR_SECTION
451 PURGE_PREFETCHED_INS
451 blr 452 blr
452END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) 453END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
453 rlwinm r3,r3,0,0,31-PAGE_SHIFT /* Get page base address */ 454 rlwinm r3,r3,0,0,31-PAGE_SHIFT /* Get page base address */
@@ -489,6 +490,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_44x)
489 */ 490 */
490_GLOBAL(__flush_dcache_icache_phys) 491_GLOBAL(__flush_dcache_icache_phys)
491BEGIN_FTR_SECTION 492BEGIN_FTR_SECTION
493 PURGE_PREFETCHED_INS
492 blr /* for 601, do nothing */ 494 blr /* for 601, do nothing */
493END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) 495END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
494 mfmsr r10 496 mfmsr r10
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
index e59caf874d05..a9f7a79a3a40 100644
--- a/arch/powerpc/kernel/misc_64.S
+++ b/arch/powerpc/kernel/misc_64.S
@@ -67,6 +67,7 @@ PPC64_CACHES:
67 67
68_KPROBE(flush_icache_range) 68_KPROBE(flush_icache_range)
69BEGIN_FTR_SECTION 69BEGIN_FTR_SECTION
70 PURGE_PREFETCHED_INS
70 blr 71 blr
71END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) 72END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
72/* 73/*
@@ -211,6 +212,11 @@ _GLOBAL(__flush_dcache_icache)
211 * Different systems have different cache line sizes 212 * Different systems have different cache line sizes
212 */ 213 */
213 214
215BEGIN_FTR_SECTION
216 PURGE_PREFETCHED_INS
217 blr
218END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
219
214/* Flush the dcache */ 220/* Flush the dcache */
215 ld r7,PPC64_CACHES@toc(r2) 221 ld r7,PPC64_CACHES@toc(r2)
216 clrrdi r3,r3,PAGE_SHIFT /* Page align */ 222 clrrdi r3,r3,PAGE_SHIFT /* Page align */