Commit 0ce63670 authored by Kevin Hao's avatar Kevin Hao Committed by Benjamin Herrenschmidt
Browse files

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: default avatarKevin Hao <haokexin@gmail.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent dfee0efe
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -41,8 +41,20 @@ struct ppc64_caches {
extern struct ppc64_caches ppc64_caches;
#endif /* __powerpc64__ && ! __ASSEMBLY__ */

#if !defined(__ASSEMBLY__)
#if defined(__ASSEMBLY__)
/*
 * For a snooping icache, we still need a dummy icbi to purge all the
 * prefetched instructions from the ifetch buffers. We also need a sync
 * before the icbi to order the the actual stores to memory that might
 * have modified instructions with the icbi.
 */
#define PURGE_PREFETCHED_INS	\
	sync;			\
	icbi	0,r3;		\
	sync;			\
	isync

#else
#define __read_mostly __attribute__((__section__(".data..read_mostly")))

#ifdef CONFIG_6xx
+3 −1
Original line number Diff line number Diff line
@@ -344,7 +344,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_UNIFIED_ID_CACHE)
 */
_KPROBE(flush_icache_range)
BEGIN_FTR_SECTION
	isync
	PURGE_PREFETCHED_INS
	blr				/* for 601, do nothing */
END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
	li	r5,L1_CACHE_BYTES-1
@@ -448,6 +448,7 @@ _GLOBAL(invalidate_dcache_range)
 */
_GLOBAL(__flush_dcache_icache)
BEGIN_FTR_SECTION
	PURGE_PREFETCHED_INS
	blr
END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
	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)
 */
_GLOBAL(__flush_dcache_icache_phys)
BEGIN_FTR_SECTION
	PURGE_PREFETCHED_INS
	blr					/* for 601, do nothing */
END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
	mfmsr	r10
+6 −0
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@ PPC64_CACHES:

_KPROBE(flush_icache_range)
BEGIN_FTR_SECTION
	PURGE_PREFETCHED_INS
	blr
END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
/*
@@ -211,6 +212,11 @@ _GLOBAL(__flush_dcache_icache)
 * Different systems have different cache line sizes
 */

BEGIN_FTR_SECTION
	PURGE_PREFETCHED_INS
	blr
END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)

/* Flush the dcache */
 	ld	r7,PPC64_CACHES@toc(r2)
	clrrdi	r3,r3,PAGE_SHIFT           	    /* Page align */