Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / arch / sh / include / asm / switch_to_32.h
1 #ifndef __ASM_SH_SWITCH_TO_32_H
2 #define __ASM_SH_SWITCH_TO_32_H
3
4 #ifdef CONFIG_SH_DSP
5
6 #define is_dsp_enabled(tsk)                                             \
7         (!!(tsk->thread.dsp_status.status & SR_DSP))
8
9 #define __restore_dsp(tsk)                                              \
10 do {                                                                    \
11         register u32 *__ts2 __asm__ ("r2") =                            \
12                         (u32 *)&tsk->thread.dsp_status;                 \
13         __asm__ __volatile__ (                                          \
14                 ".balign 4\n\t"                                         \
15                 "movs.l @r2+, a0\n\t"                                   \
16                 "movs.l @r2+, a1\n\t"                                   \
17                 "movs.l @r2+, a0g\n\t"                                  \
18                 "movs.l @r2+, a1g\n\t"                                  \
19                 "movs.l @r2+, m0\n\t"                                   \
20                 "movs.l @r2+, m1\n\t"                                   \
21                 "movs.l @r2+, x0\n\t"                                   \
22                 "movs.l @r2+, x1\n\t"                                   \
23                 "movs.l @r2+, y0\n\t"                                   \
24                 "movs.l @r2+, y1\n\t"                                   \
25                 "lds.l  @r2+, dsr\n\t"                                  \
26                 "ldc.l  @r2+, rs\n\t"                                   \
27                 "ldc.l  @r2+, re\n\t"                                   \
28                 "ldc.l  @r2+, mod\n\t"                                  \
29                 : : "r" (__ts2));                                       \
30 } while (0)
31
32 #define __save_dsp(tsk)                                                 \
33 do {                                                                    \
34         register u32 *__ts2 __asm__ ("r2") =                            \
35                         (u32 *)&tsk->thread.dsp_status + 14;            \
36                                                                         \
37         __asm__ __volatile__ (                                          \
38                 ".balign 4\n\t"                                         \
39                 "stc.l  mod, @-r2\n\t"                                  \
40                 "stc.l  re, @-r2\n\t"                                   \
41                 "stc.l  rs, @-r2\n\t"                                   \
42                 "sts.l  dsr, @-r2\n\t"                                  \
43                 "movs.l y1, @-r2\n\t"                                   \
44                 "movs.l y0, @-r2\n\t"                                   \
45                 "movs.l x1, @-r2\n\t"                                   \
46                 "movs.l x0, @-r2\n\t"                                   \
47                 "movs.l m1, @-r2\n\t"                                   \
48                 "movs.l m0, @-r2\n\t"                                   \
49                 "movs.l a1g, @-r2\n\t"                                  \
50                 "movs.l a0g, @-r2\n\t"                                  \
51                 "movs.l a1, @-r2\n\t"                                   \
52                 "movs.l a0, @-r2\n\t"                                   \
53                 : : "r" (__ts2));                                       \
54 } while (0)
55
56 #else
57
58 #define is_dsp_enabled(tsk)     (0)
59 #define __save_dsp(tsk)         do { } while (0)
60 #define __restore_dsp(tsk)      do { } while (0)
61 #endif
62
63 struct task_struct *__switch_to(struct task_struct *prev,
64                                 struct task_struct *next);
65
66 /*
67  *      switch_to() should switch tasks to task nr n, first
68  */
69 #define switch_to(prev, next, last)                             \
70 do {                                                            \
71         register u32 *__ts1 __asm__ ("r1");                     \
72         register u32 *__ts2 __asm__ ("r2");                     \
73         register u32 *__ts4 __asm__ ("r4");                     \
74         register u32 *__ts5 __asm__ ("r5");                     \
75         register u32 *__ts6 __asm__ ("r6");                     \
76         register u32 __ts7 __asm__ ("r7");                      \
77         struct task_struct *__last;                             \
78                                                                 \
79         if (is_dsp_enabled(prev))                               \
80                 __save_dsp(prev);                               \
81                                                                 \
82         __ts1 = (u32 *)&prev->thread.sp;                        \
83         __ts2 = (u32 *)&prev->thread.pc;                        \
84         __ts4 = (u32 *)prev;                                    \
85         __ts5 = (u32 *)next;                                    \
86         __ts6 = (u32 *)&next->thread.sp;                        \
87         __ts7 = next->thread.pc;                                \
88                                                                 \
89         __asm__ __volatile__ (                                  \
90                 ".balign 4\n\t"                                 \
91                 "stc.l  gbr, @-r15\n\t"                         \
92                 "sts.l  pr, @-r15\n\t"                          \
93                 "mov.l  r8, @-r15\n\t"                          \
94                 "mov.l  r9, @-r15\n\t"                          \
95                 "mov.l  r10, @-r15\n\t"                         \
96                 "mov.l  r11, @-r15\n\t"                         \
97                 "mov.l  r12, @-r15\n\t"                         \
98                 "mov.l  r13, @-r15\n\t"                         \
99                 "mov.l  r14, @-r15\n\t"                         \
100                 "mov.l  r15, @r1\t! save SP\n\t"                \
101                 "mov.l  @r6, r15\t! change to new stack\n\t"    \
102                 "mova   1f, %0\n\t"                             \
103                 "mov.l  %0, @r2\t! save PC\n\t"                 \
104                 "mov.l  2f, %0\n\t"                             \
105                 "jmp    @%0\t! call __switch_to\n\t"            \
106                 " lds   r7, pr\t!  with return to new PC\n\t"   \
107                 ".balign        4\n"                            \
108                 "2:\n\t"                                        \
109                 ".long  __switch_to\n"                          \
110                 "1:\n\t"                                        \
111                 "mov.l  @r15+, r14\n\t"                         \
112                 "mov.l  @r15+, r13\n\t"                         \
113                 "mov.l  @r15+, r12\n\t"                         \
114                 "mov.l  @r15+, r11\n\t"                         \
115                 "mov.l  @r15+, r10\n\t"                         \
116                 "mov.l  @r15+, r9\n\t"                          \
117                 "mov.l  @r15+, r8\n\t"                          \
118                 "lds.l  @r15+, pr\n\t"                          \
119                 "ldc.l  @r15+, gbr\n\t"                         \
120                 : "=z" (__last)                                 \
121                 : "r" (__ts1), "r" (__ts2), "r" (__ts4),        \
122                   "r" (__ts5), "r" (__ts6), "r" (__ts7)         \
123                 : "r3", "t");                                   \
124                                                                 \
125         last = __last;                                          \
126 } while (0)
127
128 #define finish_arch_switch(prev)                                \
129 do {                                                            \
130         if (is_dsp_enabled(prev))                               \
131                 __restore_dsp(prev);                            \
132 } while (0)
133
134 #endif /* __ASM_SH_SWITCH_TO_32_H */