1
2
3
4
5
6
7
8
9
10
11
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/sched.h>
15#include <linux/mm.h>
16
17#include <asm/bcache.h>
18#include <asm/io.h>
19#include <asm/page.h>
20#include <asm/pgtable.h>
21#include <asm/system.h>
22#include <asm/bootinfo.h>
23#include <asm/sgialib.h>
24#include <asm/mmu_context.h>
25
26
27#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
28 "nop; nop; nop; nop; nop; nop;\n\t" \
29 ".set reorder\n\t")
30
31
32static int icache_size, dcache_size;
33static int ic_lsize, dc_lsize;
34
35
36static unsigned int scache_size, sc_lsize;
37
38#include <asm/r4kcacheops.h>
39#include <asm/r4kcache.h>
40
41#undef DEBUG_CACHE
42
43
44
45
46static void no_sc_noop(void) {}
47
48static struct bcache_ops no_sc_ops = {
49 (void *)no_sc_noop, (void *)no_sc_noop,
50 (void *)no_sc_noop, (void *)no_sc_noop
51};
52
53struct bcache_ops *bcops = &no_sc_ops;
54
55
56
57
58
59
60#define icache_waybit (icache_size >> 1)
61#define dcache_waybit (dcache_size >> 1)
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76static void r4k_clear_page_d16(void * page)
77{
78 __asm__ __volatile__(
79 ".set\tnoreorder\n\t"
80 ".set\tnoat\n\t"
81 "daddiu\t$1,%0,%2\n"
82 "1:\tcache\t%3,(%0)\n\t"
83 "sd\t$0,(%0)\n\t"
84 "sd\t$0,8(%0)\n\t"
85 "cache\t%3,16(%0)\n\t"
86 "sd\t$0,16(%0)\n\t"
87 "sd\t$0,24(%0)\n\t"
88 "daddiu\t%0,64\n\t"
89 "cache\t%3,-32(%0)\n\t"
90 "sd\t$0,-32(%0)\n\t"
91 "sd\t$0,-24(%0)\n\t"
92 "cache\t%3,-16(%0)\n\t"
93 "sd\t$0,-16(%0)\n\t"
94 "bne\t$1,%0,1b\n\t"
95 "sd\t$0,-8(%0)\n\t"
96 ".set\tat\n\t"
97 ".set\treorder"
98 :"=r" (page)
99 :"0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D)
100 :"$1", "memory");
101}
102
103static void r4k_clear_page_d32(void * page)
104{
105 __asm__ __volatile__(
106 ".set\tnoreorder\n\t"
107 ".set\tnoat\n\t"
108 "daddiu\t$1,%0,%2\n"
109 "1:\tcache\t%3,(%0)\n\t"
110 "sd\t$0,(%0)\n\t"
111 "sd\t$0,8(%0)\n\t"
112 "sd\t$0,16(%0)\n\t"
113 "sd\t$0,24(%0)\n\t"
114 "daddiu\t%0,64\n\t"
115 "cache\t%3,-32(%0)\n\t"
116 "sd\t$0,-32(%0)\n\t"
117 "sd\t$0,-24(%0)\n\t"
118 "sd\t$0,-16(%0)\n\t"
119 "bne\t$1,%0,1b\n\t"
120 "sd\t$0,-8(%0)\n\t"
121 ".set\tat\n\t"
122 ".set\treorder"
123 :"=r" (page)
124 :"0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D)
125 :"$1", "memory");
126}
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156static void r4k_clear_page_r4600_v1(void * page)
157{
158 __asm__ __volatile__(
159 ".set\tnoreorder\n\t"
160 ".set\tnoat\n\t"
161 "daddiu\t$1,%0,%2\n"
162 "1:\tnop\n\t"
163 "nop\n\t"
164 "nop\n\t"
165 "nop\n\t"
166 "cache\t%3,(%0)\n\t"
167 "sd\t$0,(%0)\n\t"
168 "sd\t$0,8(%0)\n\t"
169 "sd\t$0,16(%0)\n\t"
170 "sd\t$0,24(%0)\n\t"
171 "daddiu\t%0,64\n\t"
172 "nop\n\t"
173 "nop\n\t"
174 "nop\n\t"
175 "cache\t%3,-32(%0)\n\t"
176 "sd\t$0,-32(%0)\n\t"
177 "sd\t$0,-24(%0)\n\t"
178 "sd\t$0,-16(%0)\n\t"
179 "bne\t$1,%0,1b\n\t"
180 "sd\t$0,-8(%0)\n\t"
181 ".set\tat\n\t"
182 ".set\treorder"
183 :"=r" (page)
184 :"0" (page),
185 "I" (PAGE_SIZE),
186 "i" (Create_Dirty_Excl_D)
187 :"$1", "memory");
188}
189
190
191
192
193static void r4k_clear_page_r4600_v2(void * page)
194{
195 unsigned int flags;
196
197 local_irq_save(flags);
198 *(volatile unsigned int *)KSEG1;
199 __asm__ __volatile__(
200 ".set\tnoreorder\n\t"
201 ".set\tnoat\n\t"
202 "daddiu\t$1,%0,%2\n"
203 "1:\tcache\t%3,(%0)\n\t"
204 "sd\t$0,(%0)\n\t"
205 "sd\t$0,8(%0)\n\t"
206 "sd\t$0,16(%0)\n\t"
207 "sd\t$0,24(%0)\n\t"
208 "daddiu\t%0,64\n\t"
209 "cache\t%3,-32(%0)\n\t"
210 "sd\t$0,-32(%0)\n\t"
211 "sd\t$0,-24(%0)\n\t"
212 "sd\t$0,-16(%0)\n\t"
213 "bne\t$1,%0,1b\n\t"
214 "sd\t$0,-8(%0)\n\t"
215 ".set\tat\n\t"
216 ".set\treorder"
217 :"=r" (page)
218 :"0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D)
219 :"$1", "memory");
220 local_irq_restore(flags);
221}
222
223
224
225
226
227
228
229
230
231
232static void r4k_clear_page_s16(void * page)
233{
234 __asm__ __volatile__(
235 ".set\tnoreorder\n\t"
236 ".set\tnoat\n\t"
237 "daddiu\t$1,%0,%2\n"
238 "1:\tcache\t%3,(%0)\n\t"
239 "sd\t$0,(%0)\n\t"
240 "sd\t$0,8(%0)\n\t"
241 "cache\t%3,16(%0)\n\t"
242 "sd\t$0,16(%0)\n\t"
243 "sd\t$0,24(%0)\n\t"
244 "daddiu\t%0,64\n\t"
245 "cache\t%3,-32(%0)\n\t"
246 "sd\t$0,-32(%0)\n\t"
247 "sd\t$0,-24(%0)\n\t"
248 "cache\t%3,-16(%0)\n\t"
249 "sd\t$0,-16(%0)\n\t"
250 "bne\t$1,%0,1b\n\t"
251 "sd\t$0,-8(%0)\n\t"
252 ".set\tat\n\t"
253 ".set\treorder"
254 :"=r" (page)
255 :"0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD)
256 :"$1","memory");
257}
258
259static void r4k_clear_page_s32(void * page)
260{
261 __asm__ __volatile__(
262 ".set\tnoreorder\n\t"
263 ".set\tnoat\n\t"
264 "daddiu\t$1,%0,%2\n"
265 "1:\tcache\t%3,(%0)\n\t"
266 "sd\t$0,(%0)\n\t"
267 "sd\t$0,8(%0)\n\t"
268 "sd\t$0,16(%0)\n\t"
269 "sd\t$0,24(%0)\n\t"
270 "daddiu\t%0,64\n\t"
271 "cache\t%3,-32(%0)\n\t"
272 "sd\t$0,-32(%0)\n\t"
273 "sd\t$0,-24(%0)\n\t"
274 "sd\t$0,-16(%0)\n\t"
275 "bne\t$1,%0,1b\n\t"
276 "sd\t$0,-8(%0)\n\t"
277 ".set\tat\n\t"
278 ".set\treorder"
279 :"=r" (page)
280 :"0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD)
281 :"$1","memory");
282}
283
284static void r4k_clear_page_s64(void * page)
285{
286 __asm__ __volatile__(
287 ".set\tnoreorder\n\t"
288 ".set\tnoat\n\t"
289 "daddiu\t$1,%0,%2\n"
290 "1:\tcache\t%3,(%0)\n\t"
291 "sd\t$0,(%0)\n\t"
292 "sd\t$0,8(%0)\n\t"
293 "sd\t$0,16(%0)\n\t"
294 "sd\t$0,24(%0)\n\t"
295 "daddiu\t%0,64\n\t"
296 "sd\t$0,-32(%0)\n\t"
297 "sd\t$0,-24(%0)\n\t"
298 "sd\t$0,-16(%0)\n\t"
299 "bne\t$1,%0,1b\n\t"
300 "sd\t$0,-8(%0)\n\t"
301 ".set\tat\n\t"
302 ".set\treorder"
303 :"=r" (page)
304 :"0" (page),
305 "I" (PAGE_SIZE),
306 "i" (Create_Dirty_Excl_SD)
307 :"$1","memory");
308}
309
310static void r4k_clear_page_s128(void * page)
311{
312 __asm__ __volatile__(
313 ".set\tnoreorder\n\t"
314 ".set\tnoat\n\t"
315 "daddiu\t$1,%0,%2\n"
316 "1:\tcache\t%3,(%0)\n\t"
317 "sd\t$0,(%0)\n\t"
318 "sd\t$0,8(%0)\n\t"
319 "sd\t$0,16(%0)\n\t"
320 "sd\t$0,24(%0)\n\t"
321 "sd\t$0,32(%0)\n\t"
322 "sd\t$0,40(%0)\n\t"
323 "sd\t$0,48(%0)\n\t"
324 "sd\t$0,56(%0)\n\t"
325 "daddiu\t%0,128\n\t"
326 "sd\t$0,-64(%0)\n\t"
327 "sd\t$0,-56(%0)\n\t"
328 "sd\t$0,-48(%0)\n\t"
329 "sd\t$0,-40(%0)\n\t"
330 "sd\t$0,-32(%0)\n\t"
331 "sd\t$0,-24(%0)\n\t"
332 "sd\t$0,-16(%0)\n\t"
333 "bne\t$1,%0,1b\n\t"
334 "sd\t$0,-8(%0)\n\t"
335 ".set\tat\n\t"
336 ".set\treorder"
337 :"=r" (page)
338 :"0" (page),
339 "I" (PAGE_SIZE),
340 "i" (Create_Dirty_Excl_SD)
341 :"$1", "memory");
342}
343
344
345
346
347
348
349
350static void r4k_copy_page_d16(void * to, void * from)
351{
352 unsigned long dummy1, dummy2, reg1, reg2;
353
354 __asm__ __volatile__(
355 ".set\tnoreorder\n\t"
356 ".set\tnoat\n\t"
357 "daddiu\t$1,%0,%6\n"
358 "1:\tcache\t%7,(%0)\n\t"
359 "ld\t%2,(%1)\n\t"
360 "ld\t%3,8(%1)\n\t"
361 "sd\t%2,(%0)\n\t"
362 "sd\t%3,8(%0)\n\t"
363 "cache\t%7,16(%0)\n\t"
364 "ld\t%2,16(%1)\n\t"
365 "ld\t%3,24(%1)\n\t"
366 "sd\t%2,16(%0)\n\t"
367 "sd\t%3,24(%0)\n\t"
368 "cache\t%7,32(%0)\n\t"
369 "daddiu\t%0,64\n\t"
370 "daddiu\t%1,64\n\t"
371 "ld\t%2,-32(%1)\n\t"
372 "ld\t%3,-24(%1)\n\t"
373 "sd\t%2,-32(%0)\n\t"
374 "sd\t%3,-24(%0)\n\t"
375 "cache\t%7,-16(%0)\n\t"
376 "ld\t%2,-16(%1)\n\t"
377 "ld\t%3,-8(%1)\n\t"
378 "sd\t%2,-16(%0)\n\t"
379 "bne\t$1,%0,1b\n\t"
380 " sd\t%3,-8(%0)\n\t"
381 ".set\tat\n\t"
382 ".set\treorder"
383 :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2)
384 :"0" (to), "1" (from), "I" (PAGE_SIZE),
385 "i" (Create_Dirty_Excl_D));
386}
387
388static void r4k_copy_page_d32(void * to, void * from)
389{
390 unsigned long dummy1, dummy2, reg1, reg2;
391
392 __asm__ __volatile__(
393 ".set\tnoreorder\n\t"
394 ".set\tnoat\n\t"
395 "daddiu\t$1,%0,%6\n"
396 "1:\tcache\t%7,(%0)\n\t"
397 "ld\t%2,(%1)\n\t"
398 "ld\t%3,8(%1)\n\t"
399 "sd\t%2,(%0)\n\t"
400 "sd\t%3,8(%0)\n\t"
401 "ld\t%2,16(%1)\n\t"
402 "ld\t%3,24(%1)\n\t"
403 "sd\t%2,16(%0)\n\t"
404 "sd\t%3,24(%0)\n\t"
405 "cache\t%7,32(%0)\n\t"
406 "daddiu\t%0,64\n\t"
407 "daddiu\t%1,64\n\t"
408 "ld\t%2,-32(%1)\n\t"
409 "ld\t%3,-24(%1)\n\t"
410 "sd\t%2,-32(%0)\n\t"
411 "sd\t%3,-24(%0)\n\t"
412 "ld\t%2,-16(%1)\n\t"
413 "ld\t%3,-8(%1)\n\t"
414 "sd\t%2,-16(%0)\n\t"
415 "bne\t$1,%0,1b\n\t"
416 " sd\t%3,-8(%0)\n\t"
417 ".set\tat\n\t"
418 ".set\treorder"
419 :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2)
420 :"0" (to), "1" (from), "I" (PAGE_SIZE),
421 "i" (Create_Dirty_Excl_D));
422}
423
424
425
426
427static void r4k_copy_page_r4600_v1(void * to, void * from)
428{
429 unsigned long dummy1, dummy2, reg1, reg2;
430
431 __asm__ __volatile__(
432 ".set\tnoreorder\n\t"
433 ".set\tnoat\n\t"
434 "daddiu\t$1,%0,%6\n"
435 "1:\tnop\n\t"
436 "nop\n\t"
437 "nop\n\t"
438 "nop\n\t"
439 "\tcache\t%7,(%0)\n\t"
440 "ld\t%2,(%1)\n\t"
441 "ld\t%3,8(%1)\n\t"
442 "sd\t%2,(%0)\n\t"
443 "sd\t%3,8(%0)\n\t"
444 "ld\t%2,16(%1)\n\t"
445 "ld\t%3,24(%1)\n\t"
446 "sd\t%2,16(%0)\n\t"
447 "sd\t%3,24(%0)\n\t"
448 "nop\n\t"
449 "nop\n\t"
450 "nop\n\t"
451 "nop\n\t"
452 "cache\t%7,32(%0)\n\t"
453 "daddiu\t%0,64\n\t"
454 "daddiu\t%1,64\n\t"
455 "ld\t%2,-32(%1)\n\t"
456 "ld\t%3,-24(%1)\n\t"
457 "sd\t%2,-32(%0)\n\t"
458 "sd\t%3,-24(%0)\n\t"
459 "ld\t%2,-16(%1)\n\t"
460 "ld\t%3,-8(%1)\n\t"
461 "sd\t%2,-16(%0)\n\t"
462 "bne\t$1,%0,1b\n\t"
463 " sd\t%3,-8(%0)\n\t"
464 ".set\tat\n\t"
465 ".set\treorder"
466 :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2)
467 :"0" (to), "1" (from), "I" (PAGE_SIZE),
468 "i" (Create_Dirty_Excl_D));
469}
470
471static void r4k_copy_page_r4600_v2(void * to, void * from)
472{
473 unsigned long dummy1, dummy2, reg1, reg2;
474 unsigned int flags;
475
476 local_irq_save(flags);
477 __asm__ __volatile__(
478 ".set\tnoreorder\n\t"
479 ".set\tnoat\n\t"
480 "daddiu\t$1,%0,%6\n"
481 "1:\tnop\n\t"
482 "nop\n\t"
483 "nop\n\t"
484 "nop\n\t"
485 "\tcache\t%7,(%0)\n\t"
486 "ld\t%2,(%1)\n\t"
487 "ld\t%3,8(%1)\n\t"
488 "sd\t%2,(%0)\n\t"
489 "sd\t%3,8(%0)\n\t"
490 "ld\t%2,16(%1)\n\t"
491 "ld\t%3,24(%1)\n\t"
492 "sd\t%2,16(%0)\n\t"
493 "sd\t%3,24(%0)\n\t"
494 "nop\n\t"
495 "nop\n\t"
496 "nop\n\t"
497 "nop\n\t"
498 "cache\t%7,32(%0)\n\t"
499 "daddiu\t%0,64\n\t"
500 "daddiu\t%1,64\n\t"
501 "ld\t%2,-32(%1)\n\t"
502 "ld\t%3,-24(%1)\n\t"
503 "sd\t%2,-32(%0)\n\t"
504 "sd\t%3,-24(%0)\n\t"
505 "ld\t%2,-16(%1)\n\t"
506 "ld\t%3,-8(%1)\n\t"
507 "sd\t%2,-16(%0)\n\t"
508 "bne\t$1,%0,1b\n\t"
509 " sd\t%3,-8(%0)\n\t"
510 ".set\tat\n\t"
511 ".set\treorder"
512 :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2)
513 :"0" (to), "1" (from), "I" (PAGE_SIZE),
514 "i" (Create_Dirty_Excl_D));
515 local_irq_restore(flags);
516}
517
518
519
520
521static void r4k_copy_page_s16(void * to, void * from)
522{
523 unsigned long dummy1, dummy2, reg1, reg2;
524
525 __asm__ __volatile__(
526 ".set\tnoreorder\n\t"
527 ".set\tnoat\n\t"
528 "daddiu\t$1,%0,%6\n"
529 "1:\tcache\t%7,(%0)\n\t"
530 "ld\t%2,(%1)\n\t"
531 "ld\t%3,8(%1)\n\t"
532 "sd\t%2,(%0)\n\t"
533 "sd\t%3,8(%0)\n\t"
534 "cache\t%7,16(%0)\n\t"
535 "ld\t%2,16(%1)\n\t"
536 "ld\t%3,24(%1)\n\t"
537 "sd\t%2,16(%0)\n\t"
538 "sd\t%3,24(%0)\n\t"
539 "cache\t%7,32(%0)\n\t"
540 "daddiu\t%0,64\n\t"
541 "daddiu\t%1,64\n\t"
542 "ld\t%2,-32(%1)\n\t"
543 "ld\t%3,-24(%1)\n\t"
544 "sd\t%2,-32(%0)\n\t"
545 "sd\t%3,-24(%0)\n\t"
546 "cache\t%7,-16(%0)\n\t"
547 "ld\t%2,-16(%1)\n\t"
548 "ld\t%3,-8(%1)\n\t"
549 "sd\t%2,-16(%0)\n\t"
550 "bne\t$1,%0,1b\n\t"
551 " sd\t%3,-8(%0)\n\t"
552 ".set\tat\n\t"
553 ".set\treorder"
554 :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2)
555 :"0" (to), "1" (from), "I" (PAGE_SIZE),
556 "i" (Create_Dirty_Excl_SD));
557}
558
559static void r4k_copy_page_s32(void * to, void * from)
560{
561 unsigned long dummy1, dummy2, reg1, reg2;
562
563 __asm__ __volatile__(
564 ".set\tnoreorder\n\t"
565 ".set\tnoat\n\t"
566 "daddiu\t$1,%0,%6\n"
567 "1:\tcache\t%7,(%0)\n\t"
568 "ld\t%2,(%1)\n\t"
569 "ld\t%3,8(%1)\n\t"
570 "sd\t%2,(%0)\n\t"
571 "sd\t%3,8(%0)\n\t"
572 "ld\t%2,16(%1)\n\t"
573 "ld\t%3,24(%1)\n\t"
574 "sd\t%2,16(%0)\n\t"
575 "sd\t%3,24(%0)\n\t"
576 "cache\t%7,32(%0)\n\t"
577 "daddiu\t%0,64\n\t"
578 "daddiu\t%1,64\n\t"
579 "ld\t%2,-32(%1)\n\t"
580 "ld\t%3,-24(%1)\n\t"
581 "sd\t%2,-32(%0)\n\t"
582 "sd\t%3,-24(%0)\n\t"
583 "ld\t%2,-16(%1)\n\t"
584 "ld\t%3,-8(%1)\n\t"
585 "sd\t%2,-16(%0)\n\t"
586 "bne\t$1,%0,1b\n\t"
587 " sd\t%3,-8(%0)\n\t"
588 ".set\tat\n\t"
589 ".set\treorder"
590 :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2)
591 :"0" (to), "1" (from), "I" (PAGE_SIZE),
592 "i" (Create_Dirty_Excl_SD));
593}
594
595static void r4k_copy_page_s64(void * to, void * from)
596{
597 unsigned long dummy1, dummy2, reg1, reg2;
598
599 __asm__ __volatile__(
600 ".set\tnoreorder\n\t"
601 ".set\tnoat\n\t"
602 "daddiu\t$1,%0,%6\n"
603 "1:\tcache\t%7,(%0)\n\t"
604 "ld\t%2,(%1)\n\t"
605 "ld\t%3,8(%1)\n\t"
606 "sd\t%2,(%0)\n\t"
607 "sd\t%3,8(%0)\n\t"
608 "ld\t%2,16(%1)\n\t"
609 "ld\t%3,24(%1)\n\t"
610 "sd\t%2,16(%0)\n\t"
611 "sd\t%3,24(%0)\n\t"
612 "daddiu\t%0,64\n\t"
613 "daddiu\t%1,64\n\t"
614 "ld\t%2,-32(%1)\n\t"
615 "ld\t%3,-24(%1)\n\t"
616 "sd\t%2,-32(%0)\n\t"
617 "sd\t%3,-24(%0)\n\t"
618 "ld\t%2,-16(%1)\n\t"
619 "ld\t%3,-8(%1)\n\t"
620 "sd\t%2,-16(%0)\n\t"
621 "bne\t$1,%0,1b\n\t"
622 " sd\t%3,-8(%0)\n\t"
623 ".set\tat\n\t"
624 ".set\treorder"
625 :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2)
626 :"0" (to), "1" (from), "I" (PAGE_SIZE),
627 "i" (Create_Dirty_Excl_SD));
628}
629
630static void r4k_copy_page_s128(void * to, void * from)
631{
632 unsigned long dummy1, dummy2;
633 unsigned long reg1, reg2, reg3, reg4;
634
635 __asm__ __volatile__(
636 ".set\tnoreorder\n\t"
637 ".set\tnoat\n\t"
638 "daddiu\t$1,%0,%8\n"
639 "1:\tcache\t%9,(%0)\n\t"
640 "ld\t%2,(%1)\n\t"
641 "ld\t%3,8(%1)\n\t"
642 "ld\t%4,16(%1)\n\t"
643 "ld\t%5,24(%1)\n\t"
644 "sd\t%2,(%0)\n\t"
645 "sd\t%3,8(%0)\n\t"
646 "sd\t%4,16(%0)\n\t"
647 "sd\t%5,24(%0)\n\t"
648 "ld\t%2,32(%1)\n\t"
649 "ld\t%3,40(%1)\n\t"
650 "ld\t%4,48(%1)\n\t"
651 "ld\t%5,56(%1)\n\t"
652 "sd\t%2,32(%0)\n\t"
653 "sd\t%3,40(%0)\n\t"
654 "sd\t%4,48(%0)\n\t"
655 "sd\t%5,56(%0)\n\t"
656 "daddiu\t%0,128\n\t"
657 "daddiu\t%1,128\n\t"
658 "ld\t%2,-64(%1)\n\t"
659 "ld\t%3,-56(%1)\n\t"
660 "ld\t%4,-48(%1)\n\t"
661 "ld\t%5,-40(%1)\n\t"
662 "sd\t%2,-64(%0)\n\t"
663 "sd\t%3,-56(%0)\n\t"
664 "sd\t%4,-48(%0)\n\t"
665 "sd\t%5,-40(%0)\n\t"
666 "ld\t%2,-32(%1)\n\t"
667 "ld\t%3,-24(%1)\n\t"
668 "ld\t%4,-16(%1)\n\t"
669 "ld\t%5,-8(%1)\n\t"
670 "sd\t%2,-32(%0)\n\t"
671 "sd\t%3,-24(%0)\n\t"
672 "sd\t%4,-16(%0)\n\t"
673 "bne\t$1,%0,1b\n\t"
674 " sd\t%5,-8(%0)\n\t"
675 ".set\tat\n\t"
676 ".set\treorder"
677 :"=r" (dummy1), "=r" (dummy2),
678 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
679 :"0" (to), "1" (from),
680 "I" (PAGE_SIZE),
681 "i" (Create_Dirty_Excl_SD));
682}
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698static inline void r4k_flush_cache_all_s16d16i16(void)
699{
700 unsigned long flags;
701
702 local_irq_save(flags);
703 blast_dcache16(); blast_icache16(); blast_scache16();
704 local_irq_restore(flags);
705}
706
707static inline void r4k_flush_cache_all_s32d16i16(void)
708{
709 unsigned long flags;
710
711 local_irq_save(flags);
712 blast_dcache16(); blast_icache16(); blast_scache32();
713 local_irq_restore(flags);
714}
715
716static inline void r4k_flush_cache_all_s64d16i16(void)
717{
718 unsigned long flags;
719
720 local_irq_save(flags);
721 blast_dcache16(); blast_icache16(); blast_scache64();
722 local_irq_restore(flags);
723}
724
725static inline void r4k_flush_cache_all_s128d16i16(void)
726{
727 unsigned long flags;
728
729 local_irq_save(flags);
730 blast_dcache16(); blast_icache16(); blast_scache128();
731 local_irq_restore(flags);
732}
733
734static inline void r4k_flush_cache_all_s32d32i32(void)
735{
736 unsigned long flags;
737
738 local_irq_save(flags);
739 blast_dcache32(); blast_icache32(); blast_scache32();
740 local_irq_restore(flags);
741}
742
743static inline void r4k_flush_cache_all_s64d32i32(void)
744{
745 unsigned long flags;
746
747 local_irq_save(flags);
748 blast_dcache32(); blast_icache32(); blast_scache64();
749 local_irq_restore(flags);
750}
751
752static inline void r4k_flush_cache_all_s128d32i32(void)
753{
754 unsigned long flags;
755
756 local_irq_save(flags);
757 blast_dcache32(); blast_icache32(); blast_scache128();
758 local_irq_restore(flags);
759}
760
761static inline void r4k_flush_cache_all_d16i16(void)
762{
763 unsigned long flags;
764
765 local_irq_save(flags);
766 blast_dcache16(); blast_icache16();
767 local_irq_restore(flags);
768}
769
770static inline void r4k_flush_cache_all_d32i32(void)
771{
772 unsigned long flags;
773
774 local_irq_save(flags);
775 blast_dcache32(); blast_icache32();
776 local_irq_restore(flags);
777}
778
779static void r4k_flush_cache_range_s16d16i16(struct vm_area_struct *vma,
780 unsigned long start,
781 unsigned long end)
782{
783 struct mm_struct *mm = vma->vm_mm;
784 unsigned long flags;
785
786 if (CPU_CONTEXT(smp_processor_id(), mm) == 0)
787 return;
788
789 start &= PAGE_MASK;
790#ifdef DEBUG_CACHE
791 printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
792#endif
793 if (vma) {
794 if (CPU_CONTEXT(smp_processor_id(), mm) !=
795 CPU_CONTEXT(smp_processor_id(), current->mm)) {
796 r4k_flush_cache_all_s16d16i16();
797 } else {
798 pgd_t *pgd;
799 pmd_t *pmd;
800 pte_t *pte;
801
802 local_irq_save(flags);
803 while(start < end) {
804 pgd = pgd_offset(mm, start);
805 pmd = pmd_offset(pgd, start);
806 pte = pte_offset(pmd, start);
807
808 if(pte_val(*pte) & _PAGE_VALID)
809 blast_scache16_page(start);
810 start += PAGE_SIZE;
811 }
812 local_irq_restore(flags);
813 }
814 }
815}
816
817static void r4k_flush_cache_range_s32d16i16(struct vm_area_struct *vma,
818 unsigned long start,
819 unsigned long end)
820{
821 struct mm_struct *mm = vma->vm_mm;
822 unsigned long flags;
823
824 if (CPU_CONTEXT(smp_processor_id(), mm) == 0)
825 return;
826
827 start &= PAGE_MASK;
828#ifdef DEBUG_CACHE
829 printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
830#endif
831 if (vma) {
832 if (CPU_CONTEXT(smp_processor_id(), mm) !=
833 CPU_CONTEXT(smp_processor_id(), current->mm)) {
834 r4k_flush_cache_all_s32d16i16();
835 } else {
836 pgd_t *pgd;
837 pmd_t *pmd;
838 pte_t *pte;
839
840 local_irq_save(flags);
841 while(start < end) {
842 pgd = pgd_offset(mm, start);
843 pmd = pmd_offset(pgd, start);
844 pte = pte_offset(pmd, start);
845
846 if(pte_val(*pte) & _PAGE_VALID)
847 blast_scache32_page(start);
848 start += PAGE_SIZE;
849 }
850 local_irq_restore(flags);
851 }
852 }
853}
854
855static void r4k_flush_cache_range_s64d16i16(struct vm_area_struct *vma,
856 unsigned long start,
857 unsigned long end)
858{
859 struct mm_struct *mm = vma->vm_mm;
860 unsigned long flags;
861
862 if (CPU_CONTEXT(smp_processor_id(), mm) == 0)
863 return;
864
865 start &= PAGE_MASK;
866#ifdef DEBUG_CACHE
867 printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
868#endif
869 if (vma) {
870 if (CPU_CONTEXT(smp_processor_id(), mm) !=
871 CPU_CONTEXT(smp_processor_id(), current->mm)) {
872 r4k_flush_cache_all_s64d16i16();
873 } else {
874 pgd_t *pgd;
875 pmd_t *pmd;
876 pte_t *pte;
877
878 local_irq_save(flags);
879 while(start < end) {
880 pgd = pgd_offset(mm, start);
881 pmd = pmd_offset(pgd, start);
882 pte = pte_offset(pmd, start);
883
884 if(pte_val(*pte) & _PAGE_VALID)
885 blast_scache64_page(start);
886 start += PAGE_SIZE;
887 }
888 local_irq_restore(flags);
889 }
890 }
891}
892
893static void r4k_flush_cache_range_s128d16i16(struct vm_area_struct *vma,
894 unsigned long start,
895 unsigned long end)
896{
897 struct mm_struct *mm = vma->vm_mm;
898 unsigned long flags;
899
900 if (CPU_CONTEXT(smp_processor_id(), mm) == 0)
901 return;
902
903 start &= PAGE_MASK;
904#ifdef DEBUG_CACHE
905 printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
906#endif
907 if (vma) {
908 if (CPU_CONTEXT(smp_processor_id(), mm) !=
909 CPU_CONTEXT(smp_processor_id(), current->mm)) {
910 r4k_flush_cache_all_s128d16i16();
911 } else {
912 pgd_t *pgd;
913 pmd_t *pmd;
914 pte_t *pte;
915
916 local_irq_save(flags);
917 while(start < end) {
918 pgd = pgd_offset(mm, start);
919 pmd = pmd_offset(pgd, start);
920 pte = pte_offset(pmd, start);
921
922 if(pte_val(*pte) & _PAGE_VALID)
923 blast_scache128_page(start);
924 start += PAGE_SIZE;
925 }
926 local_irq_restore(flags);
927 }
928 }
929}
930
931static void r4k_flush_cache_range_s32d32i32(struct vm_area_struct *vma,
932 unsigned long start,
933 unsigned long end)
934{
935 struct mm_struct *mm = vma->vm_mm;
936 unsigned long flags;
937
938 if (CPU_CONTEXT(smp_processor_id(), mm) == 0)
939 return;
940
941 start &= PAGE_MASK;
942#ifdef DEBUG_CACHE
943 printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
944#endif
945 if (vma) {
946 if (CPU_CONTEXT(smp_processor_id(), mm) !=
947 CPU_CONTEXT(smp_processor_id(), current->mm)) {
948 r4k_flush_cache_all_s32d32i32();
949 } else {
950 pgd_t *pgd;
951 pmd_t *pmd;
952 pte_t *pte;
953
954 local_irq_save(flags);
955 while(start < end) {
956 pgd = pgd_offset(mm, start);
957 pmd = pmd_offset(pgd, start);
958 pte = pte_offset(pmd, start);
959
960 if(pte_val(*pte) & _PAGE_VALID)
961 blast_scache32_page(start);
962 start += PAGE_SIZE;
963 }
964 local_irq_restore(flags);
965 }
966 }
967}
968
969static void r4k_flush_cache_range_s64d32i32(struct vm_area_struct *vma,
970 unsigned long start,
971 unsigned long end)
972{
973 struct mm_struct *mm = vma->vm_mm;
974 unsigned long flags;
975
976 if (CPU_CONTEXT(smp_processor_id(), mm) == 0)
977 return;
978
979 start &= PAGE_MASK;
980#ifdef DEBUG_CACHE
981 printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
982#endif
983 if (vma) {
984 if (CPU_CONTEXT(smp_processor_id(), mm) !=
985 CPU_CONTEXT(smp_processor_id(), current->mm)) {
986 r4k_flush_cache_all_s64d32i32();
987 } else {
988 pgd_t *pgd;
989 pmd_t *pmd;
990 pte_t *pte;
991
992 local_irq_save(flags);
993 while(start < end) {
994 pgd = pgd_offset(mm, start);
995 pmd = pmd_offset(pgd, start);
996 pte = pte_offset(pmd, start);
997
998 if(pte_val(*pte) & _PAGE_VALID)
999 blast_scache64_page(start);
1000 start += PAGE_SIZE;
1001 }
1002 local_irq_restore(flags);
1003 }
1004 }
1005}
1006
1007static void r4k_flush_cache_range_s128d32i32(struct vm_area_struct *vma,
1008 unsigned long start,
1009 unsigned long end)
1010{
1011 struct mm_struct *mm = vma->vm_mm;
1012 unsigned long flags;
1013
1014 if (CPU_CONTEXT(smp_processor_id(), mm) != 0)
1015 return;
1016
1017 start &= PAGE_MASK;
1018#ifdef DEBUG_CACHE
1019 printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
1020#endif
1021 if (vma) {
1022 if (CPU_CONTEXT(smp_processor_id(), mm) !=
1023 CPU_CONTEXT(smp_processor_id(), current->mm)) {
1024 r4k_flush_cache_all_s128d32i32();
1025 } else {
1026 pgd_t *pgd;
1027 pmd_t *pmd;
1028 pte_t *pte;
1029
1030 local_irq_save(flags);
1031 while(start < end) {
1032 pgd = pgd_offset(mm, start);
1033 pmd = pmd_offset(pgd, start);
1034 pte = pte_offset(pmd, start);
1035
1036 if(pte_val(*pte) & _PAGE_VALID)
1037 blast_scache128_page(start);
1038 start += PAGE_SIZE;
1039 }
1040 local_irq_restore(flags);
1041 }
1042 }
1043}
1044
1045static void r4k_flush_cache_range_d16i16(struct vm_area_struct *vma,
1046 unsigned long start,
1047 unsigned long end)
1048{
1049 struct mm_struct *mm = vma->vm_mm;
1050
1051 if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
1052 unsigned long flags;
1053
1054#ifdef DEBUG_CACHE
1055 printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
1056#endif
1057 local_irq_save(flags);
1058 blast_dcache16(); blast_icache16();
1059 local_irq_restore(flags);
1060 }
1061}
1062
1063static void r4k_flush_cache_range_d32i32(struct vm_area_struct *vma,
1064 unsigned long start,
1065 unsigned long end)
1066{
1067 struct mm_struct *mm = vma->vm_mm;
1068
1069 if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
1070 unsigned long flags;
1071
1072#ifdef DEBUG_CACHE
1073 printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
1074#endif
1075 local_irq_save(flags);
1076 blast_dcache32(); blast_icache32();
1077 local_irq_restore(flags);
1078 }
1079}
1080
1081
1082
1083
1084
1085
1086static void r4k_flush_cache_mm_s16d16i16(struct mm_struct *mm)
1087{
1088 if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
1089#ifdef DEBUG_CACHE
1090 printk("cmm[%d]", (int)mm->context);
1091#endif
1092 r4k_flush_cache_all_s16d16i16();
1093 }
1094}
1095
1096static void r4k_flush_cache_mm_s32d16i16(struct mm_struct *mm)
1097{
1098 if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
1099#ifdef DEBUG_CACHE
1100 printk("cmm[%d]", (int)mm->context);
1101#endif
1102 r4k_flush_cache_all_s32d16i16();
1103 }
1104}
1105
1106static void r4k_flush_cache_mm_s64d16i16(struct mm_struct *mm)
1107{
1108 if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
1109#ifdef DEBUG_CACHE
1110 printk("cmm[%d]", (int)mm->context);
1111#endif
1112 r4k_flush_cache_all_s64d16i16();
1113 }
1114}
1115
1116static void r4k_flush_cache_mm_s128d16i16(struct mm_struct *mm)
1117{
1118 if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
1119#ifdef DEBUG_CACHE
1120 printk("cmm[%d]", (int)mm->context);
1121#endif
1122 r4k_flush_cache_all_s128d16i16();
1123 }
1124}
1125
1126static void r4k_flush_cache_mm_s32d32i32(struct mm_struct *mm)
1127{
1128 if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
1129#ifdef DEBUG_CACHE
1130 printk("cmm[%d]", (int)mm->context);
1131#endif
1132 r4k_flush_cache_all_s32d32i32();
1133 }
1134}
1135
1136static void r4k_flush_cache_mm_s64d32i32(struct mm_struct *mm)
1137{
1138 if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
1139#ifdef DEBUG_CACHE
1140 printk("cmm[%d]", (int)mm->context);
1141#endif
1142 r4k_flush_cache_all_s64d32i32();
1143 }
1144}
1145
1146static void r4k_flush_cache_mm_s128d32i32(struct mm_struct *mm)
1147{
1148 if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
1149#ifdef DEBUG_CACHE
1150 printk("cmm[%d]", (int)mm->context);
1151#endif
1152 r4k_flush_cache_all_s128d32i32();
1153 }
1154}
1155
1156static void r4k_flush_cache_mm_d16i16(struct mm_struct *mm)
1157{
1158 if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
1159#ifdef DEBUG_CACHE
1160 printk("cmm[%d]", (int)mm->context);
1161#endif
1162 r4k_flush_cache_all_d16i16();
1163 }
1164}
1165
1166static void r4k_flush_cache_mm_d32i32(struct mm_struct *mm)
1167{
1168 if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
1169#ifdef DEBUG_CACHE
1170 printk("cmm[%d]", (int)mm->context);
1171#endif
1172 r4k_flush_cache_all_d32i32();
1173 }
1174}
1175
1176static void r4k_flush_cache_page_s16d16i16(struct vm_area_struct *vma,
1177 unsigned long page)
1178{
1179 struct mm_struct *mm = vma->vm_mm;
1180 unsigned long flags;
1181 pgd_t *pgdp;
1182 pmd_t *pmdp;
1183 pte_t *ptep;
1184
1185
1186
1187
1188
1189 if (CPU_CONTEXT(smp_processor_id(), mm) == 0)
1190 return;
1191
1192#ifdef DEBUG_CACHE
1193 printk("cpage[%d,%08lx]", (int)mm->context, page);
1194#endif
1195 local_irq_save(flags);
1196 page &= PAGE_MASK;
1197 pgdp = pgd_offset(mm, page);
1198 pmdp = pmd_offset(pgdp, page);
1199 ptep = pte_offset(pmdp, page);
1200
1201
1202
1203
1204
1205 if(!(pte_val(*ptep) & _PAGE_VALID))
1206 goto out;
1207
1208
1209
1210
1211
1212
1213 if (CPU_CONTEXT(smp_processor_id(), mm) !=
1214 CPU_CONTEXT(smp_processor_id(), current->mm)) {
1215
1216
1217
1218 page = (KSEG0 + (page & (scache_size - 1)));
1219 blast_dcache16_page_indexed(page);
1220 blast_scache16_page_indexed(page);
1221 } else
1222 blast_scache16_page(page);
1223out:
1224 local_irq_restore(flags);
1225}
1226
1227static void r4k_flush_cache_page_s32d16i16(struct vm_area_struct *vma,
1228 unsigned long page)
1229{
1230 struct mm_struct *mm = vma->vm_mm;
1231 unsigned long flags;
1232 pgd_t *pgdp;
1233 pmd_t *pmdp;
1234 pte_t *ptep;
1235
1236
1237
1238
1239
1240 if (CPU_CONTEXT(smp_processor_id(), mm) == 0)
1241 return;
1242
1243#ifdef DEBUG_CACHE
1244 printk("cpage[%d,%08lx]", (int)mm->context, page);
1245#endif
1246 local_irq_save(flags);
1247 page &= PAGE_MASK;
1248 pgdp = pgd_offset(mm, page);
1249 pmdp = pmd_offset(pgdp, page);
1250 ptep = pte_offset(pmdp, page);
1251
1252
1253
1254
1255 if(!(pte_val(*ptep) & _PAGE_VALID))
1256 goto out;
1257
1258
1259
1260
1261
1262
1263 if (CPU_CONTEXT(smp_processor_id(), mm) !=
1264 CPU_CONTEXT(smp_processor_id(), current->mm)) {
1265
1266
1267
1268 page = (KSEG0 + (page & (scache_size - 1)));
1269 blast_dcache16_page_indexed(page);
1270 blast_scache32_page_indexed(page);
1271 } else
1272 blast_scache32_page(page);
1273out:
1274 local_irq_restore(flags);
1275}
1276
1277static void r4k_flush_cache_page_s64d16i16(struct vm_area_struct *vma,
1278 unsigned long page)
1279{
1280 struct mm_struct *mm = vma->vm_mm;
1281 unsigned long flags;
1282 pgd_t *pgdp;
1283 pmd_t *pmdp;
1284 pte_t *ptep;
1285
1286
1287
1288
1289
1290 if (CPU_CONTEXT(smp_processor_id(), mm) == 0)
1291 return;
1292
1293#ifdef DEBUG_CACHE
1294 printk("cpage[%d,%08lx]", (int)mm->context, page);
1295#endif
1296 local_irq_save(flags);
1297 page &= PAGE_MASK;
1298 pgdp = pgd_offset(mm, page);
1299 pmdp = pmd_offset(pgdp, page);
1300 ptep = pte_offset(pmdp, page);
1301
1302
1303
1304
1305 if(!(pte_val(*ptep) & _PAGE_VALID))
1306 goto out;
1307
1308
1309
1310
1311
1312
1313
1314 if (CPU_CONTEXT(smp_processor_id(), mm) !=
1315 CPU_CONTEXT(smp_processor_id(), current->mm)) {
1316
1317
1318
1319 page = (KSEG0 + (page & (scache_size - 1)));
1320 blast_dcache16_page_indexed(page);
1321 blast_scache64_page_indexed(page);
1322 } else
1323 blast_scache64_page(page);
1324out:
1325 local_irq_restore(flags);
1326}
1327
1328static void r4k_flush_cache_page_s128d16i16(struct vm_area_struct *vma,
1329 unsigned long page)
1330{
1331 struct mm_struct *mm = vma->vm_mm;
1332 unsigned long flags;
1333 pgd_t *pgdp;
1334 pmd_t *pmdp;
1335 pte_t *ptep;
1336
1337
1338
1339
1340
1341 if (CPU_CONTEXT(smp_processor_id(), mm) == 0)
1342 return;
1343
1344#ifdef DEBUG_CACHE
1345 printk("cpage[%d,%08lx]", (int)mm->context, page);
1346#endif
1347 local_irq_save(flags);
1348 page &= PAGE_MASK;
1349 pgdp = pgd_offset(mm, page);
1350 pmdp = pmd_offset(pgdp, page);
1351 ptep = pte_offset(pmdp, page);
1352
1353
1354
1355
1356
1357 if(!(pte_val(*ptep) & _PAGE_VALID))
1358 goto out;
1359
1360
1361
1362
1363
1364
1365 if (CPU_CONTEXT(smp_processor_id(), mm) !=
1366 CPU_CONTEXT(smp_processor_id(), current->mm)) {
1367
1368
1369
1370
1371 page = (KSEG0 + (page & (scache_size - 1)));
1372 blast_dcache16_page_indexed(page);
1373 blast_scache128_page_indexed(page);
1374 } else
1375 blast_scache128_page(page);
1376out:
1377 local_irq_restore(flags);
1378}
1379
1380static void r4k_flush_cache_page_s32d32i32(struct vm_area_struct *vma,
1381 unsigned long page)
1382{
1383 struct mm_struct *mm = vma->vm_mm;
1384 unsigned long flags;
1385 pgd_t *pgdp;
1386 pmd_t *pmdp;
1387 pte_t *ptep;
1388
1389
1390
1391
1392
1393 if (CPU_CONTEXT(smp_processor_id(), mm) == 0)
1394 return;
1395
1396#ifdef DEBUG_CACHE
1397 printk("cpage[%d,%08lx]", (int)mm->context, page);
1398#endif
1399 local_irq_save(flags);
1400 page &= PAGE_MASK;
1401 pgdp = pgd_offset(mm, page);
1402 pmdp = pmd_offset(pgdp, page);
1403 ptep = pte_offset(pmdp, page);
1404
1405
1406
1407
1408
1409 if(!(pte_val(*ptep) & _PAGE_VALID))
1410 goto out;
1411
1412
1413
1414
1415
1416
1417
1418 if (CPU_CONTEXT(smp_processor_id(), mm) !=
1419 CPU_CONTEXT(smp_processor_id(), current->mm)) {
1420
1421
1422
1423
1424 page = (KSEG0 + (page & (scache_size - 1)));
1425 blast_dcache32_page_indexed(page);
1426 blast_scache32_page_indexed(page);
1427 } else
1428 blast_scache32_page(page);
1429out:
1430 local_irq_restore(flags);
1431}
1432
1433static void r4k_flush_cache_page_s64d32i32(struct vm_area_struct *vma,
1434 unsigned long page)
1435{
1436 struct mm_struct *mm = vma->vm_mm;
1437 unsigned long flags;
1438 pgd_t *pgdp;
1439 pmd_t *pmdp;
1440 pte_t *ptep;
1441
1442
1443
1444
1445
1446 if (CPU_CONTEXT(smp_processor_id(), mm) == 0)
1447 return;
1448
1449#ifdef DEBUG_CACHE
1450 printk("cpage[%d,%08lx]", (int)mm->context, page);
1451#endif
1452 local_irq_save(flags);
1453 page &= PAGE_MASK;
1454 pgdp = pgd_offset(mm, page);
1455 pmdp = pmd_offset(pgdp, page);
1456 ptep = pte_offset(pmdp, page);
1457
1458
1459
1460
1461
1462 if(!(pte_val(*ptep) & _PAGE_VALID))
1463 goto out;
1464
1465
1466
1467
1468
1469
1470
1471 if (CPU_CONTEXT(smp_processor_id(), mm) !=
1472 CPU_CONTEXT(smp_processor_id(), current->mm)) {
1473
1474
1475
1476
1477 page = (KSEG0 + (page & (scache_size - 1)));
1478 blast_dcache32_page_indexed(page);
1479 blast_scache64_page_indexed(page);
1480 } else
1481 blast_scache64_page(page);
1482out:
1483 local_irq_restore(flags);
1484}
1485
1486static void r4k_flush_cache_page_s128d32i32(struct vm_area_struct *vma,
1487 unsigned long page)
1488{
1489 struct mm_struct *mm = vma->vm_mm;
1490 unsigned long flags;
1491 pgd_t *pgdp;
1492 pmd_t *pmdp;
1493 pte_t *ptep;
1494
1495
1496
1497
1498
1499 if (CPU_CONTEXT(smp_processor_id(), mm) == 0)
1500 return;
1501
1502#ifdef DEBUG_CACHE
1503 printk("cpage[%d,%08lx]", (int)mm->context, page);
1504#endif
1505 local_irq_save(flags);
1506 page &= PAGE_MASK;
1507 pgdp = pgd_offset(mm, page);
1508 pmdp = pmd_offset(pgdp, page);
1509 ptep = pte_offset(pmdp, page);
1510
1511
1512
1513
1514 if(!(pte_val(*ptep) & _PAGE_VALID))
1515 goto out;
1516
1517
1518
1519
1520
1521
1522
1523 if (CPU_CONTEXT(smp_processor_id(), mm) !=
1524 CPU_CONTEXT(smp_processor_id(), current->mm)) {
1525
1526
1527
1528 page = (KSEG0 + (page & (scache_size - 1)));
1529 blast_dcache32_page_indexed(page);
1530 blast_scache128_page_indexed(page);
1531 } else
1532 blast_scache128_page(page);
1533out:
1534 local_irq_restore(flags);
1535}
1536
1537static void r4k_flush_cache_page_d16i16(struct vm_area_struct *vma,
1538 unsigned long page)
1539{
1540 struct mm_struct *mm = vma->vm_mm;
1541 unsigned long flags;
1542 pgd_t *pgdp;
1543 pmd_t *pmdp;
1544 pte_t *ptep;
1545
1546
1547
1548
1549
1550 if (CPU_CONTEXT(smp_processor_id(), mm) == 0)
1551 return;
1552
1553#ifdef DEBUG_CACHE
1554 printk("cpage[%d,%08lx]", (int)mm->context, page);
1555#endif
1556 local_irq_save(flags);
1557 page &= PAGE_MASK;
1558 pgdp = pgd_offset(mm, page);
1559 pmdp = pmd_offset(pgdp, page);
1560 ptep = pte_offset(pmdp, page);
1561
1562
1563
1564
1565 if(!(pte_val(*ptep) & _PAGE_VALID))
1566 goto out;
1567
1568
1569
1570
1571
1572
1573
1574 if(mm == current->mm) {
1575 blast_dcache16_page(page);
1576 } else {
1577
1578
1579
1580 page = (KSEG0 + (page & (dcache_size - 1)));
1581 blast_dcache16_page_indexed(page);
1582 }
1583out:
1584 local_irq_restore(flags);
1585}
1586
1587static void r4k_flush_cache_page_d32i32(struct vm_area_struct *vma,
1588 unsigned long page)
1589{
1590 struct mm_struct *mm = vma->vm_mm;
1591 unsigned long flags;
1592 pgd_t *pgdp;
1593 pmd_t *pmdp;
1594 pte_t *ptep;
1595
1596
1597
1598
1599
1600 if (CPU_CONTEXT(smp_processor_id(), mm) == 0)
1601 return;
1602
1603#ifdef DEBUG_CACHE
1604 printk("cpage[%d,%08lx]", (int)mm->context, page);
1605#endif
1606 local_irq_save(flags);
1607 page &= PAGE_MASK;
1608 pgdp = pgd_offset(mm, page);
1609 pmdp = pmd_offset(pgdp, page);
1610 ptep = pte_offset(pmdp, page);
1611
1612
1613
1614
1615
1616 if(!(pte_val(*ptep) & _PAGE_PRESENT))
1617 goto out;
1618
1619
1620
1621
1622
1623
1624
1625 if((mm == current->mm) && (pte_val(*ptep) & _PAGE_VALID)) {
1626 blast_dcache32_page(page);
1627 } else {
1628
1629
1630
1631
1632 page = (KSEG0 + (page & (dcache_size - 1)));
1633 blast_dcache32_page_indexed(page);
1634 }
1635out:
1636 local_irq_restore(flags);
1637}
1638
1639static void r4k_flush_cache_page_d32i32_r4600(struct vm_area_struct *vma,
1640 unsigned long page)
1641{
1642 struct mm_struct *mm = vma->vm_mm;
1643 unsigned long flags;
1644 pgd_t *pgdp;
1645 pmd_t *pmdp;
1646 pte_t *ptep;
1647
1648
1649
1650
1651
1652 if (CPU_CONTEXT(smp_processor_id(), mm) == 0)
1653 return;
1654
1655#ifdef DEBUG_CACHE
1656 printk("cpage[%d,%08lx]", (int)mm->context, page);
1657#endif
1658 local_irq_save(flags);
1659 page &= PAGE_MASK;
1660 pgdp = pgd_offset(mm, page);
1661 pmdp = pmd_offset(pgdp, page);
1662 ptep = pte_offset(pmdp, page);
1663
1664
1665
1666
1667
1668 if(!(pte_val(*ptep) & _PAGE_PRESENT))
1669 goto out;
1670
1671
1672
1673
1674
1675
1676
1677 if((mm == current->mm) && (pte_val(*ptep) & _PAGE_VALID)) {
1678 blast_dcache32_page(page);
1679 } else {
1680
1681
1682
1683 page = (KSEG0 + (page & (dcache_size - 1)));
1684 blast_dcache32_page_indexed(page);
1685 blast_dcache32_page_indexed(page ^ dcache_waybit);
1686 }
1687out:
1688 local_irq_restore(flags);
1689}
1690
1691static void r4k_flush_page_to_ram_s16(struct page *page)
1692{
1693 blast_scache16_page((unsigned long)page_address(page));
1694}
1695
1696static void r4k_flush_page_to_ram_s32(struct page *page)
1697{
1698 blast_scache32_page((unsigned long)page_address(page));
1699}
1700
1701static void r4k_flush_page_to_ram_s64(struct page *page)
1702{
1703 blast_scache64_page((unsigned long)page_address(page));
1704}
1705
1706static void r4k_flush_page_to_ram_s128(struct page *page)
1707{
1708 blast_scache128_page((unsigned long)page_address(page));
1709}
1710
1711static void r4k_flush_page_to_ram_d16(struct page *page)
1712{
1713 unsigned long flags;
1714
1715 local_irq_save(flags);
1716 blast_dcache16_page((unsigned long)page_address(page));
1717 local_irq_restore(flags);
1718}
1719
1720static void r4k_flush_page_to_ram_d32(struct page *page)
1721{
1722 unsigned long flags;
1723
1724 local_irq_save(flags);
1725 blast_dcache32_page((unsigned long)page_address(page));
1726 local_irq_restore(flags);
1727}
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740static void r4k_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size)
1741{
1742 unsigned long end, a;
1743 unsigned int flags;
1744
1745 if (size >= (unsigned long)dcache_size) {
1746 flush_cache_l1();
1747 } else {
1748
1749 local_irq_save(flags);
1750 *(volatile unsigned long *)KSEG1;
1751
1752 a = addr & ~((unsigned long)dc_lsize - 1);
1753 end = (addr + size) & ~((unsigned long)dc_lsize - 1);
1754 while (1) {
1755 flush_dcache_line(a);
1756 if (a == end) break;
1757 a += dc_lsize;
1758 }
1759 local_irq_restore(flags);
1760 }
1761 bc_wback_inv(addr, size);
1762}
1763
1764static void r4k_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size)
1765{
1766 unsigned long end, a;
1767
1768 if (size >= (unsigned long)scache_size) {
1769 flush_cache_l1();
1770 return;
1771 }
1772
1773 a = addr & ~((unsigned long)sc_lsize - 1);
1774 end = (addr + size) & ~((unsigned long)sc_lsize - 1);
1775 while (1) {
1776 flush_scache_line(a);
1777 if (a == end) break;
1778 a += sc_lsize;
1779 }
1780}
1781
1782static void r4k_dma_cache_inv_pc(unsigned long addr, unsigned long size)
1783{
1784 unsigned long end, a;
1785 unsigned int flags;
1786
1787 if (size >= (unsigned long)dcache_size) {
1788 flush_cache_l1();
1789 } else {
1790
1791 local_irq_save(flags);
1792 *(volatile unsigned long *)KSEG1;
1793
1794 a = addr & ~((unsigned long)dc_lsize - 1);
1795 end = (addr + size) & ~((unsigned long)dc_lsize - 1);
1796 while (1) {
1797 flush_dcache_line(a);
1798 if (a == end) break;
1799 a += dc_lsize;
1800 }
1801 local_irq_restore(flags);
1802 }
1803
1804 bc_inv(addr, size);
1805}
1806
1807static void r4k_dma_cache_inv_sc(unsigned long addr, unsigned long size)
1808{
1809 unsigned long end, a;
1810
1811 if (size >= (unsigned long)scache_size) {
1812 flush_cache_l1();
1813 return;
1814 }
1815
1816 a = addr & ~((unsigned long)sc_lsize - 1);
1817 end = (addr + size) & ~((unsigned long)sc_lsize - 1);
1818 while (1) {
1819 flush_scache_line(a);
1820 if (a == end) break;
1821 a += sc_lsize;
1822 }
1823}
1824
1825static void r4k_dma_cache_wback(unsigned long addr, unsigned long size)
1826{
1827 panic("r4k_dma_cache called - should not happen.\n");
1828}
1829
1830
1831
1832
1833
1834
1835static void r4k_flush_cache_sigtramp(unsigned long addr)
1836{
1837 __asm__ __volatile__("nop;nop;nop;nop");
1838
1839 protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
1840 protected_flush_icache_line(addr & ~(ic_lsize - 1));
1841}
1842
1843static void r4600v20k_flush_cache_sigtramp(unsigned long addr)
1844{
1845 unsigned int flags;
1846
1847 local_irq_save(flags);
1848
1849
1850 *(volatile unsigned int *)KSEG1;
1851
1852 protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
1853 protected_flush_icache_line(addr & ~(ic_lsize - 1));
1854
1855 local_irq_restore(flags);
1856}
1857
1858#undef DEBUG_TLB
1859
1860#define NTLB_ENTRIES 48
1861
1862#define NTLB_ENTRIES_HALF 24
1863
1864static inline void r4k_flush_tlb_all(void)
1865{
1866 unsigned long flags;
1867 unsigned long old_ctx;
1868 int entry;
1869
1870#ifdef DEBUG_TLB
1871 printk("[tlball]");
1872#endif
1873
1874 local_irq_save(flags);
1875
1876 old_ctx = (get_entryhi() & 0xff);
1877 set_entryhi(KSEG0);
1878 set_entrylo0(0);
1879 set_entrylo1(0);
1880 BARRIER;
1881
1882 entry = get_wired();
1883
1884
1885 while(entry < NTLB_ENTRIES) {
1886 set_index(entry);
1887 BARRIER;
1888 tlb_write_indexed();
1889 BARRIER;
1890 entry++;
1891 }
1892 BARRIER;
1893 set_entryhi(old_ctx);
1894 local_irq_restore(flags);
1895}
1896
1897static void r4k_flush_tlb_mm(struct mm_struct *mm)
1898{
1899 if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
1900 unsigned long flags;
1901
1902#ifdef DEBUG_TLB
1903 printk("[tlbmm<%d>]", mm->context);
1904#endif
1905 local_irq_save(flags);
1906 get_new_cpu_mmu_context(mm, smp_processor_id());
1907 if(mm == current->mm)
1908 set_entryhi(CPU_CONTEXT(smp_processor_id(), mm) & 0xff);
1909 local_irq_restore(flags);
1910 }
1911}
1912
1913static void r4k_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
1914 unsigned long end)
1915{
1916 struct mm_struct *mm = vma->vm_mm;
1917
1918 if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
1919 unsigned long flags;
1920 int size;
1921
1922#ifdef DEBUG_TLB
1923 printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff),
1924 start, end);
1925#endif
1926 local_irq_save(flags);
1927 size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
1928 size = (size + 1) >> 1;
1929 if(size <= NTLB_ENTRIES_HALF) {
1930 int oldpid = (get_entryhi() & 0xff);
1931 int newpid = (CPU_CONTEXT(smp_processor_id(), mm) & 0xff);
1932
1933 start &= (PAGE_MASK << 1);
1934 end += ((PAGE_SIZE << 1) - 1);
1935 end &= (PAGE_MASK << 1);
1936 while(start < end) {
1937 int idx;
1938
1939 set_entryhi(start | newpid);
1940 start += (PAGE_SIZE << 1);
1941 BARRIER;
1942 tlb_probe();
1943 BARRIER;
1944 idx = get_index();
1945 set_entrylo0(0);
1946 set_entrylo1(0);
1947 set_entryhi(KSEG0);
1948 BARRIER;
1949 if(idx < 0)
1950 continue;
1951 tlb_write_indexed();
1952 BARRIER;
1953 }
1954 set_entryhi(oldpid);
1955 } else {
1956 get_new_cpu_mmu_context(mm, smp_processor_id());
1957 if(mm == current->mm)
1958 set_entryhi(CPU_CONTEXT(smp_processor_id(),
1959 mm) & 0xff);
1960 }
1961 local_irq_restore(flags);
1962 }
1963}
1964
1965static void r4k_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
1966{
1967 if (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) != 0) {
1968 unsigned long flags;
1969 int oldpid, newpid, idx;
1970
1971#ifdef DEBUG_TLB
1972 printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page);
1973#endif
1974 newpid = (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & 0xff);
1975 page &= (PAGE_MASK << 1);
1976 local_irq_save(flags);
1977 oldpid = (get_entryhi() & 0xff);
1978 set_entryhi(page | newpid);
1979 BARRIER;
1980 tlb_probe();
1981 BARRIER;
1982 idx = get_index();
1983 set_entrylo0(0);
1984 set_entrylo1(0);
1985 set_entryhi(KSEG0);
1986 if(idx < 0)
1987 goto finish;
1988 BARRIER;
1989 tlb_write_indexed();
1990
1991 finish:
1992 BARRIER;
1993 set_entryhi(oldpid);
1994 local_irq_restore(flags);
1995 }
1996}
1997
1998static void r4k_flush_cache_l2(void)
1999{
2000}
2001
2002
2003
2004
2005
2006static void r4k_update_mmu_cache(struct vm_area_struct * vma,
2007 unsigned long address, pte_t pte)
2008{
2009 unsigned long flags;
2010 pgd_t *pgdp;
2011 pmd_t *pmdp;
2012 pte_t *ptep;
2013 int idx, pid;
2014
2015
2016
2017
2018 if (current->active_mm != vma->vm_mm)
2019 return;
2020
2021 local_irq_save(flags);
2022 pid = (get_entryhi() & 0xff);
2023
2024#ifdef DEBUG_TLB
2025 if((pid != (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & 0xff)) ||
2026 (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) == 0)) {
2027 printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d
2028 tlbpid=%d\n", (int) (CPU_CONTEXT(smp_processor_id(),
2029 vma->vm_mm) & 0xff), pid);
2030 }
2031#endif
2032
2033 address &= (PAGE_MASK << 1);
2034 set_entryhi(address | (pid));
2035 pgdp = pgd_offset(vma->vm_mm, address);
2036 BARRIER;
2037 tlb_probe();
2038 BARRIER;
2039 pmdp = pmd_offset(pgdp, address);
2040 idx = get_index();
2041 ptep = pte_offset(pmdp, address);
2042 BARRIER;
2043 set_entrylo0(pte_val(*ptep++) >> 6);
2044 set_entrylo1(pte_val(*ptep) >> 6);
2045 set_entryhi(address | (pid));
2046 BARRIER;
2047 if(idx < 0) {
2048 tlb_write_random();
2049 } else {
2050 tlb_write_indexed();
2051 }
2052 BARRIER;
2053 set_entryhi(pid);
2054 BARRIER;
2055 local_irq_restore(flags);
2056}
2057
2058#if 0
2059static void r4k_update_mmu_cache_hwbug(struct vm_area_struct * vma,
2060 unsigned long address, pte_t pte)
2061{
2062 unsigned long flags;
2063 pgd_t *pgdp;
2064 pmd_t *pmdp;
2065 pte_t *ptep;
2066 int idx;
2067
2068 local_irq_save(flags);
2069 address &= (PAGE_MASK << 1);
2070 set_entryhi(address | (get_entryhi() & 0xff));
2071 pgdp = pgd_offset(vma->vm_mm, address);
2072 tlb_probe();
2073 pmdp = pmd_offset(pgdp, address);
2074 idx = get_index();
2075 ptep = pte_offset(pmdp, address);
2076 set_entrylo0(pte_val(*ptep++) >> 6);
2077 set_entrylo1(pte_val(*ptep) >> 6);
2078 BARRIER;
2079 if(idx < 0)
2080 tlb_write_random();
2081 else
2082 tlb_write_indexed();
2083 BARRIER;
2084 local_irq_restore(flags);
2085}
2086#endif
2087
2088static void r4k_show_regs(struct pt_regs *regs)
2089{
2090
2091 printk("$0 : %016lx %016lx %016lx %016lx\n",
2092 0UL, regs->regs[1], regs->regs[2], regs->regs[3]);
2093 printk("$4 : %016lx %016lx %016lx %016lx\n",
2094 regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
2095 printk("$8 : %016lx %016lx %016lx %016lx\n",
2096 regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]);
2097 printk("$12 : %016lx %016lx %016lx %016lx\n",
2098 regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);
2099 printk("$16 : %016lx %016lx %016lx %016lx\n",
2100 regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]);
2101 printk("$20 : %016lx %016lx %016lx %016lx\n",
2102 regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);
2103 printk("$24 : %016lx %016lx\n",
2104 regs->regs[24], regs->regs[25]);
2105 printk("$28 : %016lx %016lx %016lx %016lx\n",
2106 regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
2107 printk("Hi : %016lx\n", regs->hi);
2108 printk("Lo : %016lx\n", regs->lo);
2109
2110
2111 printk("epc : %016lx %s\nbadvaddr: %016lx\n",
2112 regs->cp0_epc, print_tainted(), regs->cp0_badvaddr);
2113 printk("Status : %08x\nCause : %08x\n",
2114 (unsigned int) regs->cp0_status, (unsigned int) regs->cp0_cause);
2115}
2116
2117
2118static void __init probe_icache(unsigned long config)
2119{
2120 icache_size = 1 << (12 + ((config >> 9) & 7));
2121 ic_lsize = 16 << ((config >> 5) & 1);
2122
2123 printk("Primary instruction cache %dkb, linesize %d bytes)\n",
2124 icache_size >> 10, ic_lsize);
2125}
2126
2127static void __init probe_dcache(unsigned long config)
2128{
2129 dcache_size = 1 << (12 + ((config >> 6) & 7));
2130 dc_lsize = 16 << ((config >> 4) & 1);
2131
2132 printk("Primary data cache %dkb, linesize %d bytes)\n",
2133 dcache_size >> 10, dc_lsize);
2134}
2135
2136
2137
2138
2139
2140
2141
2142static int __init probe_scache(unsigned long config)
2143{
2144 extern unsigned long stext;
2145 unsigned long flags, addr, begin, end, pow2;
2146 int tmp;
2147
2148 tmp = ((config >> 17) & 1);
2149 if(tmp)
2150 return 0;
2151 tmp = ((config >> 22) & 3);
2152 switch(tmp) {
2153 case 0:
2154 sc_lsize = 16;
2155 break;
2156 case 1:
2157 sc_lsize = 32;
2158 break;
2159 case 2:
2160 sc_lsize = 64;
2161 break;
2162 case 3:
2163 sc_lsize = 128;
2164 break;
2165 }
2166
2167 begin = (unsigned long) &stext;
2168 begin &= ~((4 * 1024 * 1024) - 1);
2169 end = begin + (4 * 1024 * 1024);
2170
2171
2172
2173
2174 local_irq_save(flags);
2175
2176
2177 pow2 = (64 * 1024);
2178 for(addr = begin; addr < end; addr = (begin + pow2)) {
2179 unsigned long *p = (unsigned long *) addr;
2180 __asm__ __volatile__("nop" : : "r" (*p));
2181 pow2 <<= 1;
2182 }
2183
2184
2185 set_taglo(0);
2186 set_taghi(0);
2187 __asm__ __volatile__("nop; nop; nop; nop;");
2188 __asm__ __volatile__("\n\t.set noreorder\n\t"
2189 "cache 8, (%0)\n\t"
2190 ".set reorder\n\t" : : "r" (begin));
2191 __asm__ __volatile__("\n\t.set noreorder\n\t"
2192 "cache 9, (%0)\n\t"
2193 ".set reorder\n\t" : : "r" (begin));
2194 __asm__ __volatile__("\n\t.set noreorder\n\t"
2195 "cache 11, (%0)\n\t"
2196 ".set reorder\n\t" : : "r" (begin));
2197
2198
2199 pow2 = (128 * 1024);
2200 tmp = 0;
2201 for(addr = (begin + (128 * 1024)); addr < (end); addr = (begin + pow2)) {
2202 __asm__ __volatile__("\n\t.set noreorder\n\t"
2203 "cache 7, (%0)\n\t"
2204 ".set reorder\n\t" : : "r" (addr));
2205 __asm__ __volatile__("nop; nop; nop; nop;");
2206 if(!get_taglo())
2207 break;
2208 pow2 <<= 1;
2209 }
2210 local_irq_restore(flags);
2211 addr -= begin;
2212 printk("Secondary cache sized at %dK linesize %d\n",
2213 (int) (addr >> 10), sc_lsize);
2214 scache_size = addr;
2215 return 1;
2216}
2217
2218static void __init setup_noscache_funcs(void)
2219{
2220 unsigned int prid;
2221
2222 switch(dc_lsize) {
2223 case 16:
2224 _clear_page = r4k_clear_page_d16;
2225 _copy_page = r4k_copy_page_d16;
2226 _flush_cache_l1 = r4k_flush_cache_all_d16i16;
2227 _flush_cache_mm = r4k_flush_cache_mm_d16i16;
2228 _flush_cache_range = r4k_flush_cache_range_d16i16;
2229 _flush_cache_page = r4k_flush_cache_page_d16i16;
2230 break;
2231 case 32:
2232 prid = read_32bit_cp0_register(CP0_PRID) & 0xfff0;
2233 if (prid == 0x2010) {
2234 _clear_page = r4k_clear_page_r4600_v1;
2235 _copy_page = r4k_copy_page_r4600_v1;
2236 } else if (prid == 0x2020) {
2237 _clear_page = r4k_clear_page_r4600_v2;
2238 _copy_page = r4k_copy_page_r4600_v2;
2239 } else {
2240 _clear_page = r4k_clear_page_d32;
2241 _copy_page = r4k_copy_page_d32;
2242 }
2243 _flush_cache_l1 = r4k_flush_cache_all_d32i32;
2244 _flush_cache_mm = r4k_flush_cache_mm_d32i32;
2245 _flush_cache_range = r4k_flush_cache_range_d32i32;
2246 _flush_cache_page = r4k_flush_cache_page_d32i32;
2247 break;
2248 }
2249
2250 switch(ic_lsize) {
2251 case 16:
2252 _flush_page_to_ram = r4k_flush_page_to_ram_d16;
2253 break;
2254 case 32:
2255 _flush_page_to_ram = r4k_flush_page_to_ram_d32;
2256 break;
2257 }
2258
2259 _dma_cache_wback_inv = r4k_dma_cache_wback_inv_pc;
2260 _dma_cache_wback = r4k_dma_cache_wback;
2261 _dma_cache_inv = r4k_dma_cache_inv_pc;
2262}
2263
2264static void __init setup_scache_funcs(void)
2265{
2266 switch(sc_lsize) {
2267 case 16:
2268 switch(dc_lsize) {
2269 case 16:
2270 _flush_cache_l1 = r4k_flush_cache_all_s16d16i16;
2271 _flush_cache_mm = r4k_flush_cache_mm_s16d16i16;
2272 _flush_cache_range = r4k_flush_cache_range_s16d16i16;
2273 _flush_cache_page = r4k_flush_cache_page_s16d16i16;
2274 break;
2275 case 32:
2276 panic("Invalid cache configuration detected");
2277 };
2278 _flush_page_to_ram = r4k_flush_page_to_ram_s16;
2279 _clear_page = r4k_clear_page_s16;
2280 _copy_page = r4k_copy_page_s16;
2281 break;
2282 case 32:
2283 switch(dc_lsize) {
2284 case 16:
2285 _flush_cache_l1 = r4k_flush_cache_all_s32d16i16;
2286 _flush_cache_mm = r4k_flush_cache_mm_s32d16i16;
2287 _flush_cache_range = r4k_flush_cache_range_s32d16i16;
2288 _flush_cache_page = r4k_flush_cache_page_s32d16i16;
2289 break;
2290 case 32:
2291 _flush_cache_l1 = r4k_flush_cache_all_s32d32i32;
2292 _flush_cache_mm = r4k_flush_cache_mm_s32d32i32;
2293 _flush_cache_range = r4k_flush_cache_range_s32d32i32;
2294 _flush_cache_page = r4k_flush_cache_page_s32d32i32;
2295 break;
2296 };
2297 _flush_page_to_ram = r4k_flush_page_to_ram_s32;
2298 _clear_page = r4k_clear_page_s32;
2299 _copy_page = r4k_copy_page_s32;
2300 break;
2301 case 64:
2302 switch(dc_lsize) {
2303 case 16:
2304 _flush_cache_l1 = r4k_flush_cache_all_s64d16i16;
2305 _flush_cache_mm = r4k_flush_cache_mm_s64d16i16;
2306 _flush_cache_range = r4k_flush_cache_range_s64d16i16;
2307 _flush_cache_page = r4k_flush_cache_page_s64d16i16;
2308 break;
2309 case 32:
2310 _flush_cache_l1 = r4k_flush_cache_all_s64d32i32;
2311 _flush_cache_mm = r4k_flush_cache_mm_s64d32i32;
2312 _flush_cache_range = r4k_flush_cache_range_s64d32i32;
2313 _flush_cache_page = r4k_flush_cache_page_s64d32i32;
2314 break;
2315 };
2316 _flush_page_to_ram = r4k_flush_page_to_ram_s64;
2317 _clear_page = r4k_clear_page_s64;
2318 _copy_page = r4k_copy_page_s64;
2319 break;
2320 case 128:
2321 switch(dc_lsize) {
2322 case 16:
2323 _flush_cache_l1 = r4k_flush_cache_all_s128d16i16;
2324 _flush_cache_mm = r4k_flush_cache_mm_s128d16i16;
2325 _flush_cache_range = r4k_flush_cache_range_s128d16i16;
2326 _flush_cache_page = r4k_flush_cache_page_s128d16i16;
2327 break;
2328 case 32:
2329 _flush_cache_l1 = r4k_flush_cache_all_s128d32i32;
2330 _flush_cache_mm = r4k_flush_cache_mm_s128d32i32;
2331 _flush_cache_range = r4k_flush_cache_range_s128d32i32;
2332 _flush_cache_page = r4k_flush_cache_page_s128d32i32;
2333 break;
2334 };
2335 _flush_page_to_ram = r4k_flush_page_to_ram_s128;
2336 _clear_page = r4k_clear_page_s128;
2337 _copy_page = r4k_copy_page_s128;
2338 break;
2339 }
2340 _dma_cache_wback_inv = r4k_dma_cache_wback_inv_sc;
2341 _dma_cache_wback = r4k_dma_cache_wback;
2342 _dma_cache_inv = r4k_dma_cache_inv_sc;
2343}
2344
2345typedef int (*probe_func_t)(unsigned long);
2346
2347static inline void __init setup_scache(unsigned int config)
2348{
2349 probe_func_t probe_scache_kseg1;
2350 int sc_present = 0;
2351
2352
2353 probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache));
2354 sc_present = probe_scache_kseg1(config);
2355
2356 if (sc_present) {
2357 setup_scache_funcs();
2358 return;
2359 }
2360
2361 setup_noscache_funcs();
2362}
2363
2364void __init ld_mmu_r4xx0(void)
2365{
2366 unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
2367
2368 printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID));
2369
2370#ifdef CONFIG_MIPS_UNCACHED
2371 set_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
2372#else
2373 set_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
2374#endif
2375
2376 probe_icache(config);
2377 probe_dcache(config);
2378 setup_scache(config);
2379
2380 switch(mips_cputype) {
2381 case CPU_R4600:
2382 case CPU_R4700:
2383 case CPU_R5000:
2384 case CPU_NEVADA:
2385 _flush_cache_page = r4k_flush_cache_page_d32i32_r4600;
2386 }
2387
2388 _flush_cache_sigtramp = r4k_flush_cache_sigtramp;
2389 if ((read_32bit_cp0_register(CP0_PRID) & 0xfff0) == 0x2020) {
2390 _flush_cache_sigtramp = r4600v20k_flush_cache_sigtramp;
2391 }
2392
2393 _flush_tlb_all = r4k_flush_tlb_all;
2394 _flush_tlb_mm = r4k_flush_tlb_mm;
2395 _flush_tlb_range = r4k_flush_tlb_range;
2396 _flush_tlb_page = r4k_flush_tlb_page;
2397 _flush_cache_l2 = r4k_flush_cache_l2;
2398
2399 update_mmu_cache = r4k_update_mmu_cache;
2400
2401 _show_regs = r4k_show_regs;
2402
2403 flush_cache_l1();
2404
2405
2406
2407
2408
2409
2410
2411
2412 write_32bit_cp0_register(CP0_PAGEMASK, PM_4K);
2413 _flush_tlb_all();
2414}
2415