Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.21 173 lines 3.9 kB view raw
1/* 2 * sc-rm7k.c: RM7000 cache management functions. 3 * 4 * Copyright (C) 1997, 2001, 2003, 2004 Ralf Baechle (ralf@linux-mips.org) 5 */ 6 7#undef DEBUG 8 9#include <linux/init.h> 10#include <linux/kernel.h> 11#include <linux/mm.h> 12#include <linux/bitops.h> 13 14#include <asm/addrspace.h> 15#include <asm/bcache.h> 16#include <asm/cacheops.h> 17#include <asm/mipsregs.h> 18#include <asm/processor.h> 19#include <asm/cacheflush.h> /* for run_uncached() */ 20 21/* Primary cache parameters. */ 22#define sc_lsize 32 23#define tc_pagesize (32*128) 24 25/* Secondary cache parameters. */ 26#define scache_size (256*1024) /* Fixed to 256KiB on RM7000 */ 27 28extern unsigned long icache_way_size, dcache_way_size; 29 30#include <asm/r4kcache.h> 31 32int rm7k_tcache_enabled; 33 34/* 35 * Writeback and invalidate the primary cache dcache before DMA. 36 * (XXX These need to be fixed ...) 37 */ 38static void rm7k_sc_wback_inv(unsigned long addr, unsigned long size) 39{ 40 unsigned long end, a; 41 42 pr_debug("rm7k_sc_wback_inv[%08lx,%08lx]", addr, size); 43 44 /* Catch bad driver code */ 45 BUG_ON(size == 0); 46 47 blast_scache_range(addr, addr + size); 48 49 if (!rm7k_tcache_enabled) 50 return; 51 52 a = addr & ~(tc_pagesize - 1); 53 end = (addr + size - 1) & ~(tc_pagesize - 1); 54 while(1) { 55 invalidate_tcache_page(a); /* Page_Invalidate_T */ 56 if (a == end) 57 break; 58 a += tc_pagesize; 59 } 60} 61 62static void rm7k_sc_inv(unsigned long addr, unsigned long size) 63{ 64 unsigned long end, a; 65 66 pr_debug("rm7k_sc_inv[%08lx,%08lx]", addr, size); 67 68 /* Catch bad driver code */ 69 BUG_ON(size == 0); 70 71 blast_inv_scache_range(addr, addr + size); 72 73 if (!rm7k_tcache_enabled) 74 return; 75 76 a = addr & ~(tc_pagesize - 1); 77 end = (addr + size - 1) & ~(tc_pagesize - 1); 78 while(1) { 79 invalidate_tcache_page(a); /* Page_Invalidate_T */ 80 if (a == end) 81 break; 82 a += tc_pagesize; 83 } 84} 85 86/* 87 * This function is executed in uncached address space. 88 */ 89static __init void __rm7k_sc_enable(void) 90{ 91 int i; 92 93 set_c0_config(RM7K_CONF_SE); 94 95 write_c0_taglo(0); 96 write_c0_taghi(0); 97 98 for (i = 0; i < scache_size; i += sc_lsize) { 99 __asm__ __volatile__ ( 100 ".set noreorder\n\t" 101 ".set mips3\n\t" 102 "cache %1, (%0)\n\t" 103 ".set mips0\n\t" 104 ".set reorder" 105 : 106 : "r" (CKSEG0ADDR(i)), "i" (Index_Store_Tag_SD)); 107 } 108} 109 110static __init void rm7k_sc_enable(void) 111{ 112 if (read_c0_config() & RM7K_CONF_SE) 113 return; 114 115 printk(KERN_INFO "Enabling secondary cache...\n"); 116 run_uncached(__rm7k_sc_enable); 117} 118 119static void rm7k_sc_disable(void) 120{ 121 clear_c0_config(RM7K_CONF_SE); 122} 123 124struct bcache_ops rm7k_sc_ops = { 125 .bc_enable = rm7k_sc_enable, 126 .bc_disable = rm7k_sc_disable, 127 .bc_wback_inv = rm7k_sc_wback_inv, 128 .bc_inv = rm7k_sc_inv 129}; 130 131void __init rm7k_sc_init(void) 132{ 133 struct cpuinfo_mips *c = &current_cpu_data; 134 unsigned int config = read_c0_config(); 135 136 if ((config & RM7K_CONF_SC)) 137 return; 138 139 c->scache.linesz = sc_lsize; 140 c->scache.ways = 4; 141 c->scache.waybit= __ffs(scache_size / c->scache.ways); 142 c->scache.waysize = scache_size / c->scache.ways; 143 c->scache.sets = scache_size / (c->scache.linesz * c->scache.ways); 144 printk(KERN_INFO "Secondary cache size %dK, linesize %d bytes.\n", 145 (scache_size >> 10), sc_lsize); 146 147 if (!(config & RM7K_CONF_SE)) 148 rm7k_sc_enable(); 149 150 /* 151 * While we're at it let's deal with the tertiary cache. 152 */ 153 if (!(config & RM7K_CONF_TC)) { 154 155 /* 156 * We can't enable the L3 cache yet. There may be board-specific 157 * magic necessary to turn it on, and blindly asking the CPU to 158 * start using it would may give cache errors. 159 * 160 * Also, board-specific knowledge may allow us to use the 161 * CACHE Flash_Invalidate_T instruction if the tag RAM supports 162 * it, and may specify the size of the L3 cache so we don't have 163 * to probe it. 164 */ 165 printk(KERN_INFO "Tertiary cache present, %s enabled\n", 166 (config & RM7K_CONF_TE) ? "already" : "not (yet)"); 167 168 if ((config & RM7K_CONF_TE)) 169 rm7k_tcache_enabled = 1; 170 } 171 172 bcops = &rm7k_sc_ops; 173}