13 #include <asm/cacheflush.h>
15 #include <asm/cpuinfo.h>
18 static inline void __enable_icache_msr(
void)
20 __asm__ __volatile__ (
" msrset r0, %0; \
25 static inline void __disable_icache_msr(
void)
27 __asm__ __volatile__ (
" msrclr r0, %0; \
32 static inline void __enable_dcache_msr(
void)
34 __asm__ __volatile__ (
" msrset r0, %0; \
41 static inline void __disable_dcache_msr(
void)
43 __asm__ __volatile__ (
" msrclr r0, %0; \
50 static inline void __enable_icache_nomsr(
void)
52 __asm__ __volatile__ (
" mfs r12, rmsr; \
62 static inline void __disable_icache_nomsr(
void)
64 __asm__ __volatile__ (
" mfs r12, rmsr; \
74 static inline void __enable_dcache_nomsr(
void)
76 __asm__ __volatile__ (
" mfs r12, rmsr; \
86 static inline void __disable_dcache_nomsr(
void)
88 __asm__ __volatile__ (
" mfs r12, rmsr; \
104 #define CACHE_LOOP_LIMITS(start, end, cache_line_length, cache_size) \
106 int align = ~(cache_line_length - 1); \
107 end = min(start + cache_size, end); \
115 #define CACHE_ALL_LOOP(cache_size, line_length, op) \
117 unsigned int len = cache_size - line_length; \
118 int step = -line_length; \
119 WARN_ON(step >= 0); \
121 __asm__ __volatile__ (" 1: " #op " %0, r0; \
124 " : : "r" (len), "r" (step) \
136 #define CACHE_RANGE_LOOP_2(start, end, line_length, op) \
138 int step = -line_length; \
139 int align = ~(line_length - 1); \
141 end = ((end & align) == end) ? end - line_length : end & align; \
142 count = end - start; \
143 WARN_ON(count < 0); \
145 __asm__ __volatile__ (" 1: " #op " %0, %1; \
148 " : : "r" (start), "r" (count), \
149 "r" (step) : "memory"); \
153 #define CACHE_RANGE_LOOP_1(start, end, line_length, op) \
156 int align = ~(line_length - 1); \
157 end = ((end & align) == end) ? end - line_length : end & align; \
158 WARN_ON(end - start < 0); \
160 __asm__ __volatile__ (" 1: " #op " %1, r0; \
164 " : : "r" (temp), "r" (start), "r" (end),\
165 "r" (line_length) : "memory"); \
170 static void __flush_icache_range_msr_irq(
unsigned long start,
unsigned long end)
176 pr_debug(
"%s: start 0x%x, end 0x%x\n", __func__,
177 (
unsigned int)start, (
unsigned int) end);
183 __disable_icache_msr();
189 __asm__ __volatile__ (
"wic %0, r0;" \
192 __enable_icache_msr();
196 static void __flush_icache_range_nomsr_irq(
unsigned long start,
203 pr_debug(
"%s: start 0x%x, end 0x%x\n", __func__,
204 (
unsigned int)start, (
unsigned int) end);
210 __disable_icache_nomsr();
216 __asm__ __volatile__ (
"wic %0, r0;" \
220 __enable_icache_nomsr();
224 static void __flush_icache_range_noirq(
unsigned long start,
230 pr_debug(
"%s: start 0x%x, end 0x%x\n", __func__,
231 (
unsigned int)start, (
unsigned int) end);
239 __asm__ __volatile__ (
"wic %0, r0;" \
244 static void __flush_icache_all_msr_irq(
void)
253 __disable_icache_msr();
259 __asm__ __volatile__ (
"wic %0, r0;" \
262 __enable_icache_msr();
266 static void __flush_icache_all_nomsr_irq(
void)
275 __disable_icache_nomsr();
281 __asm__ __volatile__ (
"wic %0, r0;" \
284 __enable_icache_nomsr();
288 static void __flush_icache_all_noirq(
void)
299 __asm__ __volatile__ (
"wic %0, r0;" \
304 static void __invalidate_dcache_all_msr_irq(
void)
313 __disable_dcache_msr();
319 __asm__ __volatile__ (
"wdc %0, r0;" \
322 __enable_dcache_msr();
326 static void __invalidate_dcache_all_nomsr_irq(
void)
335 __disable_dcache_nomsr();
341 __asm__ __volatile__ (
"wdc %0, r0;" \
344 __enable_dcache_nomsr();
348 static void __invalidate_dcache_all_noirq_wt(
void)
359 __asm__ __volatile__ (
"wdc %0, r0;" \
370 static void __invalidate_dcache_all_wb(
void)
382 __asm__ __volatile__ (
"wdc %0, r0;" \
387 static void __invalidate_dcache_range_wb(
unsigned long start,
393 pr_debug(
"%s: start 0x%x, end 0x%x\n", __func__,
394 (
unsigned int)start, (
unsigned int) end);
402 __asm__ __volatile__ (
"wdc.clear %0, r0;" \
407 static void __invalidate_dcache_range_nomsr_wt(
unsigned long start,
413 pr_debug(
"%s: start 0x%x, end 0x%x\n", __func__,
414 (
unsigned int)start, (
unsigned int) end);
422 __asm__ __volatile__ (
"wdc %0, r0;" \
427 static void __invalidate_dcache_range_msr_irq_wt(
unsigned long start,
434 pr_debug(
"%s: start 0x%x, end 0x%x\n", __func__,
435 (
unsigned int)start, (
unsigned int) end);
440 __disable_dcache_msr();
446 __asm__ __volatile__ (
"wdc %0, r0;" \
450 __enable_dcache_msr();
454 static void __invalidate_dcache_range_nomsr_irq(
unsigned long start,
461 pr_debug(
"%s: start 0x%x, end 0x%x\n", __func__,
462 (
unsigned int)start, (
unsigned int) end);
468 __disable_dcache_nomsr();
474 __asm__ __volatile__ (
"wdc %0, r0;" \
478 __enable_dcache_nomsr();
482 static void __flush_dcache_all_wb(
void)
494 __asm__ __volatile__ (
"wdc.flush %0, r0;" \
499 static void __flush_dcache_range_wb(
unsigned long start,
unsigned long end)
504 pr_debug(
"%s: start 0x%x, end 0x%x\n", __func__,
505 (
unsigned int)start, (
unsigned int) end);
513 __asm__ __volatile__ (
"wdc.flush %0, r0;" \
522 static const struct scache wb_msr = {
523 .ie = __enable_icache_msr,
524 .id = __disable_icache_msr,
525 .ifl = __flush_icache_all_noirq,
526 .iflr = __flush_icache_range_noirq,
527 .iin = __flush_icache_all_noirq,
528 .iinr = __flush_icache_range_noirq,
529 .de = __enable_dcache_msr,
530 .dd = __disable_dcache_msr,
531 .dfl = __flush_dcache_all_wb,
532 .dflr = __flush_dcache_range_wb,
533 .din = __invalidate_dcache_all_wb,
534 .dinr = __invalidate_dcache_range_wb,
538 static const struct scache wb_nomsr = {
539 .ie = __enable_icache_nomsr,
540 .id = __disable_icache_nomsr,
541 .ifl = __flush_icache_all_noirq,
542 .iflr = __flush_icache_range_noirq,
543 .iin = __flush_icache_all_noirq,
544 .iinr = __flush_icache_range_noirq,
545 .de = __enable_dcache_nomsr,
546 .dd = __disable_dcache_nomsr,
547 .dfl = __flush_dcache_all_wb,
548 .dflr = __flush_dcache_range_wb,
549 .din = __invalidate_dcache_all_wb,
550 .dinr = __invalidate_dcache_range_wb,
554 static const struct scache wt_msr = {
555 .ie = __enable_icache_msr,
556 .id = __disable_icache_msr,
557 .ifl = __flush_icache_all_msr_irq,
558 .iflr = __flush_icache_range_msr_irq,
559 .iin = __flush_icache_all_msr_irq,
560 .iinr = __flush_icache_range_msr_irq,
561 .de = __enable_dcache_msr,
562 .dd = __disable_dcache_msr,
563 .dfl = __invalidate_dcache_all_msr_irq,
564 .dflr = __invalidate_dcache_range_msr_irq_wt,
565 .din = __invalidate_dcache_all_msr_irq,
566 .dinr = __invalidate_dcache_range_msr_irq_wt,
569 static const struct scache wt_nomsr = {
570 .ie = __enable_icache_nomsr,
571 .id = __disable_icache_nomsr,
572 .ifl = __flush_icache_all_nomsr_irq,
573 .iflr = __flush_icache_range_nomsr_irq,
574 .iin = __flush_icache_all_nomsr_irq,
575 .iinr = __flush_icache_range_nomsr_irq,
576 .de = __enable_dcache_nomsr,
577 .dd = __disable_dcache_nomsr,
578 .dfl = __invalidate_dcache_all_nomsr_irq,
579 .dflr = __invalidate_dcache_range_nomsr_irq,
580 .din = __invalidate_dcache_all_nomsr_irq,
581 .dinr = __invalidate_dcache_range_nomsr_irq,
585 static const struct scache wt_msr_noirq = {
586 .ie = __enable_icache_msr,
587 .id = __disable_icache_msr,
588 .ifl = __flush_icache_all_noirq,
589 .iflr = __flush_icache_range_noirq,
590 .iin = __flush_icache_all_noirq,
591 .iinr = __flush_icache_range_noirq,
592 .de = __enable_dcache_msr,
593 .dd = __disable_dcache_msr,
594 .dfl = __invalidate_dcache_all_noirq_wt,
595 .dflr = __invalidate_dcache_range_nomsr_wt,
596 .din = __invalidate_dcache_all_noirq_wt,
597 .dinr = __invalidate_dcache_range_nomsr_wt,
600 static const struct scache wt_nomsr_noirq = {
601 .ie = __enable_icache_nomsr,
602 .id = __disable_icache_nomsr,
603 .ifl = __flush_icache_all_noirq,
604 .iflr = __flush_icache_range_noirq,
605 .iin = __flush_icache_all_noirq,
606 .iinr = __flush_icache_range_noirq,
607 .de = __enable_dcache_nomsr,
608 .dd = __disable_dcache_nomsr,
609 .dfl = __invalidate_dcache_all_noirq_wt,
610 .dflr = __invalidate_dcache_range_nomsr_wt,
611 .din = __invalidate_dcache_all_noirq_wt,
612 .dinr = __invalidate_dcache_range_nomsr_wt,
616 #define CPUVER_7_20_A 0x0c
617 #define CPUVER_7_20_D 0x0f
619 #define INFO(s) printk(KERN_INFO "cache: " s "\n");
626 mbc = (
struct scache *)&wb_msr;
629 INFO(
"WB won't work properly");
633 INFO(
"wt_msr_noirq");
634 mbc = (
struct scache *)&wt_msr_noirq;
637 mbc = (
struct scache *)&wt_msr;
643 mbc = (
struct scache *)&wb_nomsr;
646 INFO(
"WB won't work properly");
650 INFO(
"wt_nomsr_noirq");
651 mbc = (
struct scache *)&wt_nomsr_noirq;
654 mbc = (
struct scache *)&wt_nomsr;