1 
2 #ifndef M68K_PGALLOC_H
3 #define M68K_PGALLOC_H
4 
5 #include <linux/config.h>
6 #include <asm/setup.h>
7 #include <asm/virtconvert.h>
8 
9 /*
10  * Cache handling functions
11  */
12 
13 #define flush_icache()						\
14 ({								\
15 	if (CPU_IS_040_OR_060)					\
16 		__asm__ __volatile__("nop\n\t"			\
17 				     ".chip 68040\n\t"		\
18 				     "cinva %%ic\n\t"		\
19 				     ".chip 68k" : );		\
20 	else {							\
21 		unsigned long _tmp;				\
22 		__asm__ __volatile__("movec %%cacr,%0\n\t"	\
23 				     "orw %1,%0\n\t"		\
24 				     "movec %0,%%cacr"		\
25 				     : "=&d" (_tmp)		\
26 				     : "id" (FLUSH_I));	\
27 	}							\
28 })
29 
30 /*
31  * invalidate the cache for the specified memory range.
32  * It starts at the physical address specified for
33  * the given number of bytes.
34  */
35 extern void cache_clear(unsigned long paddr, int len);
36 /*
37  * push any dirty cache in the specified memory range.
38  * It starts at the physical address specified for
39  * the given number of bytes.
40  */
41 extern void cache_push(unsigned long paddr, int len);
42 
43 /*
44  * push and invalidate pages in the specified user virtual
45  * memory range.
46  */
47 extern void cache_push_v(unsigned long vaddr, int len);
48 
49 /* cache code */
50 #define FLUSH_I_AND_D	(0x00000808)
51 #define FLUSH_I 	(0x00000008)
52 
53 /* This is needed whenever the virtual mapping of the current
54    process changes.  */
55 #define __flush_cache_all()					\
56 ({								\
57 	if (CPU_IS_040_OR_060)					\
58 		__asm__ __volatile__("nop\n\t"			\
59 				     ".chip 68040\n\t"		\
60 				     "cpusha %dc\n\t"		\
61 				     ".chip 68k");		\
62 	else {							\
63 		unsigned long _tmp;				\
64 		__asm__ __volatile__("movec %%cacr,%0\n\t"	\
65 				     "orw %1,%0\n\t"		\
66 				     "movec %0,%%cacr"		\
67 				     : "=&d" (_tmp)		\
68 				     : "di" (FLUSH_I_AND_D));	\
69 	}							\
70 })
71 
72 #define __flush_cache_030()					\
73 ({								\
74 	if (CPU_IS_020_OR_030) {				\
75 		unsigned long _tmp;				\
76 		__asm__ __volatile__("movec %%cacr,%0\n\t"	\
77 				     "orw %1,%0\n\t"		\
78 				     "movec %0,%%cacr"		\
79 				     : "=&d" (_tmp)		\
80 				     : "di" (FLUSH_I_AND_D));	\
81 	}							\
82 })
83 
84 #define flush_cache_all() __flush_cache_all()
85 
flush_cache_mm(struct mm_struct * mm)86 static inline void flush_cache_mm(struct mm_struct *mm)
87 {
88 	if (mm == current->mm)
89 		__flush_cache_030();
90 }
91 
flush_cache_range(struct mm_struct * mm,unsigned long start,unsigned long end)92 static inline void flush_cache_range(struct mm_struct *mm, unsigned long start,
93 				     unsigned long end)
94 {
95 	if (mm == current->mm)
96 	        __flush_cache_030();
97 }
98 
flush_cache_page(struct vm_area_struct * vma,unsigned long vmaddr)99 static inline void flush_cache_page(struct vm_area_struct *vma,
100 				    unsigned long vmaddr)
101 {
102 	if (vma->vm_mm == current->mm)
103 	        __flush_cache_030();
104 }
105 
106 /* Push the page at kernel virtual address and clear the icache */
107 /* RZ: use cpush %bc instead of cpush %dc, cinv %ic */
108 #define flush_page_to_ram(page) __flush_page_to_ram((unsigned long) page_address(page))
__flush_page_to_ram(unsigned long address)109 static inline void __flush_page_to_ram(unsigned long address)
110 {
111 	if (CPU_IS_040_OR_060) {
112 		__asm__ __volatile__("nop\n\t"
113 				     ".chip 68040\n\t"
114 				     "cpushp %%bc,(%0)\n\t"
115 				     ".chip 68k"
116 				     : : "a" (__pa((void *)address)));
117 	} else {
118 		unsigned long _tmp;
119 		__asm__ __volatile__("movec %%cacr,%0\n\t"
120 				     "orw %1,%0\n\t"
121 				     "movec %0,%%cacr"
122 				     : "=&d" (_tmp)
123 				     : "di" (FLUSH_I));
124 	}
125 }
126 
127 #define flush_dcache_page(page)			do { } while (0)
128 #define flush_icache_page(vma,pg)              do { } while (0)
129 #define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
130 
131 /* Push n pages at kernel virtual address and clear the icache */
132 /* RZ: use cpush %bc instead of cpush %dc, cinv %ic */
flush_icache_range(unsigned long address,unsigned long endaddr)133 extern inline void flush_icache_range (unsigned long address,
134 				       unsigned long endaddr)
135 {
136 	if (CPU_IS_040_OR_060) {
137 		short n = (endaddr - address + PAGE_SIZE - 1) / PAGE_SIZE;
138 
139 		while (--n >= 0) {
140 			__asm__ __volatile__("nop\n\t"
141 					     ".chip 68040\n\t"
142 					     "cpushp %%bc,(%0)\n\t"
143 					     ".chip 68k"
144 					     : : "a" (virt_to_phys((void *)address)));
145 			address += PAGE_SIZE;
146 		}
147 	} else {
148 		unsigned long tmp;
149 		__asm__ __volatile__("movec %%cacr,%0\n\t"
150 				     "orw %1,%0\n\t"
151 				     "movec %0,%%cacr"
152 				     : "=&d" (tmp)
153 				     : "di" (FLUSH_I));
154 	}
155 }
156 
157 
158 
159 
160 #ifdef CONFIG_SUN3
161 #include <asm/sun3_pgalloc.h>
162 #else
163 #include <asm/motorola_pgalloc.h>
164 #endif
165 
166 #endif /* M68K_PGALLOC_H */
167