b5860535e61f9ad6bd7bcc878ff599401809c0e6
[linux-2.6.git] / arch / sh / mm / cache-sh4.c
1 /*
2  * arch/sh/mm/cache-sh4.c
3  *
4  * Copyright (C) 1999, 2000, 2002  Niibe Yutaka
5  * Copyright (C) 2001 - 2007  Paul Mundt
6  * Copyright (C) 2003  Richard Curnow
7  * Copyright (c) 2007 STMicroelectronics (R&D) Ltd.
8  *
9  * This file is subject to the terms and conditions of the GNU General Public
10  * License.  See the file "COPYING" in the main directory of this archive
11  * for more details.
12  */
13 #include <linux/init.h>
14 #include <linux/mm.h>
15 #include <linux/io.h>
16 #include <linux/mutex.h>
17 #include <linux/fs.h>
18 #include <asm/mmu_context.h>
19 #include <asm/cacheflush.h>
20
21 /*
22  * The maximum number of pages we support up to when doing ranged dcache
23  * flushing. Anything exceeding this will simply flush the dcache in its
24  * entirety.
25  */
26 #define MAX_DCACHE_PAGES        64      /* XXX: Tune for ways */
27 #define MAX_ICACHE_PAGES        32
28
29 static void __flush_dcache_segment_1way(unsigned long start,
30                                         unsigned long extent);
31 static void __flush_dcache_segment_2way(unsigned long start,
32                                         unsigned long extent);
33 static void __flush_dcache_segment_4way(unsigned long start,
34                                         unsigned long extent);
35
36 static void __flush_cache_4096(unsigned long addr, unsigned long phys,
37                                unsigned long exec_offset);
38
39 /*
40  * This is initialised here to ensure that it is not placed in the BSS.  If
41  * that were to happen, note that cache_init gets called before the BSS is
42  * cleared, so this would get nulled out which would be hopeless.
43  */
44 static void (*__flush_dcache_segment_fn)(unsigned long, unsigned long) =
45         (void (*)(unsigned long, unsigned long))0xdeadbeef;
46
47 /*
48  * SH-4 has virtually indexed and physically tagged cache.
49  */
50 void __init sh4_cache_init(void)
51 {
52         printk("PVR=%08x CVR=%08x PRR=%08x\n",
53                 ctrl_inl(CCN_PVR),
54                 ctrl_inl(CCN_CVR),
55                 ctrl_inl(CCN_PRR));
56
57         switch (boot_cpu_data.dcache.ways) {
58         case 1:
59                 __flush_dcache_segment_fn = __flush_dcache_segment_1way;
60                 break;
61         case 2:
62                 __flush_dcache_segment_fn = __flush_dcache_segment_2way;
63                 break;
64         case 4:
65                 __flush_dcache_segment_fn = __flush_dcache_segment_4way;
66                 break;
67         default:
68                 panic("unknown number of cache ways\n");
69                 break;
70         }
71 }
72
73 /*
74  * Write back the range of D-cache, and purge the I-cache.
75  *
76  * Called from kernel/module.c:sys_init_module and routine for a.out format,
77  * signal handler code and kprobes code
78  */
79 void flush_icache_range(unsigned long start, unsigned long end)
80 {
81         int icacheaddr;
82         unsigned long flags, v;
83         int i;
84
85        /* If there are too many pages then just blow the caches */
86         if (((end - start) >> PAGE_SHIFT) >= MAX_ICACHE_PAGES) {
87                 flush_cache_all();
88        } else {
89                /* selectively flush d-cache then invalidate the i-cache */
90                /* this is inefficient, so only use for small ranges */
91                start &= ~(L1_CACHE_BYTES-1);
92                end += L1_CACHE_BYTES-1;
93                end &= ~(L1_CACHE_BYTES-1);
94
95                local_irq_save(flags);
96                jump_to_uncached();
97
98                for (v = start; v < end; v+=L1_CACHE_BYTES) {
99                        asm volatile("ocbwb     %0"
100                                     : /* no output */
101                                     : "m" (__m(v)));
102
103                        icacheaddr = CACHE_IC_ADDRESS_ARRAY | (
104                                        v & cpu_data->icache.entry_mask);
105
106                        for (i = 0; i < cpu_data->icache.ways;
107                                i++, icacheaddr += cpu_data->icache.way_incr)
108                                        /* Clear i-cache line valid-bit */
109                                        ctrl_outl(0, icacheaddr);
110                }
111
112                 back_to_cached();
113                 local_irq_restore(flags);
114         }
115 }
116
117 static inline void flush_cache_4096(unsigned long start,
118                                     unsigned long phys)
119 {
120         unsigned long flags, exec_offset = 0;
121
122         /*
123          * All types of SH-4 require PC to be in P2 to operate on the I-cache.
124          * Some types of SH-4 require PC to be in P2 to operate on the D-cache.
125          */
126         if ((boot_cpu_data.flags & CPU_HAS_P2_FLUSH_BUG) ||
127             (start < CACHE_OC_ADDRESS_ARRAY))
128                 exec_offset = 0x20000000;
129
130         local_irq_save(flags);
131         __flush_cache_4096(start | SH_CACHE_ASSOC,
132                            P1SEGADDR(phys), exec_offset);
133         local_irq_restore(flags);
134 }
135
136 /*
137  * Write back & invalidate the D-cache of the page.
138  * (To avoid "alias" issues)
139  */
140 void flush_dcache_page(struct page *page)
141 {
142         struct address_space *mapping = page_mapping(page);
143
144 #ifndef CONFIG_SMP
145         if (mapping && !mapping_mapped(mapping))
146                 set_bit(PG_dcache_dirty, &page->flags);
147         else
148 #endif
149         {
150                 unsigned long phys = PHYSADDR(page_address(page));
151                 unsigned long addr = CACHE_OC_ADDRESS_ARRAY;
152                 int i, n;
153
154                 /* Loop all the D-cache */
155                 n = boot_cpu_data.dcache.n_aliases;
156                 for (i = 0; i < n; i++, addr += 4096)
157                         flush_cache_4096(addr, phys);
158         }
159
160         wmb();
161 }
162
163 /* TODO: Selective icache invalidation through IC address array.. */
164 static void __uses_jump_to_uncached flush_icache_all(void)
165 {
166         unsigned long flags, ccr;
167
168         local_irq_save(flags);
169         jump_to_uncached();
170
171         /* Flush I-cache */
172         ccr = ctrl_inl(CCR);
173         ccr |= CCR_CACHE_ICI;
174         ctrl_outl(ccr, CCR);
175
176         /*
177          * back_to_cached() will take care of the barrier for us, don't add
178          * another one!
179          */
180
181         back_to_cached();
182         local_irq_restore(flags);
183 }
184
185 static inline void flush_dcache_all(void)
186 {
187         (*__flush_dcache_segment_fn)(0UL, boot_cpu_data.dcache.way_size);
188         wmb();
189 }
190
191 void flush_cache_all(void)
192 {
193         flush_dcache_all();
194         flush_icache_all();
195 }
196
197 static void __flush_cache_mm(struct mm_struct *mm, unsigned long start,
198                              unsigned long end)
199 {
200         unsigned long d = 0, p = start & PAGE_MASK;
201         unsigned long alias_mask = boot_cpu_data.dcache.alias_mask;
202         unsigned long n_aliases = boot_cpu_data.dcache.n_aliases;
203         unsigned long select_bit;
204         unsigned long all_aliases_mask;
205         unsigned long addr_offset;
206         pgd_t *dir;
207         pmd_t *pmd;
208         pud_t *pud;
209         pte_t *pte;
210         int i;
211
212         dir = pgd_offset(mm, p);
213         pud = pud_offset(dir, p);
214         pmd = pmd_offset(pud, p);
215         end = PAGE_ALIGN(end);
216
217         all_aliases_mask = (1 << n_aliases) - 1;
218
219         do {
220                 if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) {
221                         p &= PMD_MASK;
222                         p += PMD_SIZE;
223                         pmd++;
224
225                         continue;
226                 }
227
228                 pte = pte_offset_kernel(pmd, p);
229
230                 do {
231                         unsigned long phys;
232                         pte_t entry = *pte;
233
234                         if (!(pte_val(entry) & _PAGE_PRESENT)) {
235                                 pte++;
236                                 p += PAGE_SIZE;
237                                 continue;
238                         }
239
240                         phys = pte_val(entry) & PTE_PHYS_MASK;
241
242                         if ((p ^ phys) & alias_mask) {
243                                 d |= 1 << ((p & alias_mask) >> PAGE_SHIFT);
244                                 d |= 1 << ((phys & alias_mask) >> PAGE_SHIFT);
245
246                                 if (d == all_aliases_mask)
247                                         goto loop_exit;
248                         }
249
250                         pte++;
251                         p += PAGE_SIZE;
252                 } while (p < end && ((unsigned long)pte & ~PAGE_MASK));
253                 pmd++;
254         } while (p < end);
255
256 loop_exit:
257         addr_offset = 0;
258         select_bit = 1;
259
260         for (i = 0; i < n_aliases; i++) {
261                 if (d & select_bit) {
262                         (*__flush_dcache_segment_fn)(addr_offset, PAGE_SIZE);
263                         wmb();
264                 }
265
266                 select_bit <<= 1;
267                 addr_offset += PAGE_SIZE;
268         }
269 }
270
271 /*
272  * Note : (RPC) since the caches are physically tagged, the only point
273  * of flush_cache_mm for SH-4 is to get rid of aliases from the
274  * D-cache.  The assumption elsewhere, e.g. flush_cache_range, is that
275  * lines can stay resident so long as the virtual address they were
276  * accessed with (hence cache set) is in accord with the physical
277  * address (i.e. tag).  It's no different here.  So I reckon we don't
278  * need to flush the I-cache, since aliases don't matter for that.  We
279  * should try that.
280  *
281  * Caller takes mm->mmap_sem.
282  */
283 void flush_cache_mm(struct mm_struct *mm)
284 {
285         if (cpu_context(smp_processor_id(), mm) == NO_CONTEXT)
286                 return;
287
288         /*
289          * If cache is only 4k-per-way, there are never any 'aliases'.  Since
290          * the cache is physically tagged, the data can just be left in there.
291          */
292         if (boot_cpu_data.dcache.n_aliases == 0)
293                 return;
294
295         /*
296          * Don't bother groveling around the dcache for the VMA ranges
297          * if there are too many PTEs to make it worthwhile.
298          */
299         if (mm->nr_ptes >= MAX_DCACHE_PAGES)
300                 flush_dcache_all();
301         else {
302                 struct vm_area_struct *vma;
303
304                 /*
305                  * In this case there are reasonably sized ranges to flush,
306                  * iterate through the VMA list and take care of any aliases.
307                  */
308                 for (vma = mm->mmap; vma; vma = vma->vm_next)
309                         __flush_cache_mm(mm, vma->vm_start, vma->vm_end);
310         }
311
312         /* Only touch the icache if one of the VMAs has VM_EXEC set. */
313         if (mm->exec_vm)
314                 flush_icache_all();
315 }
316
317 /*
318  * Write back and invalidate I/D-caches for the page.
319  *
320  * ADDR: Virtual Address (U0 address)
321  * PFN: Physical page number
322  */
323 void flush_cache_page(struct vm_area_struct *vma, unsigned long address,
324                       unsigned long pfn)
325 {
326         unsigned long phys = pfn << PAGE_SHIFT;
327         unsigned int alias_mask;
328
329         if (cpu_context(smp_processor_id(), vma->vm_mm) == NO_CONTEXT)
330                 return;
331
332         alias_mask = boot_cpu_data.dcache.alias_mask;
333
334         /* We only need to flush D-cache when we have alias */
335         if ((address^phys) & alias_mask) {
336                 /* Loop 4K of the D-cache */
337                 flush_cache_4096(
338                         CACHE_OC_ADDRESS_ARRAY | (address & alias_mask),
339                         phys);
340                 /* Loop another 4K of the D-cache */
341                 flush_cache_4096(
342                         CACHE_OC_ADDRESS_ARRAY | (phys & alias_mask),
343                         phys);
344         }
345
346         alias_mask = boot_cpu_data.icache.alias_mask;
347         if (vma->vm_flags & VM_EXEC) {
348                 /*
349                  * Evict entries from the portion of the cache from which code
350                  * may have been executed at this address (virtual).  There's
351                  * no need to evict from the portion corresponding to the
352                  * physical address as for the D-cache, because we know the
353                  * kernel has never executed the code through its identity
354                  * translation.
355                  */
356                 flush_cache_4096(
357                         CACHE_IC_ADDRESS_ARRAY | (address & alias_mask),
358                         phys);
359         }
360 }
361
362 /*
363  * Write back and invalidate D-caches.
364  *
365  * START, END: Virtual Address (U0 address)
366  *
367  * NOTE: We need to flush the _physical_ page entry.
368  * Flushing the cache lines for U0 only isn't enough.
369  * We need to flush for P1 too, which may contain aliases.
370  */
371 void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
372                        unsigned long end)
373 {
374         if (cpu_context(smp_processor_id(), vma->vm_mm) == NO_CONTEXT)
375                 return;
376
377         /*
378          * If cache is only 4k-per-way, there are never any 'aliases'.  Since
379          * the cache is physically tagged, the data can just be left in there.
380          */
381         if (boot_cpu_data.dcache.n_aliases == 0)
382                 return;
383
384         /*
385          * Don't bother with the lookup and alias check if we have a
386          * wide range to cover, just blow away the dcache in its
387          * entirety instead. -- PFM.
388          */
389         if (((end - start) >> PAGE_SHIFT) >= MAX_DCACHE_PAGES)
390                 flush_dcache_all();
391         else
392                 __flush_cache_mm(vma->vm_mm, start, end);
393
394         if (vma->vm_flags & VM_EXEC) {
395                 /*
396                  * TODO: Is this required???  Need to look at how I-cache
397                  * coherency is assured when new programs are loaded to see if
398                  * this matters.
399                  */
400                 flush_icache_all();
401         }
402 }
403
404 /**
405  * __flush_cache_4096
406  *
407  * @addr:  address in memory mapped cache array
408  * @phys:  P1 address to flush (has to match tags if addr has 'A' bit
409  *         set i.e. associative write)
410  * @exec_offset: set to 0x20000000 if flush has to be executed from P2
411  *               region else 0x0
412  *
413  * The offset into the cache array implied by 'addr' selects the
414  * 'colour' of the virtual address range that will be flushed.  The
415  * operation (purge/write-back) is selected by the lower 2 bits of
416  * 'phys'.
417  */
418 static void __flush_cache_4096(unsigned long addr, unsigned long phys,
419                                unsigned long exec_offset)
420 {
421         int way_count;
422         unsigned long base_addr = addr;
423         struct cache_info *dcache;
424         unsigned long way_incr;
425         unsigned long a, ea, p;
426         unsigned long temp_pc;
427
428         dcache = &boot_cpu_data.dcache;
429         /* Write this way for better assembly. */
430         way_count = dcache->ways;
431         way_incr = dcache->way_incr;
432
433         /*
434          * Apply exec_offset (i.e. branch to P2 if required.).
435          *
436          * FIXME:
437          *
438          *      If I write "=r" for the (temp_pc), it puts this in r6 hence
439          *      trashing exec_offset before it's been added on - why?  Hence
440          *      "=&r" as a 'workaround'
441          */
442         asm volatile("mov.l 1f, %0\n\t"
443                      "add   %1, %0\n\t"
444                      "jmp   @%0\n\t"
445                      "nop\n\t"
446                      ".balign 4\n\t"
447                      "1:  .long 2f\n\t"
448                      "2:\n" : "=&r" (temp_pc) : "r" (exec_offset));
449
450         /*
451          * We know there will be >=1 iteration, so write as do-while to avoid
452          * pointless nead-of-loop check for 0 iterations.
453          */
454         do {
455                 ea = base_addr + PAGE_SIZE;
456                 a = base_addr;
457                 p = phys;
458
459                 do {
460                         *(volatile unsigned long *)a = p;
461                         /*
462                          * Next line: intentionally not p+32, saves an add, p
463                          * will do since only the cache tag bits need to
464                          * match.
465                          */
466                         *(volatile unsigned long *)(a+32) = p;
467                         a += 64;
468                         p += 64;
469                 } while (a < ea);
470
471                 base_addr += way_incr;
472         } while (--way_count != 0);
473 }
474
475 /*
476  * Break the 1, 2 and 4 way variants of this out into separate functions to
477  * avoid nearly all the overhead of having the conditional stuff in the function
478  * bodies (+ the 1 and 2 way cases avoid saving any registers too).
479  */
480 static void __flush_dcache_segment_1way(unsigned long start,
481                                         unsigned long extent_per_way)
482 {
483         unsigned long orig_sr, sr_with_bl;
484         unsigned long base_addr;
485         unsigned long way_incr, linesz, way_size;
486         struct cache_info *dcache;
487         register unsigned long a0, a0e;
488
489         asm volatile("stc sr, %0" : "=r" (orig_sr));
490         sr_with_bl = orig_sr | (1<<28);
491         base_addr = ((unsigned long)&empty_zero_page[0]);
492
493         /*
494          * The previous code aligned base_addr to 16k, i.e. the way_size of all
495          * existing SH-4 D-caches.  Whilst I don't see a need to have this
496          * aligned to any better than the cache line size (which it will be
497          * anyway by construction), let's align it to at least the way_size of
498          * any existing or conceivable SH-4 D-cache.  -- RPC
499          */
500         base_addr = ((base_addr >> 16) << 16);
501         base_addr |= start;
502
503         dcache = &boot_cpu_data.dcache;
504         linesz = dcache->linesz;
505         way_incr = dcache->way_incr;
506         way_size = dcache->way_size;
507
508         a0 = base_addr;
509         a0e = base_addr + extent_per_way;
510         do {
511                 asm volatile("ldc %0, sr" : : "r" (sr_with_bl));
512                 asm volatile("movca.l r0, @%0\n\t"
513                              "ocbi @%0" : : "r" (a0));
514                 a0 += linesz;
515                 asm volatile("movca.l r0, @%0\n\t"
516                              "ocbi @%0" : : "r" (a0));
517                 a0 += linesz;
518                 asm volatile("movca.l r0, @%0\n\t"
519                              "ocbi @%0" : : "r" (a0));
520                 a0 += linesz;
521                 asm volatile("movca.l r0, @%0\n\t"
522                              "ocbi @%0" : : "r" (a0));
523                 asm volatile("ldc %0, sr" : : "r" (orig_sr));
524                 a0 += linesz;
525         } while (a0 < a0e);
526 }
527
528 static void __flush_dcache_segment_2way(unsigned long start,
529                                         unsigned long extent_per_way)
530 {
531         unsigned long orig_sr, sr_with_bl;
532         unsigned long base_addr;
533         unsigned long way_incr, linesz, way_size;
534         struct cache_info *dcache;
535         register unsigned long a0, a1, a0e;
536
537         asm volatile("stc sr, %0" : "=r" (orig_sr));
538         sr_with_bl = orig_sr | (1<<28);
539         base_addr = ((unsigned long)&empty_zero_page[0]);
540
541         /* See comment under 1-way above */
542         base_addr = ((base_addr >> 16) << 16);
543         base_addr |= start;
544
545         dcache = &boot_cpu_data.dcache;
546         linesz = dcache->linesz;
547         way_incr = dcache->way_incr;
548         way_size = dcache->way_size;
549
550         a0 = base_addr;
551         a1 = a0 + way_incr;
552         a0e = base_addr + extent_per_way;
553         do {
554                 asm volatile("ldc %0, sr" : : "r" (sr_with_bl));
555                 asm volatile("movca.l r0, @%0\n\t"
556                              "movca.l r0, @%1\n\t"
557                              "ocbi @%0\n\t"
558                              "ocbi @%1" : :
559                              "r" (a0), "r" (a1));
560                 a0 += linesz;
561                 a1 += linesz;
562                 asm volatile("movca.l r0, @%0\n\t"
563                              "movca.l r0, @%1\n\t"
564                              "ocbi @%0\n\t"
565                              "ocbi @%1" : :
566                              "r" (a0), "r" (a1));
567                 a0 += linesz;
568                 a1 += linesz;
569                 asm volatile("movca.l r0, @%0\n\t"
570                              "movca.l r0, @%1\n\t"
571                              "ocbi @%0\n\t"
572                              "ocbi @%1" : :
573                              "r" (a0), "r" (a1));
574                 a0 += linesz;
575                 a1 += linesz;
576                 asm volatile("movca.l r0, @%0\n\t"
577                              "movca.l r0, @%1\n\t"
578                              "ocbi @%0\n\t"
579                              "ocbi @%1" : :
580                              "r" (a0), "r" (a1));
581                 asm volatile("ldc %0, sr" : : "r" (orig_sr));
582                 a0 += linesz;
583                 a1 += linesz;
584         } while (a0 < a0e);
585 }
586
587 static void __flush_dcache_segment_4way(unsigned long start,
588                                         unsigned long extent_per_way)
589 {
590         unsigned long orig_sr, sr_with_bl;
591         unsigned long base_addr;
592         unsigned long way_incr, linesz, way_size;
593         struct cache_info *dcache;
594         register unsigned long a0, a1, a2, a3, a0e;
595
596         asm volatile("stc sr, %0" : "=r" (orig_sr));
597         sr_with_bl = orig_sr | (1<<28);
598         base_addr = ((unsigned long)&empty_zero_page[0]);
599
600         /* See comment under 1-way above */
601         base_addr = ((base_addr >> 16) << 16);
602         base_addr |= start;
603
604         dcache = &boot_cpu_data.dcache;
605         linesz = dcache->linesz;
606         way_incr = dcache->way_incr;
607         way_size = dcache->way_size;
608
609         a0 = base_addr;
610         a1 = a0 + way_incr;
611         a2 = a1 + way_incr;
612         a3 = a2 + way_incr;
613         a0e = base_addr + extent_per_way;
614         do {
615                 asm volatile("ldc %0, sr" : : "r" (sr_with_bl));
616                 asm volatile("movca.l r0, @%0\n\t"
617                              "movca.l r0, @%1\n\t"
618                              "movca.l r0, @%2\n\t"
619                              "movca.l r0, @%3\n\t"
620                              "ocbi @%0\n\t"
621                              "ocbi @%1\n\t"
622                              "ocbi @%2\n\t"
623                              "ocbi @%3\n\t" : :
624                              "r" (a0), "r" (a1), "r" (a2), "r" (a3));
625                 a0 += linesz;
626                 a1 += linesz;
627                 a2 += linesz;
628                 a3 += linesz;
629                 asm volatile("movca.l r0, @%0\n\t"
630                              "movca.l r0, @%1\n\t"
631                              "movca.l r0, @%2\n\t"
632                              "movca.l r0, @%3\n\t"
633                              "ocbi @%0\n\t"
634                              "ocbi @%1\n\t"
635                              "ocbi @%2\n\t"
636                              "ocbi @%3\n\t" : :
637                              "r" (a0), "r" (a1), "r" (a2), "r" (a3));
638                 a0 += linesz;
639                 a1 += linesz;
640                 a2 += linesz;
641                 a3 += linesz;
642                 asm volatile("movca.l r0, @%0\n\t"
643                              "movca.l r0, @%1\n\t"
644                              "movca.l r0, @%2\n\t"
645                              "movca.l r0, @%3\n\t"
646                              "ocbi @%0\n\t"
647                              "ocbi @%1\n\t"
648                              "ocbi @%2\n\t"
649                              "ocbi @%3\n\t" : :
650                              "r" (a0), "r" (a1), "r" (a2), "r" (a3));
651                 a0 += linesz;
652                 a1 += linesz;
653                 a2 += linesz;
654                 a3 += linesz;
655                 asm volatile("movca.l r0, @%0\n\t"
656                              "movca.l r0, @%1\n\t"
657                              "movca.l r0, @%2\n\t"
658                              "movca.l r0, @%3\n\t"
659                              "ocbi @%0\n\t"
660                              "ocbi @%1\n\t"
661                              "ocbi @%2\n\t"
662                              "ocbi @%3\n\t" : :
663                              "r" (a0), "r" (a1), "r" (a2), "r" (a3));
664                 asm volatile("ldc %0, sr" : : "r" (orig_sr));
665                 a0 += linesz;
666                 a1 += linesz;
667                 a2 += linesz;
668                 a3 += linesz;
669         } while (a0 < a0e);
670 }