Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block
[sfrench/cifs-2.6.git] / arch / sh / include / asm / system_32.h
1 #ifndef __ASM_SH_SYSTEM_32_H
2 #define __ASM_SH_SYSTEM_32_H
3
4 #include <linux/types.h>
5
6 #ifdef CONFIG_SH_DSP
7
8 #define is_dsp_enabled(tsk)                                             \
9         (!!(tsk->thread.dsp_status.status & SR_DSP))
10
11 #define __restore_dsp(tsk)                                              \
12 do {                                                                    \
13         register u32 *__ts2 __asm__ ("r2") =                            \
14                         (u32 *)&tsk->thread.dsp_status;                 \
15         __asm__ __volatile__ (                                          \
16                 ".balign 4\n\t"                                         \
17                 "movs.l @r2+, a0\n\t"                                   \
18                 "movs.l @r2+, a1\n\t"                                   \
19                 "movs.l @r2+, a0g\n\t"                                  \
20                 "movs.l @r2+, a1g\n\t"                                  \
21                 "movs.l @r2+, m0\n\t"                                   \
22                 "movs.l @r2+, m1\n\t"                                   \
23                 "movs.l @r2+, x0\n\t"                                   \
24                 "movs.l @r2+, x1\n\t"                                   \
25                 "movs.l @r2+, y0\n\t"                                   \
26                 "movs.l @r2+, y1\n\t"                                   \
27                 "lds.l  @r2+, dsr\n\t"                                  \
28                 "ldc.l  @r2+, rs\n\t"                                   \
29                 "ldc.l  @r2+, re\n\t"                                   \
30                 "ldc.l  @r2+, mod\n\t"                                  \
31                 : : "r" (__ts2));                                       \
32 } while (0)
33
34
35 #define __save_dsp(tsk)                                                 \
36 do {                                                                    \
37         register u32 *__ts2 __asm__ ("r2") =                            \
38                         (u32 *)&tsk->thread.dsp_status + 14;            \
39                                                                         \
40         __asm__ __volatile__ (                                          \
41                 ".balign 4\n\t"                                         \
42                 "stc.l  mod, @-r2\n\t"                                  \
43                 "stc.l  re, @-r2\n\t"                                   \
44                 "stc.l  rs, @-r2\n\t"                                   \
45                 "sts.l  dsr, @-r2\n\t"                                  \
46                 "movs.l y1, @-r2\n\t"                                   \
47                 "movs.l y0, @-r2\n\t"                                   \
48                 "movs.l x1, @-r2\n\t"                                   \
49                 "movs.l x0, @-r2\n\t"                                   \
50                 "movs.l m1, @-r2\n\t"                                   \
51                 "movs.l m0, @-r2\n\t"                                   \
52                 "movs.l a1g, @-r2\n\t"                                  \
53                 "movs.l a0g, @-r2\n\t"                                  \
54                 "movs.l a1, @-r2\n\t"                                   \
55                 "movs.l a0, @-r2\n\t"                                   \
56                 : : "r" (__ts2));                                       \
57 } while (0)
58
59 #else
60
61 #define is_dsp_enabled(tsk)     (0)
62 #define __save_dsp(tsk)         do { } while (0)
63 #define __restore_dsp(tsk)      do { } while (0)
64 #endif
65
66 #if defined(CONFIG_CPU_SH4A)
67 #define __icbi(addr)    __asm__ __volatile__ ( "icbi @%0\n\t" : : "r" (addr))
68 #else
69 #define __icbi(addr)    mb()
70 #endif
71
72 #define __ocbp(addr)    __asm__ __volatile__ ( "ocbp @%0\n\t" : : "r" (addr))
73 #define __ocbi(addr)    __asm__ __volatile__ ( "ocbi @%0\n\t" : : "r" (addr))
74 #define __ocbwb(addr)   __asm__ __volatile__ ( "ocbwb @%0\n\t" : : "r" (addr))
75
76 struct task_struct *__switch_to(struct task_struct *prev,
77                                 struct task_struct *next);
78
79 /*
80  *      switch_to() should switch tasks to task nr n, first
81  */
82 #define switch_to(prev, next, last)                             \
83 do {                                                            \
84         register u32 *__ts1 __asm__ ("r1");                     \
85         register u32 *__ts2 __asm__ ("r2");                     \
86         register u32 *__ts4 __asm__ ("r4");                     \
87         register u32 *__ts5 __asm__ ("r5");                     \
88         register u32 *__ts6 __asm__ ("r6");                     \
89         register u32 __ts7 __asm__ ("r7");                      \
90         struct task_struct *__last;                             \
91                                                                 \
92         if (is_dsp_enabled(prev))                               \
93                 __save_dsp(prev);                               \
94                                                                 \
95         __ts1 = (u32 *)&prev->thread.sp;                        \
96         __ts2 = (u32 *)&prev->thread.pc;                        \
97         __ts4 = (u32 *)prev;                                    \
98         __ts5 = (u32 *)next;                                    \
99         __ts6 = (u32 *)&next->thread.sp;                        \
100         __ts7 = next->thread.pc;                                \
101                                                                 \
102         __asm__ __volatile__ (                                  \
103                 ".balign 4\n\t"                                 \
104                 "stc.l  gbr, @-r15\n\t"                         \
105                 "sts.l  pr, @-r15\n\t"                          \
106                 "mov.l  r8, @-r15\n\t"                          \
107                 "mov.l  r9, @-r15\n\t"                          \
108                 "mov.l  r10, @-r15\n\t"                         \
109                 "mov.l  r11, @-r15\n\t"                         \
110                 "mov.l  r12, @-r15\n\t"                         \
111                 "mov.l  r13, @-r15\n\t"                         \
112                 "mov.l  r14, @-r15\n\t"                         \
113                 "mov.l  r15, @r1\t! save SP\n\t"                \
114                 "mov.l  @r6, r15\t! change to new stack\n\t"    \
115                 "mova   1f, %0\n\t"                             \
116                 "mov.l  %0, @r2\t! save PC\n\t"                 \
117                 "mov.l  2f, %0\n\t"                             \
118                 "jmp    @%0\t! call __switch_to\n\t"            \
119                 " lds   r7, pr\t!  with return to new PC\n\t"   \
120                 ".balign        4\n"                            \
121                 "2:\n\t"                                        \
122                 ".long  __switch_to\n"                          \
123                 "1:\n\t"                                        \
124                 "mov.l  @r15+, r14\n\t"                         \
125                 "mov.l  @r15+, r13\n\t"                         \
126                 "mov.l  @r15+, r12\n\t"                         \
127                 "mov.l  @r15+, r11\n\t"                         \
128                 "mov.l  @r15+, r10\n\t"                         \
129                 "mov.l  @r15+, r9\n\t"                          \
130                 "mov.l  @r15+, r8\n\t"                          \
131                 "lds.l  @r15+, pr\n\t"                          \
132                 "ldc.l  @r15+, gbr\n\t"                         \
133                 : "=z" (__last)                                 \
134                 : "r" (__ts1), "r" (__ts2), "r" (__ts4),        \
135                   "r" (__ts5), "r" (__ts6), "r" (__ts7)         \
136                 : "r3", "t");                                   \
137                                                                 \
138         last = __last;                                          \
139 } while (0)
140
141 #define finish_arch_switch(prev)                                \
142 do {                                                            \
143         if (is_dsp_enabled(prev))                               \
144                 __restore_dsp(prev);                            \
145 } while (0)
146
147 #define __uses_jump_to_uncached \
148         noinline __attribute__ ((__section__ (".uncached.text")))
149
150 /*
151  * Jump to uncached area.
152  * When handling TLB or caches, we need to do it from an uncached area.
153  */
154 #define jump_to_uncached()                      \
155 do {                                            \
156         unsigned long __dummy;                  \
157                                                 \
158         __asm__ __volatile__(                   \
159                 "mova   1f, %0\n\t"             \
160                 "add    %1, %0\n\t"             \
161                 "jmp    @%0\n\t"                \
162                 " nop\n\t"                      \
163                 ".balign 4\n"                   \
164                 "1:"                            \
165                 : "=&z" (__dummy)               \
166                 : "r" (cached_to_uncached));    \
167 } while (0)
168
169 /*
170  * Back to cached area.
171  */
172 #define back_to_cached()                                \
173 do {                                                    \
174         unsigned long __dummy;                          \
175         ctrl_barrier();                                 \
176         __asm__ __volatile__(                           \
177                 "mov.l  1f, %0\n\t"                     \
178                 "jmp    @%0\n\t"                        \
179                 " nop\n\t"                              \
180                 ".balign 4\n"                           \
181                 "1:     .long 2f\n"                     \
182                 "2:"                                    \
183                 : "=&r" (__dummy));                     \
184 } while (0)
185
186 #ifdef CONFIG_CPU_HAS_SR_RB
187 #define lookup_exception_vector()       \
188 ({                                      \
189         unsigned long _vec;             \
190                                         \
191         __asm__ __volatile__ (          \
192                 "stc r2_bank, %0\n\t"   \
193                 : "=r" (_vec)           \
194         );                              \
195                                         \
196         _vec;                           \
197 })
198 #else
199 #define lookup_exception_vector()       \
200 ({                                      \
201         unsigned long _vec;             \
202         __asm__ __volatile__ (          \
203                 "mov r4, %0\n\t"        \
204                 : "=r" (_vec)           \
205         );                              \
206                                         \
207         _vec;                           \
208 })
209 #endif
210
211 static inline reg_size_t register_align(void *val)
212 {
213         return (unsigned long)(signed long)val;
214 }
215
216 int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
217                             struct mem_access *ma, int);
218
219 asmlinkage void do_address_error(struct pt_regs *regs,
220                                  unsigned long writeaccess,
221                                  unsigned long address);
222 asmlinkage void do_divide_error(unsigned long r4, unsigned long r5,
223                                 unsigned long r6, unsigned long r7,
224                                 struct pt_regs __regs);
225 asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
226                                 unsigned long r6, unsigned long r7,
227                                 struct pt_regs __regs);
228 asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5,
229                                 unsigned long r6, unsigned long r7,
230                                 struct pt_regs __regs);
231 asmlinkage void do_exception_error(unsigned long r4, unsigned long r5,
232                                    unsigned long r6, unsigned long r7,
233                                    struct pt_regs __regs);
234
235 static inline void set_bl_bit(void)
236 {
237         unsigned long __dummy0, __dummy1;
238
239         __asm__ __volatile__ (
240                 "stc    sr, %0\n\t"
241                 "or     %2, %0\n\t"
242                 "and    %3, %0\n\t"
243                 "ldc    %0, sr\n\t"
244                 : "=&r" (__dummy0), "=r" (__dummy1)
245                 : "r" (0x10000000), "r" (0xffffff0f)
246                 : "memory"
247         );
248 }
249
250 static inline void clear_bl_bit(void)
251 {
252         unsigned long __dummy0, __dummy1;
253
254         __asm__ __volatile__ (
255                 "stc    sr, %0\n\t"
256                 "and    %2, %0\n\t"
257                 "ldc    %0, sr\n\t"
258                 : "=&r" (__dummy0), "=r" (__dummy1)
259                 : "1" (~0x10000000)
260                 : "memory"
261         );
262 }
263
264 #endif /* __ASM_SH_SYSTEM_32_H */