diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/m68k/include/asm/cacheflush_mm.h | 88 | ||||
-rw-r--r-- | arch/m68k/mm/cache.c | 24 |
2 files changed, 104 insertions, 8 deletions
diff --git a/arch/m68k/include/asm/cacheflush_mm.h b/arch/m68k/include/asm/cacheflush_mm.h index 73de7c89d8e0..8104bd874649 100644 --- a/arch/m68k/include/asm/cacheflush_mm.h +++ b/arch/m68k/include/asm/cacheflush_mm.h | |||
@@ -2,23 +2,89 @@ | |||
2 | #define _M68K_CACHEFLUSH_H | 2 | #define _M68K_CACHEFLUSH_H |
3 | 3 | ||
4 | #include <linux/mm.h> | 4 | #include <linux/mm.h> |
5 | #ifdef CONFIG_COLDFIRE | ||
6 | #include <asm/mcfsim.h> | ||
7 | #endif | ||
5 | 8 | ||
6 | /* cache code */ | 9 | /* cache code */ |
7 | #define FLUSH_I_AND_D (0x00000808) | 10 | #define FLUSH_I_AND_D (0x00000808) |
8 | #define FLUSH_I (0x00000008) | 11 | #define FLUSH_I (0x00000008) |
9 | 12 | ||
13 | #ifndef ICACHE_MAX_ADDR | ||
14 | #define ICACHE_MAX_ADDR 0 | ||
15 | #define ICACHE_SET_MASK 0 | ||
16 | #define DCACHE_MAX_ADDR 0 | ||
17 | #define DCACHE_SETMASK 0 | ||
18 | #endif | ||
19 | |||
20 | static inline void flush_cf_icache(unsigned long start, unsigned long end) | ||
21 | { | ||
22 | unsigned long set; | ||
23 | |||
24 | for (set = start; set <= end; set += (0x10 - 3)) { | ||
25 | __asm__ __volatile__ ( | ||
26 | "cpushl %%ic,(%0)\n\t" | ||
27 | "addq%.l #1,%0\n\t" | ||
28 | "cpushl %%ic,(%0)\n\t" | ||
29 | "addq%.l #1,%0\n\t" | ||
30 | "cpushl %%ic,(%0)\n\t" | ||
31 | "addq%.l #1,%0\n\t" | ||
32 | "cpushl %%ic,(%0)" | ||
33 | : "=a" (set) | ||
34 | : "a" (set)); | ||
35 | } | ||
36 | } | ||
37 | |||
38 | static inline void flush_cf_dcache(unsigned long start, unsigned long end) | ||
39 | { | ||
40 | unsigned long set; | ||
41 | |||
42 | for (set = start; set <= end; set += (0x10 - 3)) { | ||
43 | __asm__ __volatile__ ( | ||
44 | "cpushl %%dc,(%0)\n\t" | ||
45 | "addq%.l #1,%0\n\t" | ||
46 | "cpushl %%dc,(%0)\n\t" | ||
47 | "addq%.l #1,%0\n\t" | ||
48 | "cpushl %%dc,(%0)\n\t" | ||
49 | "addq%.l #1,%0\n\t" | ||
50 | "cpushl %%dc,(%0)" | ||
51 | : "=a" (set) | ||
52 | : "a" (set)); | ||
53 | } | ||
54 | } | ||
55 | |||
56 | static inline void flush_cf_bcache(unsigned long start, unsigned long end) | ||
57 | { | ||
58 | unsigned long set; | ||
59 | |||
60 | for (set = start; set <= end; set += (0x10 - 3)) { | ||
61 | __asm__ __volatile__ ( | ||
62 | "cpushl %%bc,(%0)\n\t" | ||
63 | "addq%.l #1,%0\n\t" | ||
64 | "cpushl %%bc,(%0)\n\t" | ||
65 | "addq%.l #1,%0\n\t" | ||
66 | "cpushl %%bc,(%0)\n\t" | ||
67 | "addq%.l #1,%0\n\t" | ||
68 | "cpushl %%bc,(%0)" | ||
69 | : "=a" (set) | ||
70 | : "a" (set)); | ||
71 | } | ||
72 | } | ||
73 | |||
10 | /* | 74 | /* |
11 | * Cache handling functions | 75 | * Cache handling functions |
12 | */ | 76 | */ |
13 | 77 | ||
14 | static inline void flush_icache(void) | 78 | static inline void flush_icache(void) |
15 | { | 79 | { |
16 | if (CPU_IS_040_OR_060) | 80 | if (CPU_IS_COLDFIRE) { |
81 | flush_cf_icache(0, ICACHE_MAX_ADDR); | ||
82 | } else if (CPU_IS_040_OR_060) { | ||
17 | asm volatile ( "nop\n" | 83 | asm volatile ( "nop\n" |
18 | " .chip 68040\n" | 84 | " .chip 68040\n" |
19 | " cpusha %bc\n" | 85 | " cpusha %bc\n" |
20 | " .chip 68k"); | 86 | " .chip 68k"); |
21 | else { | 87 | } else { |
22 | unsigned long tmp; | 88 | unsigned long tmp; |
23 | asm volatile ( "movec %%cacr,%0\n" | 89 | asm volatile ( "movec %%cacr,%0\n" |
24 | " or.w %1,%0\n" | 90 | " or.w %1,%0\n" |
@@ -51,12 +117,14 @@ extern void cache_push_v(unsigned long vaddr, int len); | |||
51 | process changes. */ | 117 | process changes. */ |
52 | #define __flush_cache_all() \ | 118 | #define __flush_cache_all() \ |
53 | ({ \ | 119 | ({ \ |
54 | if (CPU_IS_040_OR_060) \ | 120 | if (CPU_IS_COLDFIRE) { \ |
121 | flush_cf_dcache(0, DCACHE_MAX_ADDR); \ | ||
122 | } else if (CPU_IS_040_OR_060) { \ | ||
55 | __asm__ __volatile__("nop\n\t" \ | 123 | __asm__ __volatile__("nop\n\t" \ |
56 | ".chip 68040\n\t" \ | 124 | ".chip 68040\n\t" \ |
57 | "cpusha %dc\n\t" \ | 125 | "cpusha %dc\n\t" \ |
58 | ".chip 68k"); \ | 126 | ".chip 68k"); \ |
59 | else { \ | 127 | } else { \ |
60 | unsigned long _tmp; \ | 128 | unsigned long _tmp; \ |
61 | __asm__ __volatile__("movec %%cacr,%0\n\t" \ | 129 | __asm__ __volatile__("movec %%cacr,%0\n\t" \ |
62 | "orw %1,%0\n\t" \ | 130 | "orw %1,%0\n\t" \ |
@@ -112,7 +180,17 @@ static inline void flush_cache_page(struct vm_area_struct *vma, unsigned long vm | |||
112 | /* RZ: use cpush %bc instead of cpush %dc, cinv %ic */ | 180 | /* RZ: use cpush %bc instead of cpush %dc, cinv %ic */ |
113 | static inline void __flush_page_to_ram(void *vaddr) | 181 | static inline void __flush_page_to_ram(void *vaddr) |
114 | { | 182 | { |
115 | if (CPU_IS_040_OR_060) { | 183 | if (CPU_IS_COLDFIRE) { |
184 | unsigned long addr, start, end; | ||
185 | addr = ((unsigned long) vaddr) & ~(PAGE_SIZE - 1); | ||
186 | start = addr & ICACHE_SET_MASK; | ||
187 | end = (addr + PAGE_SIZE - 1) & ICACHE_SET_MASK; | ||
188 | if (start > end) { | ||
189 | flush_cf_bcache(0, end); | ||
190 | end = ICACHE_MAX_ADDR; | ||
191 | } | ||
192 | flush_cf_bcache(start, end); | ||
193 | } else if (CPU_IS_040_OR_060) { | ||
116 | __asm__ __volatile__("nop\n\t" | 194 | __asm__ __volatile__("nop\n\t" |
117 | ".chip 68040\n\t" | 195 | ".chip 68040\n\t" |
118 | "cpushp %%bc,(%0)\n\t" | 196 | "cpushp %%bc,(%0)\n\t" |
diff --git a/arch/m68k/mm/cache.c b/arch/m68k/mm/cache.c index 5437fff5fe07..95d0bf66e2e2 100644 --- a/arch/m68k/mm/cache.c +++ b/arch/m68k/mm/cache.c | |||
@@ -74,8 +74,16 @@ static unsigned long virt_to_phys_slow(unsigned long vaddr) | |||
74 | /* RZ: use cpush %bc instead of cpush %dc, cinv %ic */ | 74 | /* RZ: use cpush %bc instead of cpush %dc, cinv %ic */ |
75 | void flush_icache_range(unsigned long address, unsigned long endaddr) | 75 | void flush_icache_range(unsigned long address, unsigned long endaddr) |
76 | { | 76 | { |
77 | 77 | if (CPU_IS_COLDFIRE) { | |
78 | if (CPU_IS_040_OR_060) { | 78 | unsigned long start, end; |
79 | start = address & ICACHE_SET_MASK; | ||
80 | end = endaddr & ICACHE_SET_MASK; | ||
81 | if (start > end) { | ||
82 | flush_cf_icache(0, end); | ||
83 | end = ICACHE_MAX_ADDR; | ||
84 | } | ||
85 | flush_cf_icache(start, end); | ||
86 | } else if (CPU_IS_040_OR_060) { | ||
79 | address &= PAGE_MASK; | 87 | address &= PAGE_MASK; |
80 | 88 | ||
81 | do { | 89 | do { |
@@ -100,7 +108,17 @@ EXPORT_SYMBOL(flush_icache_range); | |||
100 | void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, | 108 | void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, |
101 | unsigned long addr, int len) | 109 | unsigned long addr, int len) |
102 | { | 110 | { |
103 | if (CPU_IS_040_OR_060) { | 111 | if (CPU_IS_COLDFIRE) { |
112 | unsigned long start, end; | ||
113 | start = addr & ICACHE_SET_MASK; | ||
114 | end = (addr + len) & ICACHE_SET_MASK; | ||
115 | if (start > end) { | ||
116 | flush_cf_icache(0, end); | ||
117 | end = ICACHE_MAX_ADDR; | ||
118 | } | ||
119 | flush_cf_icache(start, end); | ||
120 | |||
121 | } else if (CPU_IS_040_OR_060) { | ||
104 | asm volatile ("nop\n\t" | 122 | asm volatile ("nop\n\t" |
105 | ".chip 68040\n\t" | 123 | ".chip 68040\n\t" |
106 | "cpushp %%bc,(%0)\n\t" | 124 | "cpushp %%bc,(%0)\n\t" |