aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sh/mm/cache-sh4.c5
-rw-r--r--arch/sh/mm/fault.c5
-rw-r--r--include/asm-sh/mmu_context.h7
-rw-r--r--include/asm-sh/system.h43
4 files changed, 45 insertions, 15 deletions
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c
index c036c2b4ac2b..2203bd6aadb3 100644
--- a/arch/sh/mm/cache-sh4.c
+++ b/arch/sh/mm/cache-sh4.c
@@ -269,6 +269,11 @@ static inline void flush_icache_all(void)
269 ccr |= CCR_CACHE_ICI; 269 ccr |= CCR_CACHE_ICI;
270 ctrl_outl(ccr, CCR); 270 ctrl_outl(ccr, CCR);
271 271
272 /*
273 * back_to_P1() will take care of the barrier for us, don't add
274 * another one!
275 */
276
272 back_to_P1(); 277 back_to_P1();
273 local_irq_restore(flags); 278 local_irq_restore(flags);
274} 279}
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index 775f86cd3fe8..364181f27b79 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -369,12 +369,13 @@ void flush_tlb_all(void)
369 * Flush all the TLB. 369 * Flush all the TLB.
370 * 370 *
371 * Write to the MMU control register's bit: 371 * Write to the MMU control register's bit:
372 * TF-bit for SH-3, TI-bit for SH-4. 372 * TF-bit for SH-3, TI-bit for SH-4.
373 * It's same position, bit #2. 373 * It's same position, bit #2.
374 */ 374 */
375 local_irq_save(flags); 375 local_irq_save(flags);
376 status = ctrl_inl(MMUCR); 376 status = ctrl_inl(MMUCR);
377 status |= 0x04; 377 status |= 0x04;
378 ctrl_outl(status, MMUCR); 378 ctrl_outl(status, MMUCR);
379 ctrl_barrier();
379 local_irq_restore(flags); 380 local_irq_restore(flags);
380} 381}
diff --git a/include/asm-sh/mmu_context.h b/include/asm-sh/mmu_context.h
index 6760d064bd02..87678ba8d6b6 100644
--- a/include/asm-sh/mmu_context.h
+++ b/include/asm-sh/mmu_context.h
@@ -174,9 +174,7 @@ static inline void enable_mmu(void)
174{ 174{
175 /* Enable MMU */ 175 /* Enable MMU */
176 ctrl_outl(MMU_CONTROL_INIT, MMUCR); 176 ctrl_outl(MMU_CONTROL_INIT, MMUCR);
177 177 ctrl_barrier();
178 /* The manual suggests doing some nops after turning on the MMU */
179 __asm__ __volatile__ ("nop;nop;nop;nop;nop;nop;nop;nop\n\t");
180 178
181 if (mmu_context_cache == NO_CONTEXT) 179 if (mmu_context_cache == NO_CONTEXT)
182 mmu_context_cache = MMU_CONTEXT_FIRST_VERSION; 180 mmu_context_cache = MMU_CONTEXT_FIRST_VERSION;
@@ -191,7 +189,8 @@ static inline void disable_mmu(void)
191 cr = ctrl_inl(MMUCR); 189 cr = ctrl_inl(MMUCR);
192 cr &= ~MMU_CONTROL_INIT; 190 cr &= ~MMU_CONTROL_INIT;
193 ctrl_outl(cr, MMUCR); 191 ctrl_outl(cr, MMUCR);
194 __asm__ __volatile__ ("nop;nop;nop;nop;nop;nop;nop;nop\n\t"); 192
193 ctrl_barrier();
195} 194}
196#else 195#else
197/* 196/*
diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h
index eb4902ed920a..1630a5411e5f 100644
--- a/include/asm-sh/system.h
+++ b/include/asm-sh/system.h
@@ -67,8 +67,17 @@ static inline void sched_cacheflush(void)
67{ 67{
68} 68}
69 69
70#define nop() __asm__ __volatile__ ("nop") 70#ifdef CONFIG_CPU_SH4A
71 71#define __icbi() \
72{ \
73 unsigned long __addr; \
74 __addr = 0xa8000000; \
75 __asm__ __volatile__( \
76 "icbi %0\n\t" \
77 : /* no output */ \
78 : "m" (__m(__addr))); \
79}
80#endif
72 81
73#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) 82#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
74 83
@@ -84,15 +93,31 @@ static __inline__ unsigned long tas(volatile int *m)
84 93
85extern void __xchg_called_with_bad_pointer(void); 94extern void __xchg_called_with_bad_pointer(void);
86 95
96/*
97 * A brief note on ctrl_barrier(), the control register write barrier.
98 *
99 * Legacy SH cores typically require a sequence of 8 nops after
100 * modification of a control register in order for the changes to take
101 * effect. On newer cores (like the sh4a and sh5) this is accomplished
102 * with icbi.
103 *
104 * Also note that on sh4a in the icbi case we can forego a synco for the
105 * write barrier, as it's not necessary for control registers.
106 *
107 * Historically we have only done this type of barrier for the MMUCR, but
108 * it's also necessary for the CCR, so we make it generic here instead.
109 */
87#ifdef CONFIG_CPU_SH4A 110#ifdef CONFIG_CPU_SH4A
88#define mb() __asm__ __volatile__ ("synco": : :"memory") 111#define mb() __asm__ __volatile__ ("synco": : :"memory")
89#define rmb() mb() 112#define rmb() mb()
90#define wmb() __asm__ __volatile__ ("synco": : :"memory") 113#define wmb() __asm__ __volatile__ ("synco": : :"memory")
114#define ctrl_barrier() __icbi()
91#define read_barrier_depends() do { } while(0) 115#define read_barrier_depends() do { } while(0)
92#else 116#else
93#define mb() __asm__ __volatile__ ("": : :"memory") 117#define mb() __asm__ __volatile__ ("": : :"memory")
94#define rmb() mb() 118#define rmb() mb()
95#define wmb() __asm__ __volatile__ ("": : :"memory") 119#define wmb() __asm__ __volatile__ ("": : :"memory")
120#define ctrl_barrier() __asm__ __volatile__ ("nop;nop;nop;nop;nop;nop;nop;nop")
96#define read_barrier_depends() do { } while(0) 121#define read_barrier_depends() do { } while(0)
97#endif 122#endif
98 123
@@ -218,8 +243,8 @@ do { \
218#define back_to_P1() \ 243#define back_to_P1() \
219do { \ 244do { \
220 unsigned long __dummy; \ 245 unsigned long __dummy; \
246 ctrl_barrier(); \
221 __asm__ __volatile__( \ 247 __asm__ __volatile__( \
222 "nop;nop;nop;nop;nop;nop;nop\n\t" \
223 "mov.l 1f, %0\n\t" \ 248 "mov.l 1f, %0\n\t" \
224 "jmp @%0\n\t" \ 249 "jmp @%0\n\t" \
225 " nop\n\t" \ 250 " nop\n\t" \