diff options
Diffstat (limited to 'arch/microblaze/kernel/cpu/cache.c')
-rw-r--r-- | arch/microblaze/kernel/cpu/cache.c | 148 |
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 | ||
18 | static inline void __enable_icache_msr(void) | 18 | static 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 | ||
25 | static inline void __disable_icache_msr(void) | 25 | static 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 | ||
32 | static inline void __enable_dcache_msr(void) | 32 | static 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 | ||
41 | static inline void __disable_dcache_msr(void) | 39 | static 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 | ||
50 | static inline void __enable_icache_nomsr(void) | 46 | static 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 | ||
62 | static inline void __disable_icache_nomsr(void) | 56 | static 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 | ||
74 | static inline void __enable_dcache_nomsr(void) | 66 | static 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 | ||
86 | static inline void __disable_dcache_nomsr(void) | 76 | static 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 | |||
621 | void microblaze_cache_init(void) | 608 | void 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 | ||