diff options
Diffstat (limited to 'arch/sh/mm/cache-sh4.c')
-rw-r--r-- | arch/sh/mm/cache-sh4.c | 81 |
1 files changed, 48 insertions, 33 deletions
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c index 86486326ef1..226b190c5b9 100644 --- a/arch/sh/mm/cache-sh4.c +++ b/arch/sh/mm/cache-sh4.c @@ -2,7 +2,7 @@ * arch/sh/mm/cache-sh4.c * * Copyright (C) 1999, 2000, 2002 Niibe Yutaka - * Copyright (C) 2001 - 2006 Paul Mundt + * Copyright (C) 2001 - 2007 Paul Mundt * Copyright (C) 2003 Richard Curnow * * 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) = static void compute_alias(struct cache_info *c) { c->alias_mask = ((c->sets - 1) << c->entry_shift) & ~(PAGE_SIZE - 1); - c->n_aliases = (c->alias_mask >> PAGE_SHIFT) + 1; + c->n_aliases = c->alias_mask ? (c->alias_mask >> PAGE_SHIFT) + 1 : 0; } static void __init emit_cache_params(void) @@ -54,21 +54,35 @@ static void __init emit_cache_params(void) ctrl_inl(CCN_CVR), ctrl_inl(CCN_PRR)); printk("I-cache : n_ways=%d n_sets=%d way_incr=%d\n", - current_cpu_data.icache.ways, - current_cpu_data.icache.sets, - current_cpu_data.icache.way_incr); + boot_cpu_data.icache.ways, + boot_cpu_data.icache.sets, + boot_cpu_data.icache.way_incr); printk("I-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n", - current_cpu_data.icache.entry_mask, - current_cpu_data.icache.alias_mask, - current_cpu_data.icache.n_aliases); + boot_cpu_data.icache.entry_mask, + boot_cpu_data.icache.alias_mask, + boot_cpu_data.icache.n_aliases); printk("D-cache : n_ways=%d n_sets=%d way_incr=%d\n", - current_cpu_data.dcache.ways, - current_cpu_data.dcache.sets, - current_cpu_data.dcache.way_incr); + boot_cpu_data.dcache.ways, + boot_cpu_data.dcache.sets, + boot_cpu_data.dcache.way_incr); printk("D-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n", - current_cpu_data.dcache.entry_mask, - current_cpu_data.dcache.alias_mask, - current_cpu_data.dcache.n_aliases); + boot_cpu_data.dcache.entry_mask, + boot_cpu_data.dcache.alias_mask, + boot_cpu_data.dcache.n_aliases); + + /* + * Emit Secondary Cache parameters if the CPU has a probed L2. + */ + if (boot_cpu_data.flags & CPU_HAS_L2_CACHE) { + printk("S-cache : n_ways=%d n_sets=%d way_incr=%d\n", + boot_cpu_data.scache.ways, + boot_cpu_data.scache.sets, + boot_cpu_data.scache.way_incr); + printk("S-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n", + boot_cpu_data.scache.entry_mask, + boot_cpu_data.scache.alias_mask, + boot_cpu_data.scache.n_aliases); + } if (!__flush_dcache_segment_fn) panic("unknown number of cache ways\n"); @@ -79,10 +93,11 @@ static void __init emit_cache_params(void) */ void __init p3_cache_init(void) { - compute_alias(¤t_cpu_data.icache); - compute_alias(¤t_cpu_data.dcache); + compute_alias(&boot_cpu_data.icache); + compute_alias(&boot_cpu_data.dcache); + compute_alias(&boot_cpu_data.scache); - switch (current_cpu_data.dcache.ways) { + switch (boot_cpu_data.dcache.ways) { case 1: __flush_dcache_segment_fn = __flush_dcache_segment_1way; break; @@ -187,13 +202,13 @@ void flush_cache_sigtramp(unsigned long addr) : "m" (__m(v))); index = CACHE_IC_ADDRESS_ARRAY | - (v & current_cpu_data.icache.entry_mask); + (v & boot_cpu_data.icache.entry_mask); local_irq_save(flags); jump_to_P2(); - for (i = 0; i < current_cpu_data.icache.ways; - i++, index += current_cpu_data.icache.way_incr) + for (i = 0; i < boot_cpu_data.icache.ways; + i++, index += boot_cpu_data.icache.way_incr) ctrl_outl(0, index); /* Clear out Valid-bit */ back_to_P1(); @@ -210,7 +225,7 @@ static inline void flush_cache_4096(unsigned long start, * All types of SH-4 require PC to be in P2 to operate on the I-cache. * Some types of SH-4 require PC to be in P2 to operate on the D-cache. */ - if ((current_cpu_data.flags & CPU_HAS_P2_FLUSH_BUG) || + if ((boot_cpu_data.flags & CPU_HAS_P2_FLUSH_BUG) || (start < CACHE_OC_ADDRESS_ARRAY)) exec_offset = 0x20000000; @@ -232,7 +247,7 @@ void flush_dcache_page(struct page *page) int i, n; /* Loop all the D-cache */ - n = current_cpu_data.dcache.n_aliases; + n = boot_cpu_data.dcache.n_aliases; for (i = 0; i < n; i++, addr += 4096) flush_cache_4096(addr, phys); } @@ -264,7 +279,7 @@ static inline void flush_icache_all(void) void flush_dcache_all(void) { - (*__flush_dcache_segment_fn)(0UL, current_cpu_data.dcache.way_size); + (*__flush_dcache_segment_fn)(0UL, boot_cpu_data.dcache.way_size); wmb(); } @@ -278,8 +293,8 @@ static void __flush_cache_mm(struct mm_struct *mm, unsigned long start, unsigned long end) { unsigned long d = 0, p = start & PAGE_MASK; - unsigned long alias_mask = current_cpu_data.dcache.alias_mask; - unsigned long n_aliases = current_cpu_data.dcache.n_aliases; + unsigned long alias_mask = boot_cpu_data.dcache.alias_mask; + unsigned long n_aliases = boot_cpu_data.dcache.n_aliases; unsigned long select_bit; unsigned long all_aliases_mask; unsigned long addr_offset; @@ -366,7 +381,7 @@ void flush_cache_mm(struct mm_struct *mm) * If cache is only 4k-per-way, there are never any 'aliases'. Since * the cache is physically tagged, the data can just be left in there. */ - if (current_cpu_data.dcache.n_aliases == 0) + if (boot_cpu_data.dcache.n_aliases == 0) return; /* @@ -403,7 +418,7 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long address, unsigned long phys = pfn << PAGE_SHIFT; unsigned int alias_mask; - alias_mask = current_cpu_data.dcache.alias_mask; + alias_mask = boot_cpu_data.dcache.alias_mask; /* We only need to flush D-cache when we have alias */ if ((address^phys) & alias_mask) { @@ -417,7 +432,7 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long address, phys); } - alias_mask = current_cpu_data.icache.alias_mask; + alias_mask = boot_cpu_data.icache.alias_mask; if (vma->vm_flags & VM_EXEC) { /* * 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, * If cache is only 4k-per-way, there are never any 'aliases'. Since * the cache is physically tagged, the data can just be left in there. */ - if (current_cpu_data.dcache.n_aliases == 0) + if (boot_cpu_data.dcache.n_aliases == 0) return; /* @@ -510,7 +525,7 @@ static void __flush_cache_4096(unsigned long addr, unsigned long phys, unsigned long a, ea, p; unsigned long temp_pc; - dcache = ¤t_cpu_data.dcache; + dcache = &boot_cpu_data.dcache; /* Write this way for better assembly. */ way_count = dcache->ways; way_incr = dcache->way_incr; @@ -585,7 +600,7 @@ static void __flush_dcache_segment_1way(unsigned long start, base_addr = ((base_addr >> 16) << 16); base_addr |= start; - dcache = ¤t_cpu_data.dcache; + dcache = &boot_cpu_data.dcache; linesz = dcache->linesz; way_incr = dcache->way_incr; way_size = dcache->way_size; @@ -627,7 +642,7 @@ static void __flush_dcache_segment_2way(unsigned long start, base_addr = ((base_addr >> 16) << 16); base_addr |= start; - dcache = ¤t_cpu_data.dcache; + dcache = &boot_cpu_data.dcache; linesz = dcache->linesz; way_incr = dcache->way_incr; way_size = dcache->way_size; @@ -686,7 +701,7 @@ static void __flush_dcache_segment_4way(unsigned long start, base_addr = ((base_addr >> 16) << 16); base_addr |= start; - dcache = ¤t_cpu_data.dcache; + dcache = &boot_cpu_data.dcache; linesz = dcache->linesz; way_incr = dcache->way_incr; way_size = dcache->way_size; |