aboutsummaryrefslogtreecommitdiffstats
path: root/arch/microblaze/kernel/cpu/cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/microblaze/kernel/cpu/cache.c')
-rw-r--r--arch/microblaze/kernel/cpu/cache.c148
1 files changed, 68 insertions, 80 deletions
diff --git a/arch/microblaze/kernel/cpu/cache.c b/arch/microblaze/kernel/cpu/cache.c
index 4b7d8a3f4aef..4254514b4c8c 100644
--- a/arch/microblaze/kernel/cpu/cache.c
+++ b/arch/microblaze/kernel/cpu/cache.c
@@ -17,82 +17,70 @@
17 17
18static inline void __enable_icache_msr(void) 18static inline void __enable_icache_msr(void)
19{ 19{
20 __asm__ __volatile__ (" msrset r0, %0; \ 20 __asm__ __volatile__ (" msrset r0, %0;" \
21 nop; " \ 21 "nop;" \
22 : : "i" (MSR_ICE) : "memory"); 22 : : "i" (MSR_ICE) : "memory");
23} 23}
24 24
25static inline void __disable_icache_msr(void) 25static inline void __disable_icache_msr(void)
26{ 26{
27 __asm__ __volatile__ (" msrclr r0, %0; \ 27 __asm__ __volatile__ (" msrclr r0, %0;" \
28 nop; " \ 28 "nop;" \
29 : : "i" (MSR_ICE) : "memory"); 29 : : "i" (MSR_ICE) : "memory");
30} 30}
31 31
32static inline void __enable_dcache_msr(void) 32static inline void __enable_dcache_msr(void)
33{ 33{
34 __asm__ __volatile__ (" msrset r0, %0; \ 34 __asm__ __volatile__ (" msrset r0, %0;" \
35 nop; " \ 35 "nop;" \
36 : \ 36 : : "i" (MSR_DCE) : "memory");
37 : "i" (MSR_DCE) \
38 : "memory");
39} 37}
40 38
41static inline void __disable_dcache_msr(void) 39static inline void __disable_dcache_msr(void)
42{ 40{
43 __asm__ __volatile__ (" msrclr r0, %0; \ 41 __asm__ __volatile__ (" msrclr r0, %0;" \
44 nop; " \ 42 "nop; " \
45 : \ 43 : : "i" (MSR_DCE) : "memory");
46 : "i" (MSR_DCE) \
47 : "memory");
48} 44}
49 45
50static inline void __enable_icache_nomsr(void) 46static inline void __enable_icache_nomsr(void)
51{ 47{
52 __asm__ __volatile__ (" mfs r12, rmsr; \ 48 __asm__ __volatile__ (" mfs r12, rmsr;" \
53 nop; \ 49 "nop;" \
54 ori r12, r12, %0; \ 50 "ori r12, r12, %0;" \
55 mts rmsr, r12; \ 51 "mts rmsr, r12;" \
56 nop; " \ 52 "nop;" \
57 : \ 53 : : "i" (MSR_ICE) : "memory", "r12");
58 : "i" (MSR_ICE) \
59 : "memory", "r12");
60} 54}
61 55
62static inline void __disable_icache_nomsr(void) 56static inline void __disable_icache_nomsr(void)
63{ 57{
64 __asm__ __volatile__ (" mfs r12, rmsr; \ 58 __asm__ __volatile__ (" mfs r12, rmsr;" \
65 nop; \ 59 "nop;" \
66 andi r12, r12, ~%0; \ 60 "andi r12, r12, ~%0;" \
67 mts rmsr, r12; \ 61 "mts rmsr, r12;" \
68 nop; " \ 62 "nop;" \
69 : \ 63 : : "i" (MSR_ICE) : "memory", "r12");
70 : "i" (MSR_ICE) \
71 : "memory", "r12");
72} 64}
73 65
74static inline void __enable_dcache_nomsr(void) 66static inline void __enable_dcache_nomsr(void)
75{ 67{
76 __asm__ __volatile__ (" mfs r12, rmsr; \ 68 __asm__ __volatile__ (" mfs r12, rmsr;" \
77 nop; \ 69 "nop;" \
78 ori r12, r12, %0; \ 70 "ori r12, r12, %0;" \
79 mts rmsr, r12; \ 71 "mts rmsr, r12;" \
80 nop; " \ 72 "nop;" \
81 : \ 73 : : "i" (MSR_DCE) : "memory", "r12");
82 : "i" (MSR_DCE) \
83 : "memory", "r12");
84} 74}
85 75
86static inline void __disable_dcache_nomsr(void) 76static inline void __disable_dcache_nomsr(void)
87{ 77{
88 __asm__ __volatile__ (" mfs r12, rmsr; \ 78 __asm__ __volatile__ (" mfs r12, rmsr;" \
89 nop; \ 79 "nop;" \
90 andi r12, r12, ~%0; \ 80 "andi r12, r12, ~%0;" \
91 mts rmsr, r12; \ 81 "mts rmsr, r12;" \
92 nop; " \ 82 "nop;" \
93 : \ 83 : : "i" (MSR_DCE) : "memory", "r12");
94 : "i" (MSR_DCE) \
95 : "memory", "r12");
96} 84}
97 85
98 86
@@ -106,7 +94,7 @@ do { \
106 int align = ~(cache_line_length - 1); \ 94 int align = ~(cache_line_length - 1); \
107 end = min(start + cache_size, end); \ 95 end = min(start + cache_size, end); \
108 start &= align; \ 96 start &= align; \
109} while (0); 97} while (0)
110 98
111/* 99/*
112 * Helper macro to loop over the specified cache_size/line_length and 100 * Helper macro to loop over the specified cache_size/line_length and
@@ -118,12 +106,12 @@ do { \
118 int step = -line_length; \ 106 int step = -line_length; \
119 WARN_ON(step >= 0); \ 107 WARN_ON(step >= 0); \
120 \ 108 \
121 __asm__ __volatile__ (" 1: " #op " %0, r0; \ 109 __asm__ __volatile__ (" 1: " #op " %0, r0;" \
122 bgtid %0, 1b; \ 110 "bgtid %0, 1b;" \
123 addk %0, %0, %1; \ 111 "addk %0, %0, %1;" \
124 " : : "r" (len), "r" (step) \ 112 : : "r" (len), "r" (step) \
125 : "memory"); \ 113 : "memory"); \
126} while (0); 114} while (0)
127 115
128/* Used for wdc.flush/clear which can use rB for offset which is not possible 116/* Used for wdc.flush/clear which can use rB for offset which is not possible
129 * to use for simple wdc or wic. 117 * to use for simple wdc or wic.
@@ -142,12 +130,12 @@ do { \
142 count = end - start; \ 130 count = end - start; \
143 WARN_ON(count < 0); \ 131 WARN_ON(count < 0); \
144 \ 132 \
145 __asm__ __volatile__ (" 1: " #op " %0, %1; \ 133 __asm__ __volatile__ (" 1: " #op " %0, %1;" \
146 bgtid %1, 1b; \ 134 "bgtid %1, 1b;" \
147 addk %1, %1, %2; \ 135 "addk %1, %1, %2;" \
148 " : : "r" (start), "r" (count), \ 136 : : "r" (start), "r" (count), \
149 "r" (step) : "memory"); \ 137 "r" (step) : "memory"); \
150} while (0); 138} while (0)
151 139
152/* It is used only first parameter for OP - for wic, wdc */ 140/* It is used only first parameter for OP - for wic, wdc */
153#define CACHE_RANGE_LOOP_1(start, end, line_length, op) \ 141#define CACHE_RANGE_LOOP_1(start, end, line_length, op) \
@@ -157,13 +145,13 @@ do { \
157 end = ((end & align) == end) ? end - line_length : end & align; \ 145 end = ((end & align) == end) ? end - line_length : end & align; \
158 WARN_ON(end - start < 0); \ 146 WARN_ON(end - start < 0); \
159 \ 147 \
160 __asm__ __volatile__ (" 1: " #op " %1, r0; \ 148 __asm__ __volatile__ (" 1: " #op " %1, r0;" \
161 cmpu %0, %1, %2; \ 149 "cmpu %0, %1, %2;" \
162 bgtid %0, 1b; \ 150 "bgtid %0, 1b;" \
163 addk %1, %1, %3; \ 151 "addk %1, %1, %3;" \
164 " : : "r" (temp), "r" (start), "r" (end),\ 152 : : "r" (temp), "r" (start), "r" (end), \
165 "r" (line_length) : "memory"); \ 153 "r" (line_length) : "memory"); \
166} while (0); 154} while (0)
167 155
168#define ASM_LOOP 156#define ASM_LOOP
169 157
@@ -352,7 +340,7 @@ static void __invalidate_dcache_all_noirq_wt(void)
352#endif 340#endif
353 pr_debug("%s\n", __func__); 341 pr_debug("%s\n", __func__);
354#ifdef ASM_LOOP 342#ifdef ASM_LOOP
355 CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc) 343 CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc);
356#else 344#else
357 for (i = 0; i < cpuinfo.dcache_size; 345 for (i = 0; i < cpuinfo.dcache_size;
358 i += cpuinfo.dcache_line_length) 346 i += cpuinfo.dcache_line_length)
@@ -361,7 +349,8 @@ static void __invalidate_dcache_all_noirq_wt(void)
361#endif 349#endif
362} 350}
363 351
364/* FIXME It is blindly invalidation as is expected 352/*
353 * FIXME It is blindly invalidation as is expected
365 * but can't be called on noMMU in microblaze_cache_init below 354 * but can't be called on noMMU in microblaze_cache_init below
366 * 355 *
367 * MS: noMMU kernel won't boot if simple wdc is used 356 * MS: noMMU kernel won't boot if simple wdc is used
@@ -375,7 +364,7 @@ static void __invalidate_dcache_all_wb(void)
375 pr_debug("%s\n", __func__); 364 pr_debug("%s\n", __func__);
376#ifdef ASM_LOOP 365#ifdef ASM_LOOP
377 CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, 366 CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length,
378 wdc) 367 wdc);
379#else 368#else
380 for (i = 0; i < cpuinfo.dcache_size; 369 for (i = 0; i < cpuinfo.dcache_size;
381 i += cpuinfo.dcache_line_length) 370 i += cpuinfo.dcache_line_length)
@@ -616,49 +605,48 @@ static const struct scache wt_nomsr_noirq = {
616#define CPUVER_7_20_A 0x0c 605#define CPUVER_7_20_A 0x0c
617#define CPUVER_7_20_D 0x0f 606#define CPUVER_7_20_D 0x0f
618 607
619#define INFO(s) printk(KERN_INFO "cache: " s "\n");
620
621void microblaze_cache_init(void) 608void microblaze_cache_init(void)
622{ 609{
623 if (cpuinfo.use_instr & PVR2_USE_MSR_INSTR) { 610 if (cpuinfo.use_instr & PVR2_USE_MSR_INSTR) {
624 if (cpuinfo.dcache_wb) { 611 if (cpuinfo.dcache_wb) {
625 INFO("wb_msr"); 612 pr_info("wb_msr\n");
626 mbc = (struct scache *)&wb_msr; 613 mbc = (struct scache *)&wb_msr;
627 if (cpuinfo.ver_code <= CPUVER_7_20_D) { 614 if (cpuinfo.ver_code <= CPUVER_7_20_D) {
628 /* MS: problem with signal handling - hw bug */ 615 /* MS: problem with signal handling - hw bug */
629 INFO("WB won't work properly"); 616 pr_info("WB won't work properly\n");
630 } 617 }
631 } else { 618 } else {
632 if (cpuinfo.ver_code >= CPUVER_7_20_A) { 619 if (cpuinfo.ver_code >= CPUVER_7_20_A) {
633 INFO("wt_msr_noirq"); 620 pr_info("wt_msr_noirq\n");
634 mbc = (struct scache *)&wt_msr_noirq; 621 mbc = (struct scache *)&wt_msr_noirq;
635 } else { 622 } else {
636 INFO("wt_msr"); 623 pr_info("wt_msr\n");
637 mbc = (struct scache *)&wt_msr; 624 mbc = (struct scache *)&wt_msr;
638 } 625 }
639 } 626 }
640 } else { 627 } else {
641 if (cpuinfo.dcache_wb) { 628 if (cpuinfo.dcache_wb) {
642 INFO("wb_nomsr"); 629 pr_info("wb_nomsr\n");
643 mbc = (struct scache *)&wb_nomsr; 630 mbc = (struct scache *)&wb_nomsr;
644 if (cpuinfo.ver_code <= CPUVER_7_20_D) { 631 if (cpuinfo.ver_code <= CPUVER_7_20_D) {
645 /* MS: problem with signal handling - hw bug */ 632 /* MS: problem with signal handling - hw bug */
646 INFO("WB won't work properly"); 633 pr_info("WB won't work properly\n");
647 } 634 }
648 } else { 635 } else {
649 if (cpuinfo.ver_code >= CPUVER_7_20_A) { 636 if (cpuinfo.ver_code >= CPUVER_7_20_A) {
650 INFO("wt_nomsr_noirq"); 637 pr_info("wt_nomsr_noirq\n");
651 mbc = (struct scache *)&wt_nomsr_noirq; 638 mbc = (struct scache *)&wt_nomsr_noirq;
652 } else { 639 } else {
653 INFO("wt_nomsr"); 640 pr_info("wt_nomsr\n");
654 mbc = (struct scache *)&wt_nomsr; 641 mbc = (struct scache *)&wt_nomsr;
655 } 642 }
656 } 643 }
657 } 644 }
658/* FIXME Invalidation is done in U-BOOT 645 /*
659 * WT cache: Data is already written to main memory 646 * FIXME Invalidation is done in U-BOOT
660 * WB cache: Discard data on noMMU which caused that kernel doesn't boot 647 * WT cache: Data is already written to main memory
661 */ 648 * WB cache: Discard data on noMMU which caused that kernel doesn't boot
649 */
662 /* invalidate_dcache(); */ 650 /* invalidate_dcache(); */
663 enable_dcache(); 651 enable_dcache();
664 652