diff options
Diffstat (limited to 'arch/mips/mm')
-rw-r--r-- | arch/mips/mm/c-r3k.c | 2 | ||||
-rw-r--r-- | arch/mips/mm/c-r4k.c | 28 | ||||
-rw-r--r-- | arch/mips/mm/c-sb1.c | 58 | ||||
-rw-r--r-- | arch/mips/mm/c-tx39.c | 4 | ||||
-rw-r--r-- | arch/mips/mm/cache.c | 18 | ||||
-rw-r--r-- | arch/mips/mm/fault.c | 2 | ||||
-rw-r--r-- | arch/mips/mm/init.c | 4 | ||||
-rw-r--r-- | arch/mips/mm/tlb-r4k.c | 21 |
8 files changed, 70 insertions, 67 deletions
diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c index bb041a22f20a..e1f35ef81145 100644 --- a/arch/mips/mm/c-r3k.c +++ b/arch/mips/mm/c-r3k.c | |||
@@ -335,7 +335,7 @@ void __init r3k_cache_init(void) | |||
335 | flush_cache_mm = r3k_flush_cache_mm; | 335 | flush_cache_mm = r3k_flush_cache_mm; |
336 | flush_cache_range = r3k_flush_cache_range; | 336 | flush_cache_range = r3k_flush_cache_range; |
337 | flush_cache_page = r3k_flush_cache_page; | 337 | flush_cache_page = r3k_flush_cache_page; |
338 | flush_icache_page = r3k_flush_icache_page; | 338 | __flush_icache_page = r3k_flush_icache_page; |
339 | flush_icache_range = r3k_flush_icache_range; | 339 | flush_icache_range = r3k_flush_icache_range; |
340 | 340 | ||
341 | flush_cache_sigtramp = r3k_flush_cache_sigtramp; | 341 | flush_cache_sigtramp = r3k_flush_cache_sigtramp; |
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 069803f58f3b..0b2da53750bd 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c | |||
@@ -89,7 +89,7 @@ static inline void r4k_blast_dcache_page_dc32(unsigned long addr) | |||
89 | blast_dcache32_page(addr); | 89 | blast_dcache32_page(addr); |
90 | } | 90 | } |
91 | 91 | ||
92 | static inline void r4k_blast_dcache_page_setup(void) | 92 | static void __init r4k_blast_dcache_page_setup(void) |
93 | { | 93 | { |
94 | unsigned long dc_lsize = cpu_dcache_line_size(); | 94 | unsigned long dc_lsize = cpu_dcache_line_size(); |
95 | 95 | ||
@@ -103,7 +103,7 @@ static inline void r4k_blast_dcache_page_setup(void) | |||
103 | 103 | ||
104 | static void (* r4k_blast_dcache_page_indexed)(unsigned long addr); | 104 | static void (* r4k_blast_dcache_page_indexed)(unsigned long addr); |
105 | 105 | ||
106 | static inline void r4k_blast_dcache_page_indexed_setup(void) | 106 | static void __init r4k_blast_dcache_page_indexed_setup(void) |
107 | { | 107 | { |
108 | unsigned long dc_lsize = cpu_dcache_line_size(); | 108 | unsigned long dc_lsize = cpu_dcache_line_size(); |
109 | 109 | ||
@@ -117,7 +117,7 @@ static inline void r4k_blast_dcache_page_indexed_setup(void) | |||
117 | 117 | ||
118 | static void (* r4k_blast_dcache)(void); | 118 | static void (* r4k_blast_dcache)(void); |
119 | 119 | ||
120 | static inline void r4k_blast_dcache_setup(void) | 120 | static void __init r4k_blast_dcache_setup(void) |
121 | { | 121 | { |
122 | unsigned long dc_lsize = cpu_dcache_line_size(); | 122 | unsigned long dc_lsize = cpu_dcache_line_size(); |
123 | 123 | ||
@@ -202,7 +202,7 @@ static inline void tx49_blast_icache32_page_indexed(unsigned long page) | |||
202 | 202 | ||
203 | static void (* r4k_blast_icache_page)(unsigned long addr); | 203 | static void (* r4k_blast_icache_page)(unsigned long addr); |
204 | 204 | ||
205 | static inline void r4k_blast_icache_page_setup(void) | 205 | static void __init r4k_blast_icache_page_setup(void) |
206 | { | 206 | { |
207 | unsigned long ic_lsize = cpu_icache_line_size(); | 207 | unsigned long ic_lsize = cpu_icache_line_size(); |
208 | 208 | ||
@@ -219,7 +219,7 @@ static inline void r4k_blast_icache_page_setup(void) | |||
219 | 219 | ||
220 | static void (* r4k_blast_icache_page_indexed)(unsigned long addr); | 220 | static void (* r4k_blast_icache_page_indexed)(unsigned long addr); |
221 | 221 | ||
222 | static inline void r4k_blast_icache_page_indexed_setup(void) | 222 | static void __init r4k_blast_icache_page_indexed_setup(void) |
223 | { | 223 | { |
224 | unsigned long ic_lsize = cpu_icache_line_size(); | 224 | unsigned long ic_lsize = cpu_icache_line_size(); |
225 | 225 | ||
@@ -243,7 +243,7 @@ static inline void r4k_blast_icache_page_indexed_setup(void) | |||
243 | 243 | ||
244 | static void (* r4k_blast_icache)(void); | 244 | static void (* r4k_blast_icache)(void); |
245 | 245 | ||
246 | static inline void r4k_blast_icache_setup(void) | 246 | static void __init r4k_blast_icache_setup(void) |
247 | { | 247 | { |
248 | unsigned long ic_lsize = cpu_icache_line_size(); | 248 | unsigned long ic_lsize = cpu_icache_line_size(); |
249 | 249 | ||
@@ -264,7 +264,7 @@ static inline void r4k_blast_icache_setup(void) | |||
264 | 264 | ||
265 | static void (* r4k_blast_scache_page)(unsigned long addr); | 265 | static void (* r4k_blast_scache_page)(unsigned long addr); |
266 | 266 | ||
267 | static inline void r4k_blast_scache_page_setup(void) | 267 | static void __init r4k_blast_scache_page_setup(void) |
268 | { | 268 | { |
269 | unsigned long sc_lsize = cpu_scache_line_size(); | 269 | unsigned long sc_lsize = cpu_scache_line_size(); |
270 | 270 | ||
@@ -282,7 +282,7 @@ static inline void r4k_blast_scache_page_setup(void) | |||
282 | 282 | ||
283 | static void (* r4k_blast_scache_page_indexed)(unsigned long addr); | 283 | static void (* r4k_blast_scache_page_indexed)(unsigned long addr); |
284 | 284 | ||
285 | static inline void r4k_blast_scache_page_indexed_setup(void) | 285 | static void __init r4k_blast_scache_page_indexed_setup(void) |
286 | { | 286 | { |
287 | unsigned long sc_lsize = cpu_scache_line_size(); | 287 | unsigned long sc_lsize = cpu_scache_line_size(); |
288 | 288 | ||
@@ -300,7 +300,7 @@ static inline void r4k_blast_scache_page_indexed_setup(void) | |||
300 | 300 | ||
301 | static void (* r4k_blast_scache)(void); | 301 | static void (* r4k_blast_scache)(void); |
302 | 302 | ||
303 | static inline void r4k_blast_scache_setup(void) | 303 | static void __init r4k_blast_scache_setup(void) |
304 | { | 304 | { |
305 | unsigned long sc_lsize = cpu_scache_line_size(); | 305 | unsigned long sc_lsize = cpu_scache_line_size(); |
306 | 306 | ||
@@ -475,7 +475,7 @@ static inline void local_r4k_flush_cache_page(void *args) | |||
475 | } | 475 | } |
476 | } | 476 | } |
477 | if (exec) { | 477 | if (exec) { |
478 | if (cpu_has_vtag_icache) { | 478 | if (cpu_has_vtag_icache && mm == current->active_mm) { |
479 | int cpu = smp_processor_id(); | 479 | int cpu = smp_processor_id(); |
480 | 480 | ||
481 | if (cpu_context(cpu, mm) != 0) | 481 | if (cpu_context(cpu, mm) != 0) |
@@ -599,7 +599,7 @@ static inline void local_r4k_flush_icache_page(void *args) | |||
599 | * We're not sure of the virtual address(es) involved here, so | 599 | * We're not sure of the virtual address(es) involved here, so |
600 | * we have to flush the entire I-cache. | 600 | * we have to flush the entire I-cache. |
601 | */ | 601 | */ |
602 | if (cpu_has_vtag_icache) { | 602 | if (cpu_has_vtag_icache && vma->vm_mm == current->active_mm) { |
603 | int cpu = smp_processor_id(); | 603 | int cpu = smp_processor_id(); |
604 | 604 | ||
605 | if (cpu_context(cpu, vma->vm_mm) != 0) | 605 | if (cpu_context(cpu, vma->vm_mm) != 0) |
@@ -1221,7 +1221,7 @@ void au1x00_fixup_config_od(void) | |||
1221 | } | 1221 | } |
1222 | } | 1222 | } |
1223 | 1223 | ||
1224 | static inline void coherency_setup(void) | 1224 | static void __init coherency_setup(void) |
1225 | { | 1225 | { |
1226 | change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); | 1226 | change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); |
1227 | 1227 | ||
@@ -1242,7 +1242,7 @@ static inline void coherency_setup(void) | |||
1242 | clear_c0_config(CONF_CU); | 1242 | clear_c0_config(CONF_CU); |
1243 | break; | 1243 | break; |
1244 | /* | 1244 | /* |
1245 | * We need to catch the ealry Alchemy SOCs with | 1245 | * We need to catch the early Alchemy SOCs with |
1246 | * the write-only co_config.od bit and set it back to one... | 1246 | * the write-only co_config.od bit and set it back to one... |
1247 | */ | 1247 | */ |
1248 | case CPU_AU1000: /* rev. DA, HA, HB */ | 1248 | case CPU_AU1000: /* rev. DA, HA, HB */ |
@@ -1291,7 +1291,7 @@ void __init r4k_cache_init(void) | |||
1291 | __flush_cache_all = r4k___flush_cache_all; | 1291 | __flush_cache_all = r4k___flush_cache_all; |
1292 | flush_cache_mm = r4k_flush_cache_mm; | 1292 | flush_cache_mm = r4k_flush_cache_mm; |
1293 | flush_cache_page = r4k_flush_cache_page; | 1293 | flush_cache_page = r4k_flush_cache_page; |
1294 | flush_icache_page = r4k_flush_icache_page; | 1294 | __flush_icache_page = r4k_flush_icache_page; |
1295 | flush_cache_range = r4k_flush_cache_range; | 1295 | flush_cache_range = r4k_flush_cache_range; |
1296 | 1296 | ||
1297 | flush_cache_sigtramp = r4k_flush_cache_sigtramp; | 1297 | flush_cache_sigtramp = r4k_flush_cache_sigtramp; |
diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c index 2d71efb82ac5..16bad7c0a63f 100644 --- a/arch/mips/mm/c-sb1.c +++ b/arch/mips/mm/c-sb1.c | |||
@@ -155,6 +155,26 @@ static inline void __sb1_flush_icache_all(void) | |||
155 | } | 155 | } |
156 | 156 | ||
157 | /* | 157 | /* |
158 | * Invalidate a range of the icache. The addresses are virtual, and | ||
159 | * the cache is virtually indexed and tagged. However, we don't | ||
160 | * necessarily have the right ASID context, so use index ops instead | ||
161 | * of hit ops. | ||
162 | */ | ||
163 | static inline void __sb1_flush_icache_range(unsigned long start, | ||
164 | unsigned long end) | ||
165 | { | ||
166 | start &= ~(icache_line_size - 1); | ||
167 | end = (end + icache_line_size - 1) & ~(icache_line_size - 1); | ||
168 | |||
169 | while (start != end) { | ||
170 | cache_set_op(Index_Invalidate_I, start & icache_index_mask); | ||
171 | start += icache_line_size; | ||
172 | } | ||
173 | mispredict(); | ||
174 | sync(); | ||
175 | } | ||
176 | |||
177 | /* | ||
158 | * Flush the icache for a given physical page. Need to writeback the | 178 | * Flush the icache for a given physical page. Need to writeback the |
159 | * dcache first, then invalidate the icache. If the page isn't | 179 | * dcache first, then invalidate the icache. If the page isn't |
160 | * executable, nothing is required. | 180 | * executable, nothing is required. |
@@ -173,8 +193,11 @@ static void local_sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long | |||
173 | /* | 193 | /* |
174 | * Bumping the ASID is probably cheaper than the flush ... | 194 | * Bumping the ASID is probably cheaper than the flush ... |
175 | */ | 195 | */ |
176 | if (cpu_context(cpu, vma->vm_mm) != 0) | 196 | if (vma->vm_mm == current->active_mm) { |
177 | drop_mmu_context(vma->vm_mm, cpu); | 197 | if (cpu_context(cpu, vma->vm_mm) != 0) |
198 | drop_mmu_context(vma->vm_mm, cpu); | ||
199 | } else | ||
200 | __sb1_flush_icache_range(addr, addr + PAGE_SIZE); | ||
178 | } | 201 | } |
179 | 202 | ||
180 | #ifdef CONFIG_SMP | 203 | #ifdef CONFIG_SMP |
@@ -210,26 +233,6 @@ void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsign | |||
210 | __attribute__((alias("local_sb1_flush_cache_page"))); | 233 | __attribute__((alias("local_sb1_flush_cache_page"))); |
211 | #endif | 234 | #endif |
212 | 235 | ||
213 | /* | ||
214 | * Invalidate a range of the icache. The addresses are virtual, and | ||
215 | * the cache is virtually indexed and tagged. However, we don't | ||
216 | * necessarily have the right ASID context, so use index ops instead | ||
217 | * of hit ops. | ||
218 | */ | ||
219 | static inline void __sb1_flush_icache_range(unsigned long start, | ||
220 | unsigned long end) | ||
221 | { | ||
222 | start &= ~(icache_line_size - 1); | ||
223 | end = (end + icache_line_size - 1) & ~(icache_line_size - 1); | ||
224 | |||
225 | while (start != end) { | ||
226 | cache_set_op(Index_Invalidate_I, start & icache_index_mask); | ||
227 | start += icache_line_size; | ||
228 | } | ||
229 | mispredict(); | ||
230 | sync(); | ||
231 | } | ||
232 | |||
233 | 236 | ||
234 | /* | 237 | /* |
235 | * Invalidate all caches on this CPU | 238 | * Invalidate all caches on this CPU |
@@ -326,9 +329,12 @@ static void local_sb1_flush_icache_page(struct vm_area_struct *vma, | |||
326 | * If there's a context, bump the ASID (cheaper than a flush, | 329 | * If there's a context, bump the ASID (cheaper than a flush, |
327 | * since we don't know VAs!) | 330 | * since we don't know VAs!) |
328 | */ | 331 | */ |
329 | if (cpu_context(cpu, vma->vm_mm) != 0) { | 332 | if (vma->vm_mm == current->active_mm) { |
330 | drop_mmu_context(vma->vm_mm, cpu); | 333 | if (cpu_context(cpu, vma->vm_mm) != 0) |
331 | } | 334 | drop_mmu_context(vma->vm_mm, cpu); |
335 | } else | ||
336 | __sb1_flush_icache_range(start, start + PAGE_SIZE); | ||
337 | |||
332 | } | 338 | } |
333 | 339 | ||
334 | #ifdef CONFIG_SMP | 340 | #ifdef CONFIG_SMP |
@@ -520,7 +526,7 @@ void sb1_cache_init(void) | |||
520 | 526 | ||
521 | /* These routines are for Icache coherence with the Dcache */ | 527 | /* These routines are for Icache coherence with the Dcache */ |
522 | flush_icache_range = sb1_flush_icache_range; | 528 | flush_icache_range = sb1_flush_icache_range; |
523 | flush_icache_page = sb1_flush_icache_page; | 529 | __flush_icache_page = sb1_flush_icache_page; |
524 | flush_icache_all = __sb1_flush_icache_all; /* local only */ | 530 | flush_icache_all = __sb1_flush_icache_all; /* local only */ |
525 | 531 | ||
526 | /* This implies an Icache flush too, so can't be nop'ed */ | 532 | /* This implies an Icache flush too, so can't be nop'ed */ |
diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c index 5dfc9b1901f6..932a09d7ef84 100644 --- a/arch/mips/mm/c-tx39.c +++ b/arch/mips/mm/c-tx39.c | |||
@@ -382,7 +382,7 @@ void __init tx39_cache_init(void) | |||
382 | flush_cache_mm = (void *) tx39h_flush_icache_all; | 382 | flush_cache_mm = (void *) tx39h_flush_icache_all; |
383 | flush_cache_range = (void *) tx39h_flush_icache_all; | 383 | flush_cache_range = (void *) tx39h_flush_icache_all; |
384 | flush_cache_page = (void *) tx39h_flush_icache_all; | 384 | flush_cache_page = (void *) tx39h_flush_icache_all; |
385 | flush_icache_page = (void *) tx39h_flush_icache_all; | 385 | __flush_icache_page = (void *) tx39h_flush_icache_all; |
386 | flush_icache_range = (void *) tx39h_flush_icache_all; | 386 | flush_icache_range = (void *) tx39h_flush_icache_all; |
387 | 387 | ||
388 | flush_cache_sigtramp = (void *) tx39h_flush_icache_all; | 388 | flush_cache_sigtramp = (void *) tx39h_flush_icache_all; |
@@ -408,7 +408,7 @@ void __init tx39_cache_init(void) | |||
408 | flush_cache_mm = tx39_flush_cache_mm; | 408 | flush_cache_mm = tx39_flush_cache_mm; |
409 | flush_cache_range = tx39_flush_cache_range; | 409 | flush_cache_range = tx39_flush_cache_range; |
410 | flush_cache_page = tx39_flush_cache_page; | 410 | flush_cache_page = tx39_flush_cache_page; |
411 | flush_icache_page = tx39_flush_icache_page; | 411 | __flush_icache_page = tx39_flush_icache_page; |
412 | flush_icache_range = tx39_flush_icache_range; | 412 | flush_icache_range = tx39_flush_icache_range; |
413 | 413 | ||
414 | flush_cache_sigtramp = tx39_flush_cache_sigtramp; | 414 | flush_cache_sigtramp = tx39_flush_cache_sigtramp; |
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index ddd3a2de1d73..40c8b0235183 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c | |||
@@ -25,7 +25,7 @@ void (*flush_cache_range)(struct vm_area_struct *vma, unsigned long start, | |||
25 | void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, | 25 | void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, |
26 | unsigned long pfn); | 26 | unsigned long pfn); |
27 | void (*flush_icache_range)(unsigned long start, unsigned long end); | 27 | void (*flush_icache_range)(unsigned long start, unsigned long end); |
28 | void (*flush_icache_page)(struct vm_area_struct *vma, struct page *page); | 28 | void (*__flush_icache_page)(struct vm_area_struct *vma, struct page *page); |
29 | 29 | ||
30 | /* MIPS specific cache operations */ | 30 | /* MIPS specific cache operations */ |
31 | void (*flush_cache_sigtramp)(unsigned long addr); | 31 | void (*flush_cache_sigtramp)(unsigned long addr); |
@@ -70,6 +70,8 @@ void __flush_dcache_page(struct page *page) | |||
70 | struct address_space *mapping = page_mapping(page); | 70 | struct address_space *mapping = page_mapping(page); |
71 | unsigned long addr; | 71 | unsigned long addr; |
72 | 72 | ||
73 | if (PageHighMem(page)) | ||
74 | return; | ||
73 | if (mapping && !mapping_mapped(mapping)) { | 75 | if (mapping && !mapping_mapped(mapping)) { |
74 | SetPageDcacheDirty(page); | 76 | SetPageDcacheDirty(page); |
75 | return; | 77 | return; |
@@ -91,16 +93,16 @@ void __update_cache(struct vm_area_struct *vma, unsigned long address, | |||
91 | { | 93 | { |
92 | struct page *page; | 94 | struct page *page; |
93 | unsigned long pfn, addr; | 95 | unsigned long pfn, addr; |
96 | int exec = (vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc; | ||
94 | 97 | ||
95 | pfn = pte_pfn(pte); | 98 | pfn = pte_pfn(pte); |
96 | if (pfn_valid(pfn) && (page = pfn_to_page(pfn), page_mapping(page)) && | 99 | if (unlikely(!pfn_valid(pfn))) |
97 | Page_dcache_dirty(page)) { | 100 | return; |
98 | if (pages_do_alias((unsigned long)page_address(page), | 101 | page = pfn_to_page(pfn); |
99 | address & PAGE_MASK)) { | 102 | if (page_mapping(page) && Page_dcache_dirty(page)) { |
100 | addr = (unsigned long) page_address(page); | 103 | addr = (unsigned long) page_address(page); |
104 | if (exec || pages_do_alias(addr, address & PAGE_MASK)) | ||
101 | flush_data_cache_page(addr); | 105 | flush_data_cache_page(addr); |
102 | } | ||
103 | |||
104 | ClearPageDcacheDirty(page); | 106 | ClearPageDcacheDirty(page); |
105 | } | 107 | } |
106 | } | 108 | } |
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c index e3a617224868..a4f8c45c4e8e 100644 --- a/arch/mips/mm/fault.c +++ b/arch/mips/mm/fault.c | |||
@@ -89,7 +89,7 @@ good_area: | |||
89 | if (!(vma->vm_flags & VM_WRITE)) | 89 | if (!(vma->vm_flags & VM_WRITE)) |
90 | goto bad_area; | 90 | goto bad_area; |
91 | } else { | 91 | } else { |
92 | if (!(vma->vm_flags & (VM_READ | VM_EXEC))) | 92 | if (!(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC))) |
93 | goto bad_area; | 93 | goto bad_area; |
94 | } | 94 | } |
95 | 95 | ||
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index c52497bb102a..5b06349af2d5 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c | |||
@@ -163,10 +163,10 @@ static int __init page_is_ram(unsigned long pagenr) | |||
163 | 163 | ||
164 | void __init paging_init(void) | 164 | void __init paging_init(void) |
165 | { | 165 | { |
166 | unsigned long zones_size[] = { [0 ... MAX_NR_ZONES - 1] = 0 }; | 166 | unsigned long zones_size[] = { 0, }; |
167 | unsigned long max_dma, high, low; | 167 | unsigned long max_dma, high, low; |
168 | #ifndef CONFIG_FLATMEM | 168 | #ifndef CONFIG_FLATMEM |
169 | unsigned long zholes_size[] = { [0 ... MAX_NR_ZONES - 1] = 0 }; | 169 | unsigned long zholes_size[] = { 0, }; |
170 | unsigned long i, j, pfn; | 170 | unsigned long i, j, pfn; |
171 | #endif | 171 | #endif |
172 | 172 | ||
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index 2cde1b772443..2e0e21ef433e 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c | |||
@@ -26,11 +26,6 @@ extern void build_tlb_refill_handler(void); | |||
26 | */ | 26 | */ |
27 | #define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1))) | 27 | #define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1))) |
28 | 28 | ||
29 | /* CP0 hazard avoidance. */ | ||
30 | #define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ | ||
31 | "nop; nop; nop; nop; nop; nop;\n\t" \ | ||
32 | ".set reorder\n\t") | ||
33 | |||
34 | /* Atomicity and interruptability */ | 29 | /* Atomicity and interruptability */ |
35 | #ifdef CONFIG_MIPS_MT_SMTC | 30 | #ifdef CONFIG_MIPS_MT_SMTC |
36 | 31 | ||
@@ -126,7 +121,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | |||
126 | start += (PAGE_SIZE << 1); | 121 | start += (PAGE_SIZE << 1); |
127 | mtc0_tlbw_hazard(); | 122 | mtc0_tlbw_hazard(); |
128 | tlb_probe(); | 123 | tlb_probe(); |
129 | BARRIER; | 124 | tlb_probe_hazard(); |
130 | idx = read_c0_index(); | 125 | idx = read_c0_index(); |
131 | write_c0_entrylo0(0); | 126 | write_c0_entrylo0(0); |
132 | write_c0_entrylo1(0); | 127 | write_c0_entrylo1(0); |
@@ -168,7 +163,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) | |||
168 | start += (PAGE_SIZE << 1); | 163 | start += (PAGE_SIZE << 1); |
169 | mtc0_tlbw_hazard(); | 164 | mtc0_tlbw_hazard(); |
170 | tlb_probe(); | 165 | tlb_probe(); |
171 | BARRIER; | 166 | tlb_probe_hazard(); |
172 | idx = read_c0_index(); | 167 | idx = read_c0_index(); |
173 | write_c0_entrylo0(0); | 168 | write_c0_entrylo0(0); |
174 | write_c0_entrylo1(0); | 169 | write_c0_entrylo1(0); |
@@ -202,7 +197,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) | |||
202 | write_c0_entryhi(page | newpid); | 197 | write_c0_entryhi(page | newpid); |
203 | mtc0_tlbw_hazard(); | 198 | mtc0_tlbw_hazard(); |
204 | tlb_probe(); | 199 | tlb_probe(); |
205 | BARRIER; | 200 | tlb_probe_hazard(); |
206 | idx = read_c0_index(); | 201 | idx = read_c0_index(); |
207 | write_c0_entrylo0(0); | 202 | write_c0_entrylo0(0); |
208 | write_c0_entrylo1(0); | 203 | write_c0_entrylo1(0); |
@@ -235,7 +230,7 @@ void local_flush_tlb_one(unsigned long page) | |||
235 | write_c0_entryhi(page); | 230 | write_c0_entryhi(page); |
236 | mtc0_tlbw_hazard(); | 231 | mtc0_tlbw_hazard(); |
237 | tlb_probe(); | 232 | tlb_probe(); |
238 | BARRIER; | 233 | tlb_probe_hazard(); |
239 | idx = read_c0_index(); | 234 | idx = read_c0_index(); |
240 | write_c0_entrylo0(0); | 235 | write_c0_entrylo0(0); |
241 | write_c0_entrylo1(0); | 236 | write_c0_entrylo1(0); |
@@ -279,7 +274,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) | |||
279 | pgdp = pgd_offset(vma->vm_mm, address); | 274 | pgdp = pgd_offset(vma->vm_mm, address); |
280 | mtc0_tlbw_hazard(); | 275 | mtc0_tlbw_hazard(); |
281 | tlb_probe(); | 276 | tlb_probe(); |
282 | BARRIER; | 277 | tlb_probe_hazard(); |
283 | pudp = pud_offset(pgdp, address); | 278 | pudp = pud_offset(pgdp, address); |
284 | pmdp = pmd_offset(pudp, address); | 279 | pmdp = pmd_offset(pudp, address); |
285 | idx = read_c0_index(); | 280 | idx = read_c0_index(); |
@@ -320,7 +315,7 @@ static void r4k_update_mmu_cache_hwbug(struct vm_area_struct * vma, | |||
320 | pgdp = pgd_offset(vma->vm_mm, address); | 315 | pgdp = pgd_offset(vma->vm_mm, address); |
321 | mtc0_tlbw_hazard(); | 316 | mtc0_tlbw_hazard(); |
322 | tlb_probe(); | 317 | tlb_probe(); |
323 | BARRIER; | 318 | tlb_probe_hazard(); |
324 | pmdp = pmd_offset(pgdp, address); | 319 | pmdp = pmd_offset(pgdp, address); |
325 | idx = read_c0_index(); | 320 | idx = read_c0_index(); |
326 | ptep = pte_offset_map(pmdp, address); | 321 | ptep = pte_offset_map(pmdp, address); |
@@ -351,7 +346,7 @@ void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, | |||
351 | wired = read_c0_wired(); | 346 | wired = read_c0_wired(); |
352 | write_c0_wired(wired + 1); | 347 | write_c0_wired(wired + 1); |
353 | write_c0_index(wired); | 348 | write_c0_index(wired); |
354 | BARRIER; | 349 | tlbw_use_hazard(); /* What is the hazard here? */ |
355 | write_c0_pagemask(pagemask); | 350 | write_c0_pagemask(pagemask); |
356 | write_c0_entryhi(entryhi); | 351 | write_c0_entryhi(entryhi); |
357 | write_c0_entrylo0(entrylo0); | 352 | write_c0_entrylo0(entrylo0); |
@@ -361,7 +356,7 @@ void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, | |||
361 | tlbw_use_hazard(); | 356 | tlbw_use_hazard(); |
362 | 357 | ||
363 | write_c0_entryhi(old_ctx); | 358 | write_c0_entryhi(old_ctx); |
364 | BARRIER; | 359 | tlbw_use_hazard(); /* What is the hazard here? */ |
365 | write_c0_pagemask(old_pagemask); | 360 | write_c0_pagemask(old_pagemask); |
366 | local_flush_tlb_all(); | 361 | local_flush_tlb_all(); |
367 | EXIT_CRITICAL(flags); | 362 | EXIT_CRITICAL(flags); |