aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/mm/c-r4k.c
diff options
context:
space:
mode:
authorChris Dearman <chris@mips.com>2006-06-20 13:06:52 -0400
committerRalf Baechle <ralf@linux-mips.org>2006-06-29 16:10:53 -0400
commit73f403527b9ec5367376076eafb3d2f505d8e2e3 (patch)
treebc3f080e75661231d9f30ecb385193bb57f8bc4e /arch/mips/mm/c-r4k.c
parentc09b47d8a99104897afd682b48f292e05461a0c2 (diff)
[MIPS] Fix handling of 0 length I & D caches.
Don't ask. Signed-off-by: Chris Dearman <chris@mips.com> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/mm/c-r4k.c')
-rw-r--r--arch/mips/mm/c-r4k.c64
1 files changed, 41 insertions, 23 deletions
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 01450938db8b..a78355a44c41 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -60,13 +60,13 @@ static unsigned long scache_size __read_mostly;
60/* 60/*
61 * Dummy cache handling routines for machines without boardcaches 61 * Dummy cache handling routines for machines without boardcaches
62 */ 62 */
63static void no_sc_noop(void) {} 63static void cache_noop(void) {}
64 64
65static struct bcache_ops no_sc_ops = { 65static struct bcache_ops no_sc_ops = {
66 .bc_enable = (void *)no_sc_noop, 66 .bc_enable = (void *)cache_noop,
67 .bc_disable = (void *)no_sc_noop, 67 .bc_disable = (void *)cache_noop,
68 .bc_wback_inv = (void *)no_sc_noop, 68 .bc_wback_inv = (void *)cache_noop,
69 .bc_inv = (void *)no_sc_noop 69 .bc_inv = (void *)cache_noop
70}; 70};
71 71
72struct bcache_ops *bcops = &no_sc_ops; 72struct bcache_ops *bcops = &no_sc_ops;
@@ -94,7 +94,9 @@ static inline void r4k_blast_dcache_page_setup(void)
94{ 94{
95 unsigned long dc_lsize = cpu_dcache_line_size(); 95 unsigned long dc_lsize = cpu_dcache_line_size();
96 96
97 if (dc_lsize == 16) 97 if (dc_lsize == 0)
98 r4k_blast_dcache_page = (void *)cache_noop;
99 else if (dc_lsize == 16)
98 r4k_blast_dcache_page = blast_dcache16_page; 100 r4k_blast_dcache_page = blast_dcache16_page;
99 else if (dc_lsize == 32) 101 else if (dc_lsize == 32)
100 r4k_blast_dcache_page = r4k_blast_dcache_page_dc32; 102 r4k_blast_dcache_page = r4k_blast_dcache_page_dc32;
@@ -106,7 +108,9 @@ static inline void r4k_blast_dcache_page_indexed_setup(void)
106{ 108{
107 unsigned long dc_lsize = cpu_dcache_line_size(); 109 unsigned long dc_lsize = cpu_dcache_line_size();
108 110
109 if (dc_lsize == 16) 111 if (dc_lsize == 0)
112 r4k_blast_dcache_page_indexed = (void *)cache_noop;
113 else if (dc_lsize == 16)
110 r4k_blast_dcache_page_indexed = blast_dcache16_page_indexed; 114 r4k_blast_dcache_page_indexed = blast_dcache16_page_indexed;
111 else if (dc_lsize == 32) 115 else if (dc_lsize == 32)
112 r4k_blast_dcache_page_indexed = blast_dcache32_page_indexed; 116 r4k_blast_dcache_page_indexed = blast_dcache32_page_indexed;
@@ -118,7 +122,9 @@ static inline void r4k_blast_dcache_setup(void)
118{ 122{
119 unsigned long dc_lsize = cpu_dcache_line_size(); 123 unsigned long dc_lsize = cpu_dcache_line_size();
120 124
121 if (dc_lsize == 16) 125 if (dc_lsize == 0)
126 r4k_blast_dcache = (void *)cache_noop;
127 else if (dc_lsize == 16)
122 r4k_blast_dcache = blast_dcache16; 128 r4k_blast_dcache = blast_dcache16;
123 else if (dc_lsize == 32) 129 else if (dc_lsize == 32)
124 r4k_blast_dcache = blast_dcache32; 130 r4k_blast_dcache = blast_dcache32;
@@ -201,7 +207,9 @@ static inline void r4k_blast_icache_page_setup(void)
201{ 207{
202 unsigned long ic_lsize = cpu_icache_line_size(); 208 unsigned long ic_lsize = cpu_icache_line_size();
203 209
204 if (ic_lsize == 16) 210 if (ic_lsize == 0)
211 r4k_blast_icache_page = (void *)cache_noop;
212 else if (ic_lsize == 16)
205 r4k_blast_icache_page = blast_icache16_page; 213 r4k_blast_icache_page = blast_icache16_page;
206 else if (ic_lsize == 32) 214 else if (ic_lsize == 32)
207 r4k_blast_icache_page = blast_icache32_page; 215 r4k_blast_icache_page = blast_icache32_page;
@@ -216,7 +224,9 @@ static inline void r4k_blast_icache_page_indexed_setup(void)
216{ 224{
217 unsigned long ic_lsize = cpu_icache_line_size(); 225 unsigned long ic_lsize = cpu_icache_line_size();
218 226
219 if (ic_lsize == 16) 227 if (ic_lsize == 0)
228 r4k_blast_icache_page_indexed = (void *)cache_noop;
229 else if (ic_lsize == 16)
220 r4k_blast_icache_page_indexed = blast_icache16_page_indexed; 230 r4k_blast_icache_page_indexed = blast_icache16_page_indexed;
221 else if (ic_lsize == 32) { 231 else if (ic_lsize == 32) {
222 if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x()) 232 if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x())
@@ -238,7 +248,9 @@ static inline void r4k_blast_icache_setup(void)
238{ 248{
239 unsigned long ic_lsize = cpu_icache_line_size(); 249 unsigned long ic_lsize = cpu_icache_line_size();
240 250
241 if (ic_lsize == 16) 251 if (ic_lsize == 0)
252 r4k_blast_icache = (void *)cache_noop;
253 else if (ic_lsize == 16)
242 r4k_blast_icache = blast_icache16; 254 r4k_blast_icache = blast_icache16;
243 else if (ic_lsize == 32) { 255 else if (ic_lsize == 32) {
244 if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x()) 256 if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x())
@@ -258,7 +270,7 @@ static inline void r4k_blast_scache_page_setup(void)
258 unsigned long sc_lsize = cpu_scache_line_size(); 270 unsigned long sc_lsize = cpu_scache_line_size();
259 271
260 if (scache_size == 0) 272 if (scache_size == 0)
261 r4k_blast_scache_page = (void *)no_sc_noop; 273 r4k_blast_scache_page = (void *)cache_noop;
262 else if (sc_lsize == 16) 274 else if (sc_lsize == 16)
263 r4k_blast_scache_page = blast_scache16_page; 275 r4k_blast_scache_page = blast_scache16_page;
264 else if (sc_lsize == 32) 276 else if (sc_lsize == 32)
@@ -276,7 +288,7 @@ static inline void r4k_blast_scache_page_indexed_setup(void)
276 unsigned long sc_lsize = cpu_scache_line_size(); 288 unsigned long sc_lsize = cpu_scache_line_size();
277 289
278 if (scache_size == 0) 290 if (scache_size == 0)
279 r4k_blast_scache_page_indexed = (void *)no_sc_noop; 291 r4k_blast_scache_page_indexed = (void *)cache_noop;
280 else if (sc_lsize == 16) 292 else if (sc_lsize == 16)
281 r4k_blast_scache_page_indexed = blast_scache16_page_indexed; 293 r4k_blast_scache_page_indexed = blast_scache16_page_indexed;
282 else if (sc_lsize == 32) 294 else if (sc_lsize == 32)
@@ -294,7 +306,7 @@ static inline void r4k_blast_scache_setup(void)
294 unsigned long sc_lsize = cpu_scache_line_size(); 306 unsigned long sc_lsize = cpu_scache_line_size();
295 307
296 if (scache_size == 0) 308 if (scache_size == 0)
297 r4k_blast_scache = (void *)no_sc_noop; 309 r4k_blast_scache = (void *)cache_noop;
298 else if (sc_lsize == 16) 310 else if (sc_lsize == 16)
299 r4k_blast_scache = blast_scache16; 311 r4k_blast_scache = blast_scache16;
300 else if (sc_lsize == 32) 312 else if (sc_lsize == 32)
@@ -508,7 +520,7 @@ static inline void local_r4k_flush_icache_range(void *args)
508 unsigned long end = fir_args->end; 520 unsigned long end = fir_args->end;
509 521
510 if (!cpu_has_ic_fills_f_dc) { 522 if (!cpu_has_ic_fills_f_dc) {
511 if (end - start > dcache_size) { 523 if (end - start >= dcache_size) {
512 r4k_blast_dcache(); 524 r4k_blast_dcache();
513 } else { 525 } else {
514 R4600_HIT_CACHEOP_WAR_IMPL; 526 R4600_HIT_CACHEOP_WAR_IMPL;
@@ -683,10 +695,12 @@ static void local_r4k_flush_cache_sigtramp(void * arg)
683 unsigned long addr = (unsigned long) arg; 695 unsigned long addr = (unsigned long) arg;
684 696
685 R4600_HIT_CACHEOP_WAR_IMPL; 697 R4600_HIT_CACHEOP_WAR_IMPL;
686 protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); 698 if (dc_lsize)
699 protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
687 if (!cpu_icache_snoops_remote_store && scache_size) 700 if (!cpu_icache_snoops_remote_store && scache_size)
688 protected_writeback_scache_line(addr & ~(sc_lsize - 1)); 701 protected_writeback_scache_line(addr & ~(sc_lsize - 1));
689 protected_flush_icache_line(addr & ~(ic_lsize - 1)); 702 if (ic_lsize)
703 protected_flush_icache_line(addr & ~(ic_lsize - 1));
690 if (MIPS4K_ICACHE_REFILL_WAR) { 704 if (MIPS4K_ICACHE_REFILL_WAR) {
691 __asm__ __volatile__ ( 705 __asm__ __volatile__ (
692 ".set push\n\t" 706 ".set push\n\t"
@@ -973,8 +987,10 @@ static void __init probe_pcache(void)
973 c->icache.waysize = icache_size / c->icache.ways; 987 c->icache.waysize = icache_size / c->icache.ways;
974 c->dcache.waysize = dcache_size / c->dcache.ways; 988 c->dcache.waysize = dcache_size / c->dcache.ways;
975 989
976 c->icache.sets = icache_size / (c->icache.linesz * c->icache.ways); 990 c->icache.sets = c->icache.linesz ?
977 c->dcache.sets = dcache_size / (c->dcache.linesz * c->dcache.ways); 991 icache_size / (c->icache.linesz * c->icache.ways) : 0;
992 c->dcache.sets = c->dcache.linesz ?
993 dcache_size / (c->dcache.linesz * c->dcache.ways) : 0;
978 994
979 /* 995 /*
980 * R10000 and R12000 P-caches are odd in a positive way. They're 32kB 996 * R10000 and R12000 P-caches are odd in a positive way. They're 32kB
@@ -1259,10 +1275,12 @@ void __init r4k_cache_init(void)
1259 * This code supports virtually indexed processors and will be 1275 * This code supports virtually indexed processors and will be
1260 * unnecessarily inefficient on physically indexed processors. 1276 * unnecessarily inefficient on physically indexed processors.
1261 */ 1277 */
1262 shm_align_mask = max_t( unsigned long, 1278 if (c->dcache.linesz)
1263 c->dcache.sets * c->dcache.linesz - 1, 1279 shm_align_mask = max_t( unsigned long,
1264 PAGE_SIZE - 1); 1280 c->dcache.sets * c->dcache.linesz - 1,
1265 1281 PAGE_SIZE - 1);
1282 else
1283 shm_align_mask = PAGE_SIZE-1;
1266 flush_cache_all = r4k_flush_cache_all; 1284 flush_cache_all = r4k_flush_cache_all;
1267 __flush_cache_all = r4k___flush_cache_all; 1285 __flush_cache_all = r4k___flush_cache_all;
1268 flush_cache_mm = r4k_flush_cache_mm; 1286 flush_cache_mm = r4k_flush_cache_mm;