aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/mm/cache-sh4.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/mm/cache-sh4.c')
-rw-r--r--arch/sh/mm/cache-sh4.c81
1 files changed, 48 insertions, 33 deletions
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c
index 86486326ef1d..226b190c5b9c 100644
--- a/arch/sh/mm/cache-sh4.c
+++ b/arch/sh/mm/cache-sh4.c
@@ -2,7 +2,7 @@
2 * arch/sh/mm/cache-sh4.c 2 * arch/sh/mm/cache-sh4.c
3 * 3 *
4 * Copyright (C) 1999, 2000, 2002 Niibe Yutaka 4 * Copyright (C) 1999, 2000, 2002 Niibe Yutaka
5 * Copyright (C) 2001 - 2006 Paul Mundt 5 * Copyright (C) 2001 - 2007 Paul Mundt
6 * Copyright (C) 2003 Richard Curnow 6 * Copyright (C) 2003 Richard Curnow
7 * 7 *
8 * This file is subject to the terms and conditions of the GNU General Public 8 * This file is subject to the terms and conditions of the GNU General Public
@@ -44,7 +44,7 @@ static void (*__flush_dcache_segment_fn)(unsigned long, unsigned long) =
44static void compute_alias(struct cache_info *c) 44static void compute_alias(struct cache_info *c)
45{ 45{
46 c->alias_mask = ((c->sets - 1) << c->entry_shift) & ~(PAGE_SIZE - 1); 46 c->alias_mask = ((c->sets - 1) << c->entry_shift) & ~(PAGE_SIZE - 1);
47 c->n_aliases = (c->alias_mask >> PAGE_SHIFT) + 1; 47 c->n_aliases = c->alias_mask ? (c->alias_mask >> PAGE_SHIFT) + 1 : 0;
48} 48}
49 49
50static void __init emit_cache_params(void) 50static void __init emit_cache_params(void)
@@ -54,21 +54,35 @@ static void __init emit_cache_params(void)
54 ctrl_inl(CCN_CVR), 54 ctrl_inl(CCN_CVR),
55 ctrl_inl(CCN_PRR)); 55 ctrl_inl(CCN_PRR));
56 printk("I-cache : n_ways=%d n_sets=%d way_incr=%d\n", 56 printk("I-cache : n_ways=%d n_sets=%d way_incr=%d\n",
57 current_cpu_data.icache.ways, 57 boot_cpu_data.icache.ways,
58 current_cpu_data.icache.sets, 58 boot_cpu_data.icache.sets,
59 current_cpu_data.icache.way_incr); 59 boot_cpu_data.icache.way_incr);
60 printk("I-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n", 60 printk("I-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n",
61 current_cpu_data.icache.entry_mask, 61 boot_cpu_data.icache.entry_mask,
62 current_cpu_data.icache.alias_mask, 62 boot_cpu_data.icache.alias_mask,
63 current_cpu_data.icache.n_aliases); 63 boot_cpu_data.icache.n_aliases);
64 printk("D-cache : n_ways=%d n_sets=%d way_incr=%d\n", 64 printk("D-cache : n_ways=%d n_sets=%d way_incr=%d\n",
65 current_cpu_data.dcache.ways, 65 boot_cpu_data.dcache.ways,
66 current_cpu_data.dcache.sets, 66 boot_cpu_data.dcache.sets,
67 current_cpu_data.dcache.way_incr); 67 boot_cpu_data.dcache.way_incr);
68 printk("D-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n", 68 printk("D-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n",
69 current_cpu_data.dcache.entry_mask, 69 boot_cpu_data.dcache.entry_mask,
70 current_cpu_data.dcache.alias_mask, 70 boot_cpu_data.dcache.alias_mask,
71 current_cpu_data.dcache.n_aliases); 71 boot_cpu_data.dcache.n_aliases);
72
73 /*
74 * Emit Secondary Cache parameters if the CPU has a probed L2.
75 */
76 if (boot_cpu_data.flags & CPU_HAS_L2_CACHE) {
77 printk("S-cache : n_ways=%d n_sets=%d way_incr=%d\n",
78 boot_cpu_data.scache.ways,
79 boot_cpu_data.scache.sets,
80 boot_cpu_data.scache.way_incr);
81 printk("S-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n",
82 boot_cpu_data.scache.entry_mask,
83 boot_cpu_data.scache.alias_mask,
84 boot_cpu_data.scache.n_aliases);
85 }
72 86
73 if (!__flush_dcache_segment_fn) 87 if (!__flush_dcache_segment_fn)
74 panic("unknown number of cache ways\n"); 88 panic("unknown number of cache ways\n");
@@ -79,10 +93,11 @@ static void __init emit_cache_params(void)
79 */ 93 */
80void __init p3_cache_init(void) 94void __init p3_cache_init(void)
81{ 95{
82 compute_alias(&current_cpu_data.icache); 96 compute_alias(&boot_cpu_data.icache);
83 compute_alias(&current_cpu_data.dcache); 97 compute_alias(&boot_cpu_data.dcache);
98 compute_alias(&boot_cpu_data.scache);
84 99
85 switch (current_cpu_data.dcache.ways) { 100 switch (boot_cpu_data.dcache.ways) {
86 case 1: 101 case 1:
87 __flush_dcache_segment_fn = __flush_dcache_segment_1way; 102 __flush_dcache_segment_fn = __flush_dcache_segment_1way;
88 break; 103 break;
@@ -187,13 +202,13 @@ void flush_cache_sigtramp(unsigned long addr)
187 : "m" (__m(v))); 202 : "m" (__m(v)));
188 203
189 index = CACHE_IC_ADDRESS_ARRAY | 204 index = CACHE_IC_ADDRESS_ARRAY |
190 (v & current_cpu_data.icache.entry_mask); 205 (v & boot_cpu_data.icache.entry_mask);
191 206
192 local_irq_save(flags); 207 local_irq_save(flags);
193 jump_to_P2(); 208 jump_to_P2();
194 209
195 for (i = 0; i < current_cpu_data.icache.ways; 210 for (i = 0; i < boot_cpu_data.icache.ways;
196 i++, index += current_cpu_data.icache.way_incr) 211 i++, index += boot_cpu_data.icache.way_incr)
197 ctrl_outl(0, index); /* Clear out Valid-bit */ 212 ctrl_outl(0, index); /* Clear out Valid-bit */
198 213
199 back_to_P1(); 214 back_to_P1();
@@ -210,7 +225,7 @@ static inline void flush_cache_4096(unsigned long start,
210 * All types of SH-4 require PC to be in P2 to operate on the I-cache. 225 * All types of SH-4 require PC to be in P2 to operate on the I-cache.
211 * Some types of SH-4 require PC to be in P2 to operate on the D-cache. 226 * Some types of SH-4 require PC to be in P2 to operate on the D-cache.
212 */ 227 */
213 if ((current_cpu_data.flags & CPU_HAS_P2_FLUSH_BUG) || 228 if ((boot_cpu_data.flags & CPU_HAS_P2_FLUSH_BUG) ||
214 (start < CACHE_OC_ADDRESS_ARRAY)) 229 (start < CACHE_OC_ADDRESS_ARRAY))
215 exec_offset = 0x20000000; 230 exec_offset = 0x20000000;
216 231
@@ -232,7 +247,7 @@ void flush_dcache_page(struct page *page)
232 int i, n; 247 int i, n;
233 248
234 /* Loop all the D-cache */ 249 /* Loop all the D-cache */
235 n = current_cpu_data.dcache.n_aliases; 250 n = boot_cpu_data.dcache.n_aliases;
236 for (i = 0; i < n; i++, addr += 4096) 251 for (i = 0; i < n; i++, addr += 4096)
237 flush_cache_4096(addr, phys); 252 flush_cache_4096(addr, phys);
238 } 253 }
@@ -264,7 +279,7 @@ static inline void flush_icache_all(void)
264 279
265void flush_dcache_all(void) 280void flush_dcache_all(void)
266{ 281{
267 (*__flush_dcache_segment_fn)(0UL, current_cpu_data.dcache.way_size); 282 (*__flush_dcache_segment_fn)(0UL, boot_cpu_data.dcache.way_size);
268 wmb(); 283 wmb();
269} 284}
270 285
@@ -278,8 +293,8 @@ static void __flush_cache_mm(struct mm_struct *mm, unsigned long start,
278 unsigned long end) 293 unsigned long end)
279{ 294{
280 unsigned long d = 0, p = start & PAGE_MASK; 295 unsigned long d = 0, p = start & PAGE_MASK;
281 unsigned long alias_mask = current_cpu_data.dcache.alias_mask; 296 unsigned long alias_mask = boot_cpu_data.dcache.alias_mask;
282 unsigned long n_aliases = current_cpu_data.dcache.n_aliases; 297 unsigned long n_aliases = boot_cpu_data.dcache.n_aliases;
283 unsigned long select_bit; 298 unsigned long select_bit;
284 unsigned long all_aliases_mask; 299 unsigned long all_aliases_mask;
285 unsigned long addr_offset; 300 unsigned long addr_offset;
@@ -366,7 +381,7 @@ void flush_cache_mm(struct mm_struct *mm)
366 * If cache is only 4k-per-way, there are never any 'aliases'. Since 381 * If cache is only 4k-per-way, there are never any 'aliases'. Since
367 * the cache is physically tagged, the data can just be left in there. 382 * the cache is physically tagged, the data can just be left in there.
368 */ 383 */
369 if (current_cpu_data.dcache.n_aliases == 0) 384 if (boot_cpu_data.dcache.n_aliases == 0)
370 return; 385 return;
371 386
372 /* 387 /*
@@ -403,7 +418,7 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long address,
403 unsigned long phys = pfn << PAGE_SHIFT; 418 unsigned long phys = pfn << PAGE_SHIFT;
404 unsigned int alias_mask; 419 unsigned int alias_mask;
405 420
406 alias_mask = current_cpu_data.dcache.alias_mask; 421 alias_mask = boot_cpu_data.dcache.alias_mask;
407 422
408 /* We only need to flush D-cache when we have alias */ 423 /* We only need to flush D-cache when we have alias */
409 if ((address^phys) & alias_mask) { 424 if ((address^phys) & alias_mask) {
@@ -417,7 +432,7 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long address,
417 phys); 432 phys);
418 } 433 }
419 434
420 alias_mask = current_cpu_data.icache.alias_mask; 435 alias_mask = boot_cpu_data.icache.alias_mask;
421 if (vma->vm_flags & VM_EXEC) { 436 if (vma->vm_flags & VM_EXEC) {
422 /* 437 /*
423 * Evict entries from the portion of the cache from which code 438 * Evict entries from the portion of the cache from which code
@@ -449,7 +464,7 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
449 * If cache is only 4k-per-way, there are never any 'aliases'. Since 464 * If cache is only 4k-per-way, there are never any 'aliases'. Since
450 * the cache is physically tagged, the data can just be left in there. 465 * the cache is physically tagged, the data can just be left in there.
451 */ 466 */
452 if (current_cpu_data.dcache.n_aliases == 0) 467 if (boot_cpu_data.dcache.n_aliases == 0)
453 return; 468 return;
454 469
455 /* 470 /*
@@ -510,7 +525,7 @@ static void __flush_cache_4096(unsigned long addr, unsigned long phys,
510 unsigned long a, ea, p; 525 unsigned long a, ea, p;
511 unsigned long temp_pc; 526 unsigned long temp_pc;
512 527
513 dcache = &current_cpu_data.dcache; 528 dcache = &boot_cpu_data.dcache;
514 /* Write this way for better assembly. */ 529 /* Write this way for better assembly. */
515 way_count = dcache->ways; 530 way_count = dcache->ways;
516 way_incr = dcache->way_incr; 531 way_incr = dcache->way_incr;
@@ -585,7 +600,7 @@ static void __flush_dcache_segment_1way(unsigned long start,
585 base_addr = ((base_addr >> 16) << 16); 600 base_addr = ((base_addr >> 16) << 16);
586 base_addr |= start; 601 base_addr |= start;
587 602
588 dcache = &current_cpu_data.dcache; 603 dcache = &boot_cpu_data.dcache;
589 linesz = dcache->linesz; 604 linesz = dcache->linesz;
590 way_incr = dcache->way_incr; 605 way_incr = dcache->way_incr;
591 way_size = dcache->way_size; 606 way_size = dcache->way_size;
@@ -627,7 +642,7 @@ static void __flush_dcache_segment_2way(unsigned long start,
627 base_addr = ((base_addr >> 16) << 16); 642 base_addr = ((base_addr >> 16) << 16);
628 base_addr |= start; 643 base_addr |= start;
629 644
630 dcache = &current_cpu_data.dcache; 645 dcache = &boot_cpu_data.dcache;
631 linesz = dcache->linesz; 646 linesz = dcache->linesz;
632 way_incr = dcache->way_incr; 647 way_incr = dcache->way_incr;
633 way_size = dcache->way_size; 648 way_size = dcache->way_size;
@@ -686,7 +701,7 @@ static void __flush_dcache_segment_4way(unsigned long start,
686 base_addr = ((base_addr >> 16) << 16); 701 base_addr = ((base_addr >> 16) << 16);
687 base_addr |= start; 702 base_addr |= start;
688 703
689 dcache = &current_cpu_data.dcache; 704 dcache = &boot_cpu_data.dcache;
690 linesz = dcache->linesz; 705 linesz = dcache->linesz;
691 way_incr = dcache->way_incr; 706 way_incr = dcache->way_incr;
692 way_size = dcache->way_size; 707 way_size = dcache->way_size;