diff options
Diffstat (limited to 'arch/mn10300/kernel/switch_to.S')
-rw-r--r-- | arch/mn10300/kernel/switch_to.S | 111 |
1 files changed, 110 insertions, 1 deletions
diff --git a/arch/mn10300/kernel/switch_to.S b/arch/mn10300/kernel/switch_to.S index 9074d0fb8788..de3e74fc9ea0 100644 --- a/arch/mn10300/kernel/switch_to.S +++ b/arch/mn10300/kernel/switch_to.S | |||
@@ -39,11 +39,17 @@ ENTRY(__switch_to) | |||
39 | 39 | ||
40 | # save prev context | 40 | # save prev context |
41 | mov __switch_back,d0 | 41 | mov __switch_back,d0 |
42 | mov d0,(THREAD_PC,a0) | ||
43 | mov sp,a2 | 42 | mov sp,a2 |
44 | mov a2,(THREAD_SP,a0) | 43 | mov a2,(THREAD_SP,a0) |
45 | mov a3,(THREAD_A3,a0) | 44 | mov a3,(THREAD_A3,a0) |
46 | 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 | |||
47 | mov (THREAD_A3,a1),a3 | 53 | mov (THREAD_A3,a1),a3 |
48 | mov (THREAD_SP,a1),a2 | 54 | mov (THREAD_SP,a1),a2 |
49 | 55 | ||
@@ -68,3 +74,106 @@ ENTRY(__switch_to) | |||
68 | __switch_back: | 74 | __switch_back: |
69 | and ~EPSW_NMID,epsw | 75 | and ~EPSW_NMID,epsw |
70 | ret [d2,d3,a2,a3,exreg1],32 | 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 */ | ||