|
2
|
1 /*=========================================================================== |
|
|
2 // |
|
|
3 // vec_xvsr.S |
|
|
4 // |
|
|
5 // SPARClite vectors: exception vector service routine |
|
|
6 // |
|
|
7 //=========================================================================== |
|
|
8 //####COPYRIGHTBEGIN#### |
|
|
9 // |
|
|
10 // ------------------------------------------- |
|
|
11 // The contents of this file are subject to the Cygnus eCos Public License |
|
|
12 // Version 1.0 (the "License"); you may not use this file except in |
|
|
13 // compliance with the License. You may obtain a copy of the License at |
|
|
14 // http://sourceware.cygnus.com/ecos |
|
|
15 // |
|
|
16 // Software distributed under the License is distributed on an "AS IS" |
|
|
17 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the |
|
|
18 // License for the specific language governing rights and limitations under |
|
|
19 // the License. |
|
|
20 // |
|
|
21 // The Original Code is eCos - Embedded Cygnus Operating System, released |
|
|
22 // September 30, 1998. |
|
|
23 // |
|
|
24 // The Initial Developer of the Original Code is Cygnus. Portions created |
|
|
25 // by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. |
|
|
26 // ------------------------------------------- |
|
|
27 // |
|
|
28 //###COPYRIGHTEND#### |
|
|
29 //=========================================================================== |
|
|
30 //#####DESCRIPTIONBEGIN#### |
|
|
31 // |
|
|
32 // Author(s): hmt |
|
|
33 // Contributors: hmt |
|
|
34 // Date: 1999-02-20 |
|
|
35 // Purpose: SPARClite vector code |
|
|
36 // Description: see vectors.S; this is the default vector service routine |
|
|
37 // for exceptions. |
|
|
38 // |
|
|
39 //####DESCRIPTIONEND#### |
|
|
40 // |
|
|
41 //=========================================================================*/ |
|
|
42 |
|
|
43 !----------------------------------------------------------------------------- |
|
|
44 |
|
|
45 .file "vec_xvsr.S" |
|
|
46 |
|
|
47 !---------------------------------------------------------------------------- |
|
|
48 |
|
|
49 #include <pkgconf/system.h> |
|
|
50 #include <pkgconf/hal.h> |
|
|
51 |
|
|
52 #ifdef CYGPKG_KERNEL |
|
|
53 # include <pkgconf/kernel.h> |
|
|
54 #endif |
|
|
55 |
|
|
56 !------------------------------------------------------------------------ |
|
|
57 |
|
|
58 #include <cyg/hal/vectors.h> |
|
|
59 |
|
|
60 #define DELAYS_AFTER_WRPSR_SAME_WINDOW |
|
|
61 #define DELAYS_AFTER_WRWIM |
|
|
62 |
|
|
63 !------------------------------------------------------------------------ |
|
|
64 |
|
|
65 .text |
|
|
66 |
|
|
67 !--------------------------------------------------------------------------- |
|
|
68 ! default exception handler VSR, which calls the appropriate ISR after |
|
|
69 ! interrupt masking - much the same as the interrupt VSR but does not lock |
|
|
70 ! scheduler or call interrupt_end(). |
|
|
71 |
|
|
72 .global hal_default_exception_vsr |
|
|
73 hal_default_exception_vsr: |
|
|
74 ! here,locals have been set up as follows: |
|
|
75 ! %l0 = psr (with this CWP/window-level in it) |
|
|
76 ! %l1 = pc |
|
|
77 ! %l2 = npc |
|
|
78 ! %l3 = vector number (16-25 for traps) |
|
|
79 ! and we are in our own register window, though it is likely that |
|
|
80 ! the next one will need to be saved before we can use it: |
|
|
81 ! ie. this one is the invalid register window. |
|
|
82 |
|
|
83 ! must establish a safe stack before re-enabling interrupts + traps |
|
|
84 and %l0, __WINBITS, %l7 ! CWP extracted |
|
|
85 mov 1, %l6 |
|
|
86 sll %l6, %l7, %l6 ! 1 << CWP |
|
|
87 rd %wim, %l5 |
|
|
88 cmp %l5, %l6 ! are they the same? |
|
|
89 bne 1f ! No, so the stack is OK as is. |
|
|
90 |
|
|
91 ! now do by hand an overflow trap, effectively |
|
|
92 mov %g1, %l7 ! (DELAY SLOT) |
|
|
93 srl %l5, 1, %l5 |
|
|
94 sll %l6, __WINSIZE-1, %l6 |
|
|
95 or %l6, %l5, %g1 ! new WIM in %g1 so we can get it |
|
|
96 ! within the save: |
|
|
97 save ! Slip into next window |
|
|
98 mov %g1, %wim ! Install the new wim |
|
|
99 ! (invalidates current window!) |
|
|
100 #ifdef DELAYS_AFTER_WRWIM |
|
|
101 nop |
|
|
102 nop |
|
|
103 nop |
|
|
104 #endif |
|
|
105 |
|
|
106 std %l0, [%sp + 0 * 4] ! save L & I registers |
|
|
107 std %l2, [%sp + 2 * 4] |
|
|
108 std %l4, [%sp + 4 * 4] |
|
|
109 std %l6, [%sp + 6 * 4] |
|
|
110 |
|
|
111 std %i0, [%sp + 8 * 4] |
|
|
112 std %i2, [%sp + 10 * 4] |
|
|
113 std %i4, [%sp + 12 * 4] |
|
|
114 std %i6, [%sp + 14 * 4] |
|
|
115 |
|
|
116 restore ! Go back to trap window. |
|
|
117 mov %l7, %g1 ! Restore %g1 |
|
|
118 |
|
|
119 1: ! now save away the regs we must preserve |
|
|
120 sub %fp, 32 * 4, %sp |
|
|
121 ! save a maximal context regardless: see also |
|
|
122 ! CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT |
|
|
123 std %l0, [%sp + 0 * 4] ! save L & I registers |
|
|
124 std %l2, [%sp + 2 * 4] |
|
|
125 std %l4, [%sp + 4 * 4] |
|
|
126 std %l6, [%sp + 6 * 4] |
|
|
127 |
|
|
128 std %i0, [%sp + 8 * 4] |
|
|
129 std %i2, [%sp + 10 * 4] |
|
|
130 std %i4, [%sp + 12 * 4] |
|
|
131 std %i6, [%sp + 14 * 4] |
|
|
132 |
|
|
133 st %g1, [%sp + 17 * 4] ! save G registers |
|
|
134 std %g2, [%sp + 18 * 4] |
|
|
135 std %g4, [%sp + 20 * 4] |
|
|
136 std %g6, [%sp + 22 * 4] |
|
|
137 |
|
|
138 ! no point whatsoever in saving O registers |
|
|
139 |
|
|
140 ! and save the CWP in %g0 save place |
|
|
141 st %l0, [%sp + 16 * 4] |
|
|
142 |
|
|
143 sub %sp, 24 * 4, %sp ! fresh frame including |
|
|
144 ! arg spill area for callees |
|
|
145 |
|
|
146 ! do not lock the scheduler |
|
|
147 |
|
|
148 ! HELP_GDB_WITH_BACKTRACE |
|
|
149 mov %i7, %l5 ! preserve it JIC |
|
|
150 mov %l1, %i7 ! bogus return link here |
|
|
151 |
|
|
152 ! and we must preserve the Y register (multiply/divide auxiliary) |
|
|
153 ! over these calls; we will keep it in %l4 which is otherwise unused. |
|
|
154 rd %y, %l4 |
|
|
155 |
|
|
156 ! Now we can reenable traps (preserving interrupt level) |
|
|
157 or %l0, 0x0e0, %l7 ! set ET (+S,PS), preserve PIL |
|
|
158 wr %l7, %psr ! and enable! |
|
|
159 #ifdef DELAYS_AFTER_WRPSR_SAME_WINDOW |
|
|
160 nop |
|
|
161 nop |
|
|
162 nop |
|
|
163 #endif |
|
|
164 ! now call the XSR and so on with the appropriate args: |
|
|
165 ! ie. |
|
|
166 ! isr_retcode = (*(hal_interrupt_handlers[ vector ])) |
|
|
167 ! ( vector, hal_interrupt_data[ vector ], stackp ); |
|
|
168 |
|
|
169 ! from hal_arch.h |
|
|
170 !// ISR tables |
|
|
171 !CYG_ADDRESS hal_interrupt_handlers[CYGNUM_HAL_ISR_COUNT]; |
|
|
172 !CYG_ADDRWORD hal_interrupt_data[CYGNUM_HAL_ISR_COUNT]; |
|
|
173 !CYG_ADDRESS hal_interrupt_objects[CYGNUM_HAL_ISR_COUNT]; |
|
|
174 |
|
|
175 mov %l3, %o0 |
|
|
176 sll %l3, 2, %l3 ! %l3 to a word offset |
|
|
177 sethi %hi(hal_interrupt_data), %l7 |
|
|
178 or %l7, %lo(hal_interrupt_data), %l7 |
|
|
179 ld [ %l7 + %l3 ], %o1 ! data |
|
|
180 add %sp, 24 * 4, %o2 ! stackpointer of saved regset |
|
|
181 |
|
|
182 sethi %hi(hal_interrupt_handlers), %l7 |
|
|
183 or %l7, %lo(hal_interrupt_handlers), %l7 |
|
|
184 ld [ %l7 + %l3 ], %l6 |
|
|
185 call %l6 |
|
|
186 nop |
|
|
187 |
|
|
188 ! do not call _interrupt_end() |
|
|
189 |
|
|
190 ! restore the Y register having done our callouts to C |
|
|
191 wr %l4, %y |
|
|
192 |
|
|
193 ! We can reinstall the original CWP here; even if interrupt_end() |
|
|
194 ! performed a reschedule (ie. yield/resume pair) we will be in the |
|
|
195 ! same window. The window is preserved by reschedule precisely |
|
|
196 ! because it is impossible atomically to disable traps here without |
|
|
197 ! involving a CWP living in a register for a time when other |
|
|
198 ! interrupts may occur. |
|
|
199 |
|
|
200 ! disable traps (using the saved psr is fastest way) |
|
|
201 wr %l0, %psr ! restores flags, disables traps, same PIL. |
|
|
202 #ifdef DELAYS_AFTER_WRPSR_SAME_WINDOW |
|
|
203 nop |
|
|
204 nop |
|
|
205 nop |
|
|
206 #endif |
|
|
207 ! HELP_GDB_WITH_BACKTRACE |
|
|
208 mov %l5, %i7 ! restore (unused) return link |
|
|
209 |
|
|
210 ! and restore other saved regs |
|
|
211 add %sp, 24 * 4, %sp ! undo fresh frame |
|
|
212 ! restore a maximal context regardless: see also |
|
|
213 ! CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT |
|
|
214 ldd [%sp + 0 * 4], %l0 ! restore L & I registers |
|
|
215 ldd [%sp + 2 * 4], %l2 ! to support the handler |
|
|
216 ldd [%sp + 4 * 4], %l4 ! having messed with them. |
|
|
217 ldd [%sp + 6 * 4], %l6 |
|
|
218 |
|
|
219 ldd [%sp + 8 * 4], %i0 |
|
|
220 ldd [%sp + 10 * 4], %i2 |
|
|
221 ldd [%sp + 12 * 4], %i4 |
|
|
222 ldd [%sp + 14 * 4], %i6 |
|
|
223 |
|
|
224 ld [%sp + 17 * 4], %g1 ! and G registers |
|
|
225 ldd [%sp + 18 * 4], %g2 |
|
|
226 ldd [%sp + 20 * 4], %g4 |
|
|
227 ldd [%sp + 22 * 4], %g6 |
|
|
228 ! no point whatsoever in loading back O registers. |
|
|
229 |
|
|
230 ! Now test for window underflow here and fix up if needs be. |
|
|
231 ! |
|
|
232 ! Why? interrupt_end() might have yielded us, when only |
|
|
233 ! its own frame was restored; its own return to us caused a |
|
|
234 ! window underflow trap, as would our return to interruptee |
|
|
235 ! unless we deal with it now. |
|
|
236 |
|
|
237 add %l0, 1, %l7 ! interruptee~s CWP plus noise |
|
|
238 and %l7, __WINBITS, %l7 ! CWP only |
|
|
239 mov 1, %l6 |
|
|
240 sll %l6, %l7, %l6 ! 1 << CWP |
|
|
241 rd %wim, %l5 |
|
|
242 cmp %l5, %l6 ! are they the same? |
|
|
243 bne 2f ! No, so the stack is OK as is. |
|
|
244 |
|
|
245 ! now do by hand an underflow trap, effectively |
|
|
246 sll %l5, 1, %l5 ! Rotate wim left |
|
|
247 srl %l6, __WINSIZE-1, %l6 |
|
|
248 wr %l5, %l6, %wim |
|
|
249 #ifdef DELAYS_AFTER_WRWIM |
|
|
250 nop ! are these delays needed? |
|
|
251 nop ! (following restore uses wim) |
|
|
252 nop |
|
|
253 #endif |
|
|
254 restore ! Interruptee~s window |
|
|
255 ldd [%sp + 0 * 4], %l0 ! restore L & I registers |
|
|
256 ldd [%sp + 2 * 4], %l2 |
|
|
257 ldd [%sp + 4 * 4], %l4 |
|
|
258 ldd [%sp + 6 * 4], %l6 |
|
|
259 |
|
|
260 ldd [%sp + 8 * 4], %i0 |
|
|
261 ldd [%sp + 10 * 4], %i2 |
|
|
262 ldd [%sp + 12 * 4], %i4 |
|
|
263 ldd [%sp + 14 * 4], %i6 |
|
|
264 save ! Back to trap window |
|
|
265 |
|
|
266 2: ! restore the condition codes, PSR and PIL and return from trap. |
|
|
267 wr %l0, %psr ! restores flags, disables traps, and old PIL |
|
|
268 #ifdef DELAYS_AFTER_WRPSR_SAME_WINDOW |
|
|
269 nop |
|
|
270 nop |
|
|
271 nop |
|
|
272 #endif |
|
|
273 jmpl %l1, %g0 |
|
|
274 rett %l2 |
|
|
275 |
|
|
276 |
|
|
277 ! end of vec_xvsr.S |