aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m68k
diff options
context:
space:
mode:
Diffstat (limited to 'arch/m68k')
-rw-r--r--arch/m68k/include/asm/cacheflush_mm.h88
-rw-r--r--arch/m68k/mm/cache.c24
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 73de7c89d8e..8104bd87464 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
20static 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
38static 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
56static 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
14static inline void flush_icache(void) 78static 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 */
113static inline void __flush_page_to_ram(void *vaddr) 181static 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 5437fff5fe0..95d0bf66e2e 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 */
75void flush_icache_range(unsigned long address, unsigned long endaddr) 75void 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);
100void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, 108void 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"