Commit | Line | Data |
---|---|---|
b920de1b DH |
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> | |
368dd5ac AT |
18 | #ifdef CONFIG_SMP |
19 | #include <proc/smp-regs.h> | |
20 | #endif /* CONFIG_SMP */ | |
b920de1b DH |
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 | |
b920de1b | 41 | mov __switch_back,d0 |
b920de1b DH |
42 | mov sp,a2 |
43 | mov a2,(THREAD_SP,a0) | |
44 | mov a3,(THREAD_A3,a0) | |
45 | ||
5141c46c DH |
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 | ||
b920de1b DH |
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 | ||
b920de1b DH |
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 | |
5141c46c DH |
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 */ |