cache-sh4.c (9839B)
1/* 2 * arch/sh/mm/cache-sh4.c 3 * 4 * Copyright (C) 1999, 2000, 2002 Niibe Yutaka 5 * Copyright (C) 2001 - 2009 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 <linux/highmem.h> 19#include <linux/pagemap.h> 20#include <asm/mmu_context.h> 21#include <asm/cache_insns.h> 22#include <asm/cacheflush.h> 23 24/* 25 * The maximum number of pages we support up to when doing ranged dcache 26 * flushing. Anything exceeding this will simply flush the dcache in its 27 * entirety. 28 */ 29#define MAX_ICACHE_PAGES 32 30 31static void __flush_cache_one(unsigned long addr, unsigned long phys, 32 unsigned long exec_offset); 33 34/* 35 * Write back the range of D-cache, and purge the I-cache. 36 * 37 * Called from kernel/module.c:sys_init_module and routine for a.out format, 38 * signal handler code and kprobes code 39 */ 40static void sh4_flush_icache_range(void *args) 41{ 42 struct flusher_data *data = args; 43 unsigned long start, end; 44 unsigned long flags, v; 45 int i; 46 47 start = data->addr1; 48 end = data->addr2; 49 50 /* If there are too many pages then just blow away the caches */ 51 if (((end - start) >> PAGE_SHIFT) >= MAX_ICACHE_PAGES) { 52 local_flush_cache_all(NULL); 53 return; 54 } 55 56 /* 57 * Selectively flush d-cache then invalidate the i-cache. 58 * This is inefficient, so only use this for small ranges. 59 */ 60 start &= ~(L1_CACHE_BYTES-1); 61 end += L1_CACHE_BYTES-1; 62 end &= ~(L1_CACHE_BYTES-1); 63 64 local_irq_save(flags); 65 jump_to_uncached(); 66 67 for (v = start; v < end; v += L1_CACHE_BYTES) { 68 unsigned long icacheaddr; 69 int j, n; 70 71 __ocbwb(v); 72 73 icacheaddr = CACHE_IC_ADDRESS_ARRAY | (v & 74 cpu_data->icache.entry_mask); 75 76 /* Clear i-cache line valid-bit */ 77 n = boot_cpu_data.icache.n_aliases; 78 for (i = 0; i < cpu_data->icache.ways; i++) { 79 for (j = 0; j < n; j++) 80 __raw_writel(0, icacheaddr + (j * PAGE_SIZE)); 81 icacheaddr += cpu_data->icache.way_incr; 82 } 83 } 84 85 back_to_cached(); 86 local_irq_restore(flags); 87} 88 89static inline void flush_cache_one(unsigned long start, unsigned long phys) 90{ 91 unsigned long flags, exec_offset = 0; 92 93 /* 94 * All types of SH-4 require PC to be uncached to operate on the I-cache. 95 * Some types of SH-4 require PC to be uncached to operate on the D-cache. 96 */ 97 if ((boot_cpu_data.flags & CPU_HAS_P2_FLUSH_BUG) || 98 (start < CACHE_OC_ADDRESS_ARRAY)) 99 exec_offset = cached_to_uncached; 100 101 local_irq_save(flags); 102 __flush_cache_one(start, phys, exec_offset); 103 local_irq_restore(flags); 104} 105 106/* 107 * Write back & invalidate the D-cache of the page. 108 * (To avoid "alias" issues) 109 */ 110static void sh4_flush_dcache_page(void *arg) 111{ 112 struct page *page = arg; 113 unsigned long addr = (unsigned long)page_address(page); 114#ifndef CONFIG_SMP 115 struct address_space *mapping = page_mapping_file(page); 116 117 if (mapping && !mapping_mapped(mapping)) 118 clear_bit(PG_dcache_clean, &page->flags); 119 else 120#endif 121 flush_cache_one(CACHE_OC_ADDRESS_ARRAY | 122 (addr & shm_align_mask), page_to_phys(page)); 123 124 wmb(); 125} 126 127/* TODO: Selective icache invalidation through IC address array.. */ 128static void flush_icache_all(void) 129{ 130 unsigned long flags, ccr; 131 132 local_irq_save(flags); 133 jump_to_uncached(); 134 135 /* Flush I-cache */ 136 ccr = __raw_readl(SH_CCR); 137 ccr |= CCR_CACHE_ICI; 138 __raw_writel(ccr, SH_CCR); 139 140 /* 141 * back_to_cached() will take care of the barrier for us, don't add 142 * another one! 143 */ 144 145 back_to_cached(); 146 local_irq_restore(flags); 147} 148 149static void flush_dcache_all(void) 150{ 151 unsigned long addr, end_addr, entry_offset; 152 153 end_addr = CACHE_OC_ADDRESS_ARRAY + 154 (current_cpu_data.dcache.sets << 155 current_cpu_data.dcache.entry_shift) * 156 current_cpu_data.dcache.ways; 157 158 entry_offset = 1 << current_cpu_data.dcache.entry_shift; 159 160 for (addr = CACHE_OC_ADDRESS_ARRAY; addr < end_addr; ) { 161 __raw_writel(0, addr); addr += entry_offset; 162 __raw_writel(0, addr); addr += entry_offset; 163 __raw_writel(0, addr); addr += entry_offset; 164 __raw_writel(0, addr); addr += entry_offset; 165 __raw_writel(0, addr); addr += entry_offset; 166 __raw_writel(0, addr); addr += entry_offset; 167 __raw_writel(0, addr); addr += entry_offset; 168 __raw_writel(0, addr); addr += entry_offset; 169 } 170} 171 172static void sh4_flush_cache_all(void *unused) 173{ 174 flush_dcache_all(); 175 flush_icache_all(); 176} 177 178/* 179 * Note : (RPC) since the caches are physically tagged, the only point 180 * of flush_cache_mm for SH-4 is to get rid of aliases from the 181 * D-cache. The assumption elsewhere, e.g. flush_cache_range, is that 182 * lines can stay resident so long as the virtual address they were 183 * accessed with (hence cache set) is in accord with the physical 184 * address (i.e. tag). It's no different here. 185 * 186 * Caller takes mm->mmap_lock. 187 */ 188static void sh4_flush_cache_mm(void *arg) 189{ 190 struct mm_struct *mm = arg; 191 192 if (cpu_context(smp_processor_id(), mm) == NO_CONTEXT) 193 return; 194 195 flush_dcache_all(); 196} 197 198/* 199 * Write back and invalidate I/D-caches for the page. 200 * 201 * ADDR: Virtual Address (U0 address) 202 * PFN: Physical page number 203 */ 204static void sh4_flush_cache_page(void *args) 205{ 206 struct flusher_data *data = args; 207 struct vm_area_struct *vma; 208 struct page *page; 209 unsigned long address, pfn, phys; 210 int map_coherent = 0; 211 pmd_t *pmd; 212 pte_t *pte; 213 void *vaddr; 214 215 vma = data->vma; 216 address = data->addr1 & PAGE_MASK; 217 pfn = data->addr2; 218 phys = pfn << PAGE_SHIFT; 219 page = pfn_to_page(pfn); 220 221 if (cpu_context(smp_processor_id(), vma->vm_mm) == NO_CONTEXT) 222 return; 223 224 pmd = pmd_off(vma->vm_mm, address); 225 pte = pte_offset_kernel(pmd, address); 226 227 /* If the page isn't present, there is nothing to do here. */ 228 if (!(pte_val(*pte) & _PAGE_PRESENT)) 229 return; 230 231 if ((vma->vm_mm == current->active_mm)) 232 vaddr = NULL; 233 else { 234 /* 235 * Use kmap_coherent or kmap_atomic to do flushes for 236 * another ASID than the current one. 237 */ 238 map_coherent = (current_cpu_data.dcache.n_aliases && 239 test_bit(PG_dcache_clean, &page->flags) && 240 page_mapcount(page)); 241 if (map_coherent) 242 vaddr = kmap_coherent(page, address); 243 else 244 vaddr = kmap_atomic(page); 245 246 address = (unsigned long)vaddr; 247 } 248 249 flush_cache_one(CACHE_OC_ADDRESS_ARRAY | 250 (address & shm_align_mask), phys); 251 252 if (vma->vm_flags & VM_EXEC) 253 flush_icache_all(); 254 255 if (vaddr) { 256 if (map_coherent) 257 kunmap_coherent(vaddr); 258 else 259 kunmap_atomic(vaddr); 260 } 261} 262 263/* 264 * Write back and invalidate D-caches. 265 * 266 * START, END: Virtual Address (U0 address) 267 * 268 * NOTE: We need to flush the _physical_ page entry. 269 * Flushing the cache lines for U0 only isn't enough. 270 * We need to flush for P1 too, which may contain aliases. 271 */ 272static void sh4_flush_cache_range(void *args) 273{ 274 struct flusher_data *data = args; 275 struct vm_area_struct *vma; 276 unsigned long start, end; 277 278 vma = data->vma; 279 start = data->addr1; 280 end = data->addr2; 281 282 if (cpu_context(smp_processor_id(), vma->vm_mm) == NO_CONTEXT) 283 return; 284 285 /* 286 * If cache is only 4k-per-way, there are never any 'aliases'. Since 287 * the cache is physically tagged, the data can just be left in there. 288 */ 289 if (boot_cpu_data.dcache.n_aliases == 0) 290 return; 291 292 flush_dcache_all(); 293 294 if (vma->vm_flags & VM_EXEC) 295 flush_icache_all(); 296} 297 298/** 299 * __flush_cache_one 300 * 301 * @addr: address in memory mapped cache array 302 * @phys: P1 address to flush (has to match tags if addr has 'A' bit 303 * set i.e. associative write) 304 * @exec_offset: set to 0x20000000 if flush has to be executed from P2 305 * region else 0x0 306 * 307 * The offset into the cache array implied by 'addr' selects the 308 * 'colour' of the virtual address range that will be flushed. The 309 * operation (purge/write-back) is selected by the lower 2 bits of 310 * 'phys'. 311 */ 312static void __flush_cache_one(unsigned long addr, unsigned long phys, 313 unsigned long exec_offset) 314{ 315 int way_count; 316 unsigned long base_addr = addr; 317 struct cache_info *dcache; 318 unsigned long way_incr; 319 unsigned long a, ea, p; 320 unsigned long temp_pc; 321 322 dcache = &boot_cpu_data.dcache; 323 /* Write this way for better assembly. */ 324 way_count = dcache->ways; 325 way_incr = dcache->way_incr; 326 327 /* 328 * Apply exec_offset (i.e. branch to P2 if required.). 329 * 330 * FIXME: 331 * 332 * If I write "=r" for the (temp_pc), it puts this in r6 hence 333 * trashing exec_offset before it's been added on - why? Hence 334 * "=&r" as a 'workaround' 335 */ 336 asm volatile("mov.l 1f, %0\n\t" 337 "add %1, %0\n\t" 338 "jmp @%0\n\t" 339 "nop\n\t" 340 ".balign 4\n\t" 341 "1: .long 2f\n\t" 342 "2:\n" : "=&r" (temp_pc) : "r" (exec_offset)); 343 344 /* 345 * We know there will be >=1 iteration, so write as do-while to avoid 346 * pointless nead-of-loop check for 0 iterations. 347 */ 348 do { 349 ea = base_addr + PAGE_SIZE; 350 a = base_addr; 351 p = phys; 352 353 do { 354 *(volatile unsigned long *)a = p; 355 /* 356 * Next line: intentionally not p+32, saves an add, p 357 * will do since only the cache tag bits need to 358 * match. 359 */ 360 *(volatile unsigned long *)(a+32) = p; 361 a += 64; 362 p += 64; 363 } while (a < ea); 364 365 base_addr += way_incr; 366 } while (--way_count != 0); 367} 368 369extern void __weak sh4__flush_region_init(void); 370 371/* 372 * SH-4 has virtually indexed and physically tagged cache. 373 */ 374void __init sh4_cache_init(void) 375{ 376 printk("PVR=%08x CVR=%08x PRR=%08x\n", 377 __raw_readl(CCN_PVR), 378 __raw_readl(CCN_CVR), 379 __raw_readl(CCN_PRR)); 380 381 local_flush_icache_range = sh4_flush_icache_range; 382 local_flush_dcache_page = sh4_flush_dcache_page; 383 local_flush_cache_all = sh4_flush_cache_all; 384 local_flush_cache_mm = sh4_flush_cache_mm; 385 local_flush_cache_dup_mm = sh4_flush_cache_mm; 386 local_flush_cache_page = sh4_flush_cache_page; 387 local_flush_cache_range = sh4_flush_cache_range; 388 389 sh4__flush_region_init(); 390}