Merge branch 'master' of git://git.infradead.org/users/eparis/selinux into for-linus
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / arch / mn10300 / kernel / switch_to.S
1 ###############################################################################
2 #
3 # MN10300 Context switch operation
4 #
5 # Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
6 # Written by David Howells (dhowells@redhat.com)
7 #
8 # This program is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU General Public Licence
10 # as published by the Free Software Foundation; either version
11 # 2 of the Licence, or (at your option) any later version.
12 #
13 ###############################################################################
14 #include <linux/sys.h>
15 #include <linux/linkage.h>
16 #include <asm/thread_info.h>
17 #include <asm/cpu-regs.h>
18 #ifdef CONFIG_SMP
19 #include <proc/smp-regs.h>
20 #endif /* CONFIG_SMP */
21
22 .text
23
24 ###############################################################################
25 #
26 # struct task_struct *__switch_to(struct thread_struct *prev,
27 # struct thread_struct *next,
28 # struct task_struct *prev_task)
29 #
30 ###############################################################################
31 ENTRY(__switch_to)
32 movm [d2,d3,a2,a3,exreg1],(sp)
33 or EPSW_NMID,epsw
34
35 mov (44,sp),d2
36
37 mov d0,a0
38 mov d1,a1
39
40 # save prev context
41 mov __switch_back,d0
42 mov sp,a2
43 mov a2,(THREAD_SP,a0)
44 mov a3,(THREAD_A3,a0)
45
46 #ifdef CONFIG_KGDB
47 btst 0xff,(kgdb_single_step)
48 bne __switch_to__lift_sstep_bp
49 __switch_to__continue:
50 #endif
51 mov d0,(THREAD_PC,a0)
52
53 mov (THREAD_A3,a1),a3
54 mov (THREAD_SP,a1),a2
55
56 # switch
57 mov a2,sp
58
59 # load next context
60 GET_THREAD_INFO a2
61 mov a2,(__current_ti)
62 mov (TI_task,a2),a2
63 mov a2,(__current)
64 #ifdef CONFIG_MN10300_CURRENT_IN_E2
65 mov a2,e2
66 #endif
67
68 mov (THREAD_PC,a1),a2
69 mov d2,d0 # for ret_from_fork
70 mov d0,a0 # for __switch_to
71
72 jmp (a2)
73
74 __switch_back:
75 and ~EPSW_NMID,epsw
76 ret [d2,d3,a2,a3,exreg1],32
77
78 #ifdef CONFIG_KGDB
79 ###############################################################################
80 #
81 # Lift the single-step breakpoints when the task being traced is switched out
82 # A0 = prev
83 # A1 = next
84 #
85 ###############################################################################
86 __switch_to__lift_sstep_bp:
87 add -12,sp
88 mov a0,e4
89 mov a1,e5
90
91 # Clear the single-step flag to prevent us coming this way until we get
92 # switched back in
93 bclr 0xff,(kgdb_single_step)
94
95 # Remove first breakpoint
96 mov (kgdb_sstep_bp_addr),a2
97 cmp 0,a2
98 beq 1f
99 movbu (kgdb_sstep_bp),d0
100 movbu d0,(a2)
101 #if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE)
102 mov a2,d0
103 mov a2,d1
104 add 1,d1
105 calls flush_icache_range
106 #endif
107 1:
108
109 # Remove second breakpoint
110 mov (kgdb_sstep_bp_addr+4),a2
111 cmp 0,a2
112 beq 2f
113 movbu (kgdb_sstep_bp+1),d0
114 movbu d0,(a2)
115 #if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE)
116 mov a2,d0
117 mov a2,d1
118 add 1,d1
119 calls flush_icache_range
120 #endif
121 2:
122
123 # Change the resumption address and return
124 mov __switch_back__reinstall_sstep_bp,d0
125 mov e4,a0
126 mov e5,a1
127 add 12,sp
128 bra __switch_to__continue
129
130 ###############################################################################
131 #
132 # Reinstall the single-step breakpoints when the task being traced is switched
133 # back in (A1 points to the new thread_struct).
134 #
135 ###############################################################################
136 __switch_back__reinstall_sstep_bp:
137 add -12,sp
138 mov a0,e4 # save the return value
139 mov 0xff,d3
140
141 # Reinstall first breakpoint
142 mov (kgdb_sstep_bp_addr),a2
143 cmp 0,a2
144 beq 1f
145 movbu (a2),d0
146 movbu d0,(kgdb_sstep_bp)
147 movbu d3,(a2)
148 #if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE)
149 mov a2,d0
150 mov a2,d1
151 add 1,d1
152 calls flush_icache_range
153 #endif
154 1:
155
156 # Reinstall second breakpoint
157 mov (kgdb_sstep_bp_addr+4),a2
158 cmp 0,a2
159 beq 2f
160 movbu (a2),d0
161 movbu d0,(kgdb_sstep_bp+1)
162 movbu d3,(a2)
163 #if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE)
164 mov a2,d0
165 mov a2,d1
166 add 1,d1
167 calls flush_icache_range
168 #endif
169 2:
170
171 mov d3,(kgdb_single_step)
172
173 # Restore the return value (the previous thread_struct pointer)
174 mov e4,a0
175 mov a0,d0
176 add 12,sp
177 bra __switch_back
178
179 #endif /* CONFIG_KGDB */