diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-05 11:59:22 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-05 11:59:22 -0400 |
commit | bbc4fd12a635492ad9d12bb418124fa2d5f0d734 (patch) | |
tree | fe245d350db180d499a9e9d6dc84bbb308f33dc2 /arch/microblaze/kernel/entry.S | |
parent | 673b864fd76a29031aa0b4b08fc80886d527b3b7 (diff) | |
parent | 2d5973cb5ac5d04662f86e19a06a4c52fa4c4ae3 (diff) |
Merge branch 'for-linus' of git://git.monstr.eu/linux-2.6-microblaze
* 'for-linus' of git://git.monstr.eu/linux-2.6-microblaze: (49 commits)
microblaze: Add KGDB support
microblaze: Support brki rX, 0x18 for user application debugging
microblaze: Remove nop after MSRCLR/SET, MTS, MFS instructions
microblaze: Simplify syscall rutine
microblaze: Move PT_MODE saving to delay slot
microblaze: Fix _interrupt function
microblaze: Fix _user_exception function
microblaze: Put together addik instructions
microblaze: Use delay slot in syscall macros
microblaze: Save kernel mode in delay slot
microblaze: Do not mix register saving and mode setting
microblaze: Move SAVE_STATE upward
microblaze: entry.S: Macro optimization
microblaze: Optimize hw exception rutine
microblaze: Implement clear_ums macro and fix SAVE_STATE macro
microblaze: Remove additional setup for kernel_mode
microblaze: Optimize SAVE_STATE macro
microblaze: Remove additional loading
microblaze: Completely remove working with R11 register
microblaze: Do not setup BIP in _debug_exception
...
Diffstat (limited to 'arch/microblaze/kernel/entry.S')
-rw-r--r-- | arch/microblaze/kernel/entry.S | 607 |
1 files changed, 242 insertions, 365 deletions
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S index c0ede25c5b99..304882e56459 100644 --- a/arch/microblaze/kernel/entry.S +++ b/arch/microblaze/kernel/entry.S | |||
@@ -48,128 +48,107 @@ | |||
48 | */ | 48 | */ |
49 | #if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR | 49 | #if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR |
50 | .macro clear_bip | 50 | .macro clear_bip |
51 | msrclr r11, MSR_BIP | 51 | msrclr r0, MSR_BIP |
52 | nop | ||
53 | .endm | 52 | .endm |
54 | 53 | ||
55 | .macro set_bip | 54 | .macro set_bip |
56 | msrset r11, MSR_BIP | 55 | msrset r0, MSR_BIP |
57 | nop | ||
58 | .endm | 56 | .endm |
59 | 57 | ||
60 | .macro clear_eip | 58 | .macro clear_eip |
61 | msrclr r11, MSR_EIP | 59 | msrclr r0, MSR_EIP |
62 | nop | ||
63 | .endm | 60 | .endm |
64 | 61 | ||
65 | .macro set_ee | 62 | .macro set_ee |
66 | msrset r11, MSR_EE | 63 | msrset r0, MSR_EE |
67 | nop | ||
68 | .endm | 64 | .endm |
69 | 65 | ||
70 | .macro disable_irq | 66 | .macro disable_irq |
71 | msrclr r11, MSR_IE | 67 | msrclr r0, MSR_IE |
72 | nop | ||
73 | .endm | 68 | .endm |
74 | 69 | ||
75 | .macro enable_irq | 70 | .macro enable_irq |
76 | msrset r11, MSR_IE | 71 | msrset r0, MSR_IE |
77 | nop | ||
78 | .endm | 72 | .endm |
79 | 73 | ||
80 | .macro set_ums | 74 | .macro set_ums |
81 | msrset r11, MSR_UMS | 75 | msrset r0, MSR_UMS |
82 | nop | 76 | msrclr r0, MSR_VMS |
83 | msrclr r11, MSR_VMS | ||
84 | nop | ||
85 | .endm | 77 | .endm |
86 | 78 | ||
87 | .macro set_vms | 79 | .macro set_vms |
88 | msrclr r11, MSR_UMS | 80 | msrclr r0, MSR_UMS |
89 | nop | 81 | msrset r0, MSR_VMS |
90 | msrset r11, MSR_VMS | 82 | .endm |
91 | nop | 83 | |
84 | .macro clear_ums | ||
85 | msrclr r0, MSR_UMS | ||
92 | .endm | 86 | .endm |
93 | 87 | ||
94 | .macro clear_vms_ums | 88 | .macro clear_vms_ums |
95 | msrclr r11, MSR_VMS | 89 | msrclr r0, MSR_VMS | MSR_UMS |
96 | nop | ||
97 | msrclr r11, MSR_UMS | ||
98 | nop | ||
99 | .endm | 90 | .endm |
100 | #else | 91 | #else |
101 | .macro clear_bip | 92 | .macro clear_bip |
102 | mfs r11, rmsr | 93 | mfs r11, rmsr |
103 | nop | ||
104 | andi r11, r11, ~MSR_BIP | 94 | andi r11, r11, ~MSR_BIP |
105 | mts rmsr, r11 | 95 | mts rmsr, r11 |
106 | nop | ||
107 | .endm | 96 | .endm |
108 | 97 | ||
109 | .macro set_bip | 98 | .macro set_bip |
110 | mfs r11, rmsr | 99 | mfs r11, rmsr |
111 | nop | ||
112 | ori r11, r11, MSR_BIP | 100 | ori r11, r11, MSR_BIP |
113 | mts rmsr, r11 | 101 | mts rmsr, r11 |
114 | nop | ||
115 | .endm | 102 | .endm |
116 | 103 | ||
117 | .macro clear_eip | 104 | .macro clear_eip |
118 | mfs r11, rmsr | 105 | mfs r11, rmsr |
119 | nop | ||
120 | andi r11, r11, ~MSR_EIP | 106 | andi r11, r11, ~MSR_EIP |
121 | mts rmsr, r11 | 107 | mts rmsr, r11 |
122 | nop | ||
123 | .endm | 108 | .endm |
124 | 109 | ||
125 | .macro set_ee | 110 | .macro set_ee |
126 | mfs r11, rmsr | 111 | mfs r11, rmsr |
127 | nop | ||
128 | ori r11, r11, MSR_EE | 112 | ori r11, r11, MSR_EE |
129 | mts rmsr, r11 | 113 | mts rmsr, r11 |
130 | nop | ||
131 | .endm | 114 | .endm |
132 | 115 | ||
133 | .macro disable_irq | 116 | .macro disable_irq |
134 | mfs r11, rmsr | 117 | mfs r11, rmsr |
135 | nop | ||
136 | andi r11, r11, ~MSR_IE | 118 | andi r11, r11, ~MSR_IE |
137 | mts rmsr, r11 | 119 | mts rmsr, r11 |
138 | nop | ||
139 | .endm | 120 | .endm |
140 | 121 | ||
141 | .macro enable_irq | 122 | .macro enable_irq |
142 | mfs r11, rmsr | 123 | mfs r11, rmsr |
143 | nop | ||
144 | ori r11, r11, MSR_IE | 124 | ori r11, r11, MSR_IE |
145 | mts rmsr, r11 | 125 | mts rmsr, r11 |
146 | nop | ||
147 | .endm | 126 | .endm |
148 | 127 | ||
149 | .macro set_ums | 128 | .macro set_ums |
150 | mfs r11, rmsr | 129 | mfs r11, rmsr |
151 | nop | ||
152 | ori r11, r11, MSR_VMS | 130 | ori r11, r11, MSR_VMS |
153 | andni r11, r11, MSR_UMS | 131 | andni r11, r11, MSR_UMS |
154 | mts rmsr, r11 | 132 | mts rmsr, r11 |
155 | nop | ||
156 | .endm | 133 | .endm |
157 | 134 | ||
158 | .macro set_vms | 135 | .macro set_vms |
159 | mfs r11, rmsr | 136 | mfs r11, rmsr |
160 | nop | ||
161 | ori r11, r11, MSR_VMS | 137 | ori r11, r11, MSR_VMS |
162 | andni r11, r11, MSR_UMS | 138 | andni r11, r11, MSR_UMS |
163 | mts rmsr, r11 | 139 | mts rmsr, r11 |
164 | nop | 140 | .endm |
141 | |||
142 | .macro clear_ums | ||
143 | mfs r11, rmsr | ||
144 | andni r11, r11, MSR_UMS | ||
145 | mts rmsr,r11 | ||
165 | .endm | 146 | .endm |
166 | 147 | ||
167 | .macro clear_vms_ums | 148 | .macro clear_vms_ums |
168 | mfs r11, rmsr | 149 | mfs r11, rmsr |
169 | nop | ||
170 | andni r11, r11, (MSR_VMS|MSR_UMS) | 150 | andni r11, r11, (MSR_VMS|MSR_UMS) |
171 | mts rmsr,r11 | 151 | mts rmsr,r11 |
172 | nop | ||
173 | .endm | 152 | .endm |
174 | #endif | 153 | #endif |
175 | 154 | ||
@@ -180,18 +159,22 @@ | |||
180 | 159 | ||
181 | /* turn on virtual protected mode save */ | 160 | /* turn on virtual protected mode save */ |
182 | #define VM_ON \ | 161 | #define VM_ON \ |
183 | set_ums; \ | 162 | set_ums; \ |
184 | rted r0, 2f; \ | 163 | rted r0, 2f; \ |
185 | 2: nop; | 164 | nop; \ |
165 | 2: | ||
186 | 166 | ||
187 | /* turn off virtual protected mode save and user mode save*/ | 167 | /* turn off virtual protected mode save and user mode save*/ |
188 | #define VM_OFF \ | 168 | #define VM_OFF \ |
189 | clear_vms_ums; \ | 169 | clear_vms_ums; \ |
190 | rted r0, TOPHYS(1f); \ | 170 | rted r0, TOPHYS(1f); \ |
191 | 1: nop; | 171 | nop; \ |
172 | 1: | ||
192 | 173 | ||
193 | #define SAVE_REGS \ | 174 | #define SAVE_REGS \ |
194 | swi r2, r1, PTO+PT_R2; /* Save SDA */ \ | 175 | swi r2, r1, PTO+PT_R2; /* Save SDA */ \ |
176 | swi r3, r1, PTO+PT_R3; \ | ||
177 | swi r4, r1, PTO+PT_R4; \ | ||
195 | swi r5, r1, PTO+PT_R5; \ | 178 | swi r5, r1, PTO+PT_R5; \ |
196 | swi r6, r1, PTO+PT_R6; \ | 179 | swi r6, r1, PTO+PT_R6; \ |
197 | swi r7, r1, PTO+PT_R7; \ | 180 | swi r7, r1, PTO+PT_R7; \ |
@@ -218,14 +201,14 @@ | |||
218 | swi r30, r1, PTO+PT_R30; \ | 201 | swi r30, r1, PTO+PT_R30; \ |
219 | swi r31, r1, PTO+PT_R31; /* Save current task reg */ \ | 202 | swi r31, r1, PTO+PT_R31; /* Save current task reg */ \ |
220 | mfs r11, rmsr; /* save MSR */ \ | 203 | mfs r11, rmsr; /* save MSR */ \ |
221 | nop; \ | ||
222 | swi r11, r1, PTO+PT_MSR; | 204 | swi r11, r1, PTO+PT_MSR; |
223 | 205 | ||
224 | #define RESTORE_REGS \ | 206 | #define RESTORE_REGS \ |
225 | lwi r11, r1, PTO+PT_MSR; \ | 207 | lwi r11, r1, PTO+PT_MSR; \ |
226 | mts rmsr , r11; \ | 208 | mts rmsr , r11; \ |
227 | nop; \ | ||
228 | lwi r2, r1, PTO+PT_R2; /* restore SDA */ \ | 209 | lwi r2, r1, PTO+PT_R2; /* restore SDA */ \ |
210 | lwi r3, r1, PTO+PT_R3; \ | ||
211 | lwi r4, r1, PTO+PT_R4; \ | ||
229 | lwi r5, r1, PTO+PT_R5; \ | 212 | lwi r5, r1, PTO+PT_R5; \ |
230 | lwi r6, r1, PTO+PT_R6; \ | 213 | lwi r6, r1, PTO+PT_R6; \ |
231 | lwi r7, r1, PTO+PT_R7; \ | 214 | lwi r7, r1, PTO+PT_R7; \ |
@@ -252,6 +235,39 @@ | |||
252 | lwi r30, r1, PTO+PT_R30; \ | 235 | lwi r30, r1, PTO+PT_R30; \ |
253 | lwi r31, r1, PTO+PT_R31; /* Restore cur task reg */ | 236 | lwi r31, r1, PTO+PT_R31; /* Restore cur task reg */ |
254 | 237 | ||
238 | #define SAVE_STATE \ | ||
239 | swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* save stack */ \ | ||
240 | /* See if already in kernel mode.*/ \ | ||
241 | mfs r1, rmsr; \ | ||
242 | andi r1, r1, MSR_UMS; \ | ||
243 | bnei r1, 1f; \ | ||
244 | /* Kernel-mode state save. */ \ | ||
245 | /* Reload kernel stack-ptr. */ \ | ||
246 | lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); \ | ||
247 | /* FIXME: I can add these two lines to one */ \ | ||
248 | /* tophys(r1,r1); */ \ | ||
249 | /* addik r1, r1, -STATE_SAVE_SIZE; */ \ | ||
250 | addik r1, r1, CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE; \ | ||
251 | SAVE_REGS \ | ||
252 | brid 2f; \ | ||
253 | swi r1, r1, PTO+PT_MODE; \ | ||
254 | 1: /* User-mode state save. */ \ | ||
255 | lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */\ | ||
256 | tophys(r1,r1); \ | ||
257 | lwi r1, r1, TS_THREAD_INFO; /* get the thread info */ \ | ||
258 | /* MS these three instructions can be added to one */ \ | ||
259 | /* addik r1, r1, THREAD_SIZE; */ \ | ||
260 | /* tophys(r1,r1); */ \ | ||
261 | /* addik r1, r1, -STATE_SAVE_SIZE; */ \ | ||
262 | addik r1, r1, THREAD_SIZE + CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE; \ | ||
263 | SAVE_REGS \ | ||
264 | lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); \ | ||
265 | swi r11, r1, PTO+PT_R1; /* Store user SP. */ \ | ||
266 | swi r0, r1, PTO + PT_MODE; /* Was in user-mode. */ \ | ||
267 | /* MS: I am clearing UMS even in case when I come from kernel space */ \ | ||
268 | clear_ums; \ | ||
269 | 2: lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); | ||
270 | |||
255 | .text | 271 | .text |
256 | 272 | ||
257 | /* | 273 | /* |
@@ -267,45 +283,23 @@ | |||
267 | * are masked. This is nice, means we don't have to CLI before state save | 283 | * are masked. This is nice, means we don't have to CLI before state save |
268 | */ | 284 | */ |
269 | C_ENTRY(_user_exception): | 285 | C_ENTRY(_user_exception): |
270 | swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)) /* save stack */ | ||
271 | addi r14, r14, 4 /* return address is 4 byte after call */ | 286 | addi r14, r14, 4 /* return address is 4 byte after call */ |
272 | swi r11, r0, TOPHYS(r0_ram + PTO + PT_R11); /* Save r11 */ | 287 | swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)) /* save stack */ |
273 | |||
274 | lwi r11, r0, TOPHYS(PER_CPU(KM));/* See if already in kernel mode.*/ | ||
275 | beqi r11, 1f; /* Jump ahead if coming from user */ | ||
276 | /* Kernel-mode state save. */ | ||
277 | lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* Reload kernel stack-ptr*/ | ||
278 | tophys(r1,r11); | ||
279 | swi r11, r1, (PT_R1-PT_SIZE); /* Save original SP. */ | ||
280 | lwi r11, r0, TOPHYS(r0_ram + PTO + PT_R11); /* restore r11 */ | ||
281 | |||
282 | addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */ | ||
283 | SAVE_REGS | ||
284 | |||
285 | addi r11, r0, 1; /* Was in kernel-mode. */ | ||
286 | swi r11, r1, PTO+PT_MODE; /* pt_regs -> kernel mode */ | ||
287 | brid 2f; | ||
288 | nop; /* Fill delay slot */ | ||
289 | 288 | ||
290 | /* User-mode state save. */ | ||
291 | 1: | ||
292 | lwi r11, r0, TOPHYS(r0_ram + PTO + PT_R11); /* restore r11 */ | ||
293 | lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */ | 289 | lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */ |
294 | tophys(r1,r1); | 290 | tophys(r1,r1); |
295 | lwi r1, r1, TS_THREAD_INFO; /* get stack from task_struct */ | 291 | lwi r1, r1, TS_THREAD_INFO; /* get stack from task_struct */ |
296 | /* calculate kernel stack pointer from task struct 8k */ | 292 | /* MS these three instructions can be added to one */ |
297 | addik r1, r1, THREAD_SIZE; | 293 | /* addik r1, r1, THREAD_SIZE; */ |
298 | tophys(r1,r1); | 294 | /* tophys(r1,r1); */ |
299 | 295 | /* addik r1, r1, -STATE_SAVE_SIZE; */ | |
300 | addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */ | 296 | addik r1, r1, THREAD_SIZE + CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE; |
301 | SAVE_REGS | 297 | SAVE_REGS |
302 | 298 | ||
303 | swi r0, r1, PTO+PT_MODE; /* Was in user-mode. */ | ||
304 | lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); | 299 | lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); |
305 | swi r11, r1, PTO+PT_R1; /* Store user SP. */ | 300 | swi r11, r1, PTO+PT_R1; /* Store user SP. */ |
306 | addi r11, r0, 1; | 301 | clear_ums; |
307 | swi r11, r0, TOPHYS(PER_CPU(KM)); /* Now we're in kernel-mode. */ | 302 | lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); |
308 | 2: lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); | ||
309 | /* Save away the syscall number. */ | 303 | /* Save away the syscall number. */ |
310 | swi r12, r1, PTO+PT_R0; | 304 | swi r12, r1, PTO+PT_R0; |
311 | tovirt(r1,r1) | 305 | tovirt(r1,r1) |
@@ -316,10 +310,8 @@ C_ENTRY(_user_exception): | |||
316 | * register should point to the location where | 310 | * register should point to the location where |
317 | * the called function should return. [note that MAKE_SYS_CALL uses label 1] */ | 311 | * the called function should return. [note that MAKE_SYS_CALL uses label 1] */ |
318 | 312 | ||
319 | # Step into virtual mode. | 313 | /* Step into virtual mode */ |
320 | set_vms; | 314 | rtbd r0, 3f |
321 | addik r11, r0, 3f | ||
322 | rtid r11, 0 | ||
323 | nop | 315 | nop |
324 | 3: | 316 | 3: |
325 | lwi r11, CURRENT_TASK, TS_THREAD_INFO /* get thread info */ | 317 | lwi r11, CURRENT_TASK, TS_THREAD_INFO /* get thread info */ |
@@ -363,24 +355,17 @@ C_ENTRY(_user_exception): | |||
363 | # Find and jump into the syscall handler. | 355 | # Find and jump into the syscall handler. |
364 | lwi r12, r12, sys_call_table | 356 | lwi r12, r12, sys_call_table |
365 | /* where the trap should return need -8 to adjust for rtsd r15, 8 */ | 357 | /* where the trap should return need -8 to adjust for rtsd r15, 8 */ |
366 | la r15, r0, ret_from_trap-8 | 358 | addi r15, r0, ret_from_trap-8 |
367 | bra r12 | 359 | bra r12 |
368 | 360 | ||
369 | /* The syscall number is invalid, return an error. */ | 361 | /* The syscall number is invalid, return an error. */ |
370 | 5: | 362 | 5: |
363 | rtsd r15, 8; /* looks like a normal subroutine return */ | ||
371 | addi r3, r0, -ENOSYS; | 364 | addi r3, r0, -ENOSYS; |
372 | rtsd r15,8; /* looks like a normal subroutine return */ | ||
373 | or r0, r0, r0 | ||
374 | |||
375 | 365 | ||
376 | /* Entry point used to return from a syscall/trap */ | 366 | /* Entry point used to return from a syscall/trap */ |
377 | /* We re-enable BIP bit before state restore */ | 367 | /* We re-enable BIP bit before state restore */ |
378 | C_ENTRY(ret_from_trap): | 368 | C_ENTRY(ret_from_trap): |
379 | set_bip; /* Ints masked for state restore*/ | ||
380 | lwi r11, r1, PTO+PT_MODE; | ||
381 | /* See if returning to kernel mode, if so, skip resched &c. */ | ||
382 | bnei r11, 2f; | ||
383 | |||
384 | swi r3, r1, PTO + PT_R3 | 369 | swi r3, r1, PTO + PT_R3 |
385 | swi r4, r1, PTO + PT_R4 | 370 | swi r4, r1, PTO + PT_R4 |
386 | 371 | ||
@@ -413,32 +398,19 @@ C_ENTRY(ret_from_trap): | |||
413 | andi r11, r11, _TIF_SIGPENDING; | 398 | andi r11, r11, _TIF_SIGPENDING; |
414 | beqi r11, 1f; /* Signals to handle, handle them */ | 399 | beqi r11, 1f; /* Signals to handle, handle them */ |
415 | 400 | ||
416 | la r5, r1, PTO; /* Arg 1: struct pt_regs *regs */ | 401 | addik r5, r1, PTO; /* Arg 1: struct pt_regs *regs */ |
417 | addi r7, r0, 1; /* Arg 3: int in_syscall */ | 402 | addi r7, r0, 1; /* Arg 3: int in_syscall */ |
418 | bralid r15, do_signal; /* Handle any signals */ | 403 | bralid r15, do_signal; /* Handle any signals */ |
419 | add r6, r0, r0; /* Arg 2: sigset_t *oldset */ | 404 | add r6, r0, r0; /* Arg 2: sigset_t *oldset */ |
420 | 405 | ||
421 | /* Finally, return to user state. */ | 406 | /* Finally, return to user state. */ |
422 | 1: | 407 | 1: set_bip; /* Ints masked for state restore */ |
423 | lwi r3, r1, PTO + PT_R3; /* restore syscall result */ | ||
424 | lwi r4, r1, PTO + PT_R4; | ||
425 | |||
426 | swi r0, r0, PER_CPU(KM); /* Now officially in user state. */ | ||
427 | swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */ | 408 | swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */ |
428 | VM_OFF; | 409 | VM_OFF; |
429 | tophys(r1,r1); | 410 | tophys(r1,r1); |
430 | RESTORE_REGS; | 411 | RESTORE_REGS; |
431 | addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */ | 412 | addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */ |
432 | lwi r1, r1, PT_R1 - PT_SIZE;/* Restore user stack pointer. */ | 413 | lwi r1, r1, PT_R1 - PT_SIZE;/* Restore user stack pointer. */ |
433 | bri 6f; | ||
434 | |||
435 | /* Return to kernel state. */ | ||
436 | 2: VM_OFF; | ||
437 | tophys(r1,r1); | ||
438 | RESTORE_REGS; | ||
439 | addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */ | ||
440 | tovirt(r1,r1); | ||
441 | 6: | ||
442 | TRAP_return: /* Make global symbol for debugging */ | 414 | TRAP_return: /* Make global symbol for debugging */ |
443 | rtbd r14, 0; /* Instructions to return from an IRQ */ | 415 | rtbd r14, 0; /* Instructions to return from an IRQ */ |
444 | nop; | 416 | nop; |
@@ -450,12 +422,11 @@ TRAP_return: /* Make global symbol for debugging */ | |||
450 | C_ENTRY(sys_fork_wrapper): | 422 | C_ENTRY(sys_fork_wrapper): |
451 | addi r5, r0, SIGCHLD /* Arg 0: flags */ | 423 | addi r5, r0, SIGCHLD /* Arg 0: flags */ |
452 | lwi r6, r1, PTO+PT_R1 /* Arg 1: child SP (use parent's) */ | 424 | lwi r6, r1, PTO+PT_R1 /* Arg 1: child SP (use parent's) */ |
453 | la r7, r1, PTO /* Arg 2: parent context */ | 425 | addik r7, r1, PTO /* Arg 2: parent context */ |
454 | add r8. r0, r0 /* Arg 3: (unused) */ | 426 | add r8. r0, r0 /* Arg 3: (unused) */ |
455 | add r9, r0, r0; /* Arg 4: (unused) */ | 427 | add r9, r0, r0; /* Arg 4: (unused) */ |
456 | add r10, r0, r0; /* Arg 5: (unused) */ | ||
457 | brid do_fork /* Do real work (tail-call) */ | 428 | brid do_fork /* Do real work (tail-call) */ |
458 | nop; | 429 | add r10, r0, r0; /* Arg 5: (unused) */ |
459 | 430 | ||
460 | /* This the initial entry point for a new child thread, with an appropriate | 431 | /* This the initial entry point for a new child thread, with an appropriate |
461 | stack in place that makes it look the the child is in the middle of an | 432 | stack in place that makes it look the the child is in the middle of an |
@@ -466,35 +437,31 @@ C_ENTRY(ret_from_fork): | |||
466 | bralid r15, schedule_tail; /* ...which is schedule_tail's arg */ | 437 | bralid r15, schedule_tail; /* ...which is schedule_tail's arg */ |
467 | add r3, r5, r0; /* switch_thread returns the prev task */ | 438 | add r3, r5, r0; /* switch_thread returns the prev task */ |
468 | /* ( in the delay slot ) */ | 439 | /* ( in the delay slot ) */ |
469 | add r3, r0, r0; /* Child's fork call should return 0. */ | ||
470 | brid ret_from_trap; /* Do normal trap return */ | 440 | brid ret_from_trap; /* Do normal trap return */ |
471 | nop; | 441 | add r3, r0, r0; /* Child's fork call should return 0. */ |
472 | 442 | ||
473 | C_ENTRY(sys_vfork): | 443 | C_ENTRY(sys_vfork): |
474 | brid microblaze_vfork /* Do real work (tail-call) */ | 444 | brid microblaze_vfork /* Do real work (tail-call) */ |
475 | la r5, r1, PTO | 445 | addik r5, r1, PTO |
476 | 446 | ||
477 | C_ENTRY(sys_clone): | 447 | C_ENTRY(sys_clone): |
478 | bnei r6, 1f; /* See if child SP arg (arg 1) is 0. */ | 448 | bnei r6, 1f; /* See if child SP arg (arg 1) is 0. */ |
479 | lwi r6, r1, PTO+PT_R1; /* If so, use paret's stack ptr */ | 449 | lwi r6, r1, PTO + PT_R1; /* If so, use paret's stack ptr */ |
480 | 1: la r7, r1, PTO; /* Arg 2: parent context */ | 450 | 1: addik r7, r1, PTO; /* Arg 2: parent context */ |
481 | add r8, r0, r0; /* Arg 3: (unused) */ | 451 | add r8, r0, r0; /* Arg 3: (unused) */ |
482 | add r9, r0, r0; /* Arg 4: (unused) */ | 452 | add r9, r0, r0; /* Arg 4: (unused) */ |
483 | add r10, r0, r0; /* Arg 5: (unused) */ | ||
484 | brid do_fork /* Do real work (tail-call) */ | 453 | brid do_fork /* Do real work (tail-call) */ |
485 | nop; | 454 | add r10, r0, r0; /* Arg 5: (unused) */ |
486 | 455 | ||
487 | C_ENTRY(sys_execve): | 456 | C_ENTRY(sys_execve): |
488 | la r8, r1, PTO; /* add user context as 4th arg */ | ||
489 | brid microblaze_execve; /* Do real work (tail-call).*/ | 457 | brid microblaze_execve; /* Do real work (tail-call).*/ |
490 | nop; | 458 | addik r8, r1, PTO; /* add user context as 4th arg */ |
491 | 459 | ||
492 | C_ENTRY(sys_rt_sigreturn_wrapper): | 460 | C_ENTRY(sys_rt_sigreturn_wrapper): |
493 | swi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */ | 461 | swi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */ |
494 | swi r4, r1, PTO+PT_R4; | 462 | swi r4, r1, PTO+PT_R4; |
495 | la r5, r1, PTO; /* add user context as 1st arg */ | ||
496 | brlid r15, sys_rt_sigreturn /* Do real work */ | 463 | brlid r15, sys_rt_sigreturn /* Do real work */ |
497 | nop; | 464 | addik r5, r1, PTO; /* add user context as 1st arg */ |
498 | lwi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */ | 465 | lwi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */ |
499 | lwi r4, r1, PTO+PT_R4; | 466 | lwi r4, r1, PTO+PT_R4; |
500 | bri ret_from_trap /* fall through will not work here due to align */ | 467 | bri ret_from_trap /* fall through will not work here due to align */ |
@@ -503,83 +470,23 @@ C_ENTRY(sys_rt_sigreturn_wrapper): | |||
503 | /* | 470 | /* |
504 | * HW EXCEPTION rutine start | 471 | * HW EXCEPTION rutine start |
505 | */ | 472 | */ |
506 | |||
507 | #define SAVE_STATE \ | ||
508 | swi r11, r0, TOPHYS(r0_ram + PTO + PT_R11); /* Save r11 */ \ | ||
509 | set_bip; /*equalize initial state for all possible entries*/\ | ||
510 | clear_eip; \ | ||
511 | enable_irq; \ | ||
512 | set_ee; \ | ||
513 | /* See if already in kernel mode.*/ \ | ||
514 | lwi r11, r0, TOPHYS(PER_CPU(KM)); \ | ||
515 | beqi r11, 1f; /* Jump ahead if coming from user */\ | ||
516 | /* Kernel-mode state save. */ \ | ||
517 | /* Reload kernel stack-ptr. */ \ | ||
518 | lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); \ | ||
519 | tophys(r1,r11); \ | ||
520 | swi r11, r1, (PT_R1-PT_SIZE); /* Save original SP. */ \ | ||
521 | lwi r11, r0, TOPHYS(r0_ram + PTO + PT_R11); /* restore r11 */\ | ||
522 | addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */\ | ||
523 | /* store return registers separately because \ | ||
524 | * this macros is use for others exceptions */ \ | ||
525 | swi r3, r1, PTO + PT_R3; \ | ||
526 | swi r4, r1, PTO + PT_R4; \ | ||
527 | SAVE_REGS \ | ||
528 | /* PC, before IRQ/trap - this is one instruction above */ \ | ||
529 | swi r17, r1, PTO+PT_PC; \ | ||
530 | \ | ||
531 | addi r11, r0, 1; /* Was in kernel-mode. */ \ | ||
532 | swi r11, r1, PTO+PT_MODE; \ | ||
533 | brid 2f; \ | ||
534 | nop; /* Fill delay slot */ \ | ||
535 | 1: /* User-mode state save. */ \ | ||
536 | lwi r11, r0, TOPHYS(r0_ram + PTO + PT_R11); /* restore r11 */\ | ||
537 | lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */\ | ||
538 | tophys(r1,r1); \ | ||
539 | lwi r1, r1, TS_THREAD_INFO; /* get the thread info */ \ | ||
540 | addik r1, r1, THREAD_SIZE; /* calculate kernel stack pointer */\ | ||
541 | tophys(r1,r1); \ | ||
542 | \ | ||
543 | addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */\ | ||
544 | /* store return registers separately because this macros \ | ||
545 | * is use for others exceptions */ \ | ||
546 | swi r3, r1, PTO + PT_R3; \ | ||
547 | swi r4, r1, PTO + PT_R4; \ | ||
548 | SAVE_REGS \ | ||
549 | /* PC, before IRQ/trap - this is one instruction above FIXME*/ \ | ||
550 | swi r17, r1, PTO+PT_PC; \ | ||
551 | \ | ||
552 | swi r0, r1, PTO+PT_MODE; /* Was in user-mode. */ \ | ||
553 | lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); \ | ||
554 | swi r11, r1, PTO+PT_R1; /* Store user SP. */ \ | ||
555 | addi r11, r0, 1; \ | ||
556 | swi r11, r0, TOPHYS(PER_CPU(KM)); /* Now we're in kernel-mode.*/\ | ||
557 | 2: lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); \ | ||
558 | /* Save away the syscall number. */ \ | ||
559 | swi r0, r1, PTO+PT_R0; \ | ||
560 | tovirt(r1,r1) | ||
561 | |||
562 | C_ENTRY(full_exception_trap): | 473 | C_ENTRY(full_exception_trap): |
563 | swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)) /* save stack */ | ||
564 | /* adjust exception address for privileged instruction | 474 | /* adjust exception address for privileged instruction |
565 | * for finding where is it */ | 475 | * for finding where is it */ |
566 | addik r17, r17, -4 | 476 | addik r17, r17, -4 |
567 | SAVE_STATE /* Save registers */ | 477 | SAVE_STATE /* Save registers */ |
478 | /* PC, before IRQ/trap - this is one instruction above */ | ||
479 | swi r17, r1, PTO+PT_PC; | ||
480 | tovirt(r1,r1) | ||
568 | /* FIXME this can be store directly in PT_ESR reg. | 481 | /* FIXME this can be store directly in PT_ESR reg. |
569 | * I tested it but there is a fault */ | 482 | * I tested it but there is a fault */ |
570 | /* where the trap should return need -8 to adjust for rtsd r15, 8 */ | 483 | /* where the trap should return need -8 to adjust for rtsd r15, 8 */ |
571 | la r15, r0, ret_from_exc - 8 | 484 | addik r15, r0, ret_from_exc - 8 |
572 | la r5, r1, PTO /* parameter struct pt_regs * regs */ | ||
573 | mfs r6, resr | 485 | mfs r6, resr |
574 | nop | ||
575 | mfs r7, rfsr; /* save FSR */ | 486 | mfs r7, rfsr; /* save FSR */ |
576 | nop | ||
577 | mts rfsr, r0; /* Clear sticky fsr */ | 487 | mts rfsr, r0; /* Clear sticky fsr */ |
578 | nop | 488 | rted r0, full_exception |
579 | la r12, r0, full_exception | 489 | addik r5, r1, PTO /* parameter struct pt_regs * regs */ |
580 | set_vms; | ||
581 | rtbd r12, 0; | ||
582 | nop; | ||
583 | 490 | ||
584 | /* | 491 | /* |
585 | * Unaligned data trap. | 492 | * Unaligned data trap. |
@@ -592,19 +499,27 @@ C_ENTRY(full_exception_trap): | |||
592 | * The assembler routine is in "arch/microblaze/kernel/hw_exception_handler.S" | 499 | * The assembler routine is in "arch/microblaze/kernel/hw_exception_handler.S" |
593 | */ | 500 | */ |
594 | C_ENTRY(unaligned_data_trap): | 501 | C_ENTRY(unaligned_data_trap): |
595 | swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)) /* save stack */ | 502 | /* MS: I have to save r11 value and then restore it because |
503 | * set_bit, clear_eip, set_ee use r11 as temp register if MSR | ||
504 | * instructions are not used. We don't need to do if MSR instructions | ||
505 | * are used and they use r0 instead of r11. | ||
506 | * I am using ENTRY_SP which should be primary used only for stack | ||
507 | * pointer saving. */ | ||
508 | swi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); | ||
509 | set_bip; /* equalize initial state for all possible entries */ | ||
510 | clear_eip; | ||
511 | set_ee; | ||
512 | lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); | ||
596 | SAVE_STATE /* Save registers.*/ | 513 | SAVE_STATE /* Save registers.*/ |
514 | /* PC, before IRQ/trap - this is one instruction above */ | ||
515 | swi r17, r1, PTO+PT_PC; | ||
516 | tovirt(r1,r1) | ||
597 | /* where the trap should return need -8 to adjust for rtsd r15, 8 */ | 517 | /* where the trap should return need -8 to adjust for rtsd r15, 8 */ |
598 | la r15, r0, ret_from_exc-8 | 518 | addik r15, r0, ret_from_exc-8 |
599 | mfs r3, resr /* ESR */ | 519 | mfs r3, resr /* ESR */ |
600 | nop | ||
601 | mfs r4, rear /* EAR */ | 520 | mfs r4, rear /* EAR */ |
602 | nop | 521 | rtbd r0, _unaligned_data_exception |
603 | la r7, r1, PTO /* parameter struct pt_regs * regs */ | 522 | addik r7, r1, PTO /* parameter struct pt_regs * regs */ |
604 | la r12, r0, _unaligned_data_exception | ||
605 | set_vms; | ||
606 | rtbd r12, 0; /* interrupts enabled */ | ||
607 | nop; | ||
608 | 523 | ||
609 | /* | 524 | /* |
610 | * Page fault traps. | 525 | * Page fault traps. |
@@ -625,38 +540,32 @@ C_ENTRY(unaligned_data_trap): | |||
625 | */ | 540 | */ |
626 | /* data and intruction trap - which is choose is resolved int fault.c */ | 541 | /* data and intruction trap - which is choose is resolved int fault.c */ |
627 | C_ENTRY(page_fault_data_trap): | 542 | C_ENTRY(page_fault_data_trap): |
628 | swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)) /* save stack */ | ||
629 | SAVE_STATE /* Save registers.*/ | 543 | SAVE_STATE /* Save registers.*/ |
544 | /* PC, before IRQ/trap - this is one instruction above */ | ||
545 | swi r17, r1, PTO+PT_PC; | ||
546 | tovirt(r1,r1) | ||
630 | /* where the trap should return need -8 to adjust for rtsd r15, 8 */ | 547 | /* where the trap should return need -8 to adjust for rtsd r15, 8 */ |
631 | la r15, r0, ret_from_exc-8 | 548 | addik r15, r0, ret_from_exc-8 |
632 | la r5, r1, PTO /* parameter struct pt_regs * regs */ | ||
633 | mfs r6, rear /* parameter unsigned long address */ | 549 | mfs r6, rear /* parameter unsigned long address */ |
634 | nop | ||
635 | mfs r7, resr /* parameter unsigned long error_code */ | 550 | mfs r7, resr /* parameter unsigned long error_code */ |
636 | nop | 551 | rted r0, do_page_fault |
637 | la r12, r0, do_page_fault | 552 | addik r5, r1, PTO /* parameter struct pt_regs * regs */ |
638 | set_vms; | ||
639 | rtbd r12, 0; /* interrupts enabled */ | ||
640 | nop; | ||
641 | 553 | ||
642 | C_ENTRY(page_fault_instr_trap): | 554 | C_ENTRY(page_fault_instr_trap): |
643 | swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)) /* save stack */ | ||
644 | SAVE_STATE /* Save registers.*/ | 555 | SAVE_STATE /* Save registers.*/ |
556 | /* PC, before IRQ/trap - this is one instruction above */ | ||
557 | swi r17, r1, PTO+PT_PC; | ||
558 | tovirt(r1,r1) | ||
645 | /* where the trap should return need -8 to adjust for rtsd r15, 8 */ | 559 | /* where the trap should return need -8 to adjust for rtsd r15, 8 */ |
646 | la r15, r0, ret_from_exc-8 | 560 | addik r15, r0, ret_from_exc-8 |
647 | la r5, r1, PTO /* parameter struct pt_regs * regs */ | ||
648 | mfs r6, rear /* parameter unsigned long address */ | 561 | mfs r6, rear /* parameter unsigned long address */ |
649 | nop | ||
650 | ori r7, r0, 0 /* parameter unsigned long error_code */ | 562 | ori r7, r0, 0 /* parameter unsigned long error_code */ |
651 | la r12, r0, do_page_fault | 563 | rted r0, do_page_fault |
652 | set_vms; | 564 | addik r5, r1, PTO /* parameter struct pt_regs * regs */ |
653 | rtbd r12, 0; /* interrupts enabled */ | ||
654 | nop; | ||
655 | 565 | ||
656 | /* Entry point used to return from an exception. */ | 566 | /* Entry point used to return from an exception. */ |
657 | C_ENTRY(ret_from_exc): | 567 | C_ENTRY(ret_from_exc): |
658 | set_bip; /* Ints masked for state restore*/ | 568 | lwi r11, r1, PTO + PT_MODE; |
659 | lwi r11, r1, PTO+PT_MODE; | ||
660 | bnei r11, 2f; /* See if returning to kernel mode, */ | 569 | bnei r11, 2f; /* See if returning to kernel mode, */ |
661 | /* ... if so, skip resched &c. */ | 570 | /* ... if so, skip resched &c. */ |
662 | 571 | ||
@@ -687,32 +596,27 @@ C_ENTRY(ret_from_exc): | |||
687 | * traps), but signal handlers may want to examine or change the | 596 | * traps), but signal handlers may want to examine or change the |
688 | * complete register state. Here we save anything not saved by | 597 | * complete register state. Here we save anything not saved by |
689 | * the normal entry sequence, so that it may be safely restored | 598 | * the normal entry sequence, so that it may be safely restored |
690 | * (in a possibly modified form) after do_signal returns. | 599 | * (in a possibly modified form) after do_signal returns. */ |
691 | * store return registers separately because this macros is use | 600 | addik r5, r1, PTO; /* Arg 1: struct pt_regs *regs */ |
692 | * for others exceptions */ | ||
693 | la r5, r1, PTO; /* Arg 1: struct pt_regs *regs */ | ||
694 | addi r7, r0, 0; /* Arg 3: int in_syscall */ | 601 | addi r7, r0, 0; /* Arg 3: int in_syscall */ |
695 | bralid r15, do_signal; /* Handle any signals */ | 602 | bralid r15, do_signal; /* Handle any signals */ |
696 | add r6, r0, r0; /* Arg 2: sigset_t *oldset */ | 603 | add r6, r0, r0; /* Arg 2: sigset_t *oldset */ |
697 | 604 | ||
698 | /* Finally, return to user state. */ | 605 | /* Finally, return to user state. */ |
699 | 1: swi r0, r0, PER_CPU(KM); /* Now officially in user state. */ | 606 | 1: set_bip; /* Ints masked for state restore */ |
700 | swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */ | 607 | swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */ |
701 | VM_OFF; | 608 | VM_OFF; |
702 | tophys(r1,r1); | 609 | tophys(r1,r1); |
703 | 610 | ||
704 | lwi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */ | ||
705 | lwi r4, r1, PTO+PT_R4; | ||
706 | RESTORE_REGS; | 611 | RESTORE_REGS; |
707 | addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */ | 612 | addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */ |
708 | 613 | ||
709 | lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer. */ | 614 | lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer. */ |
710 | bri 6f; | 615 | bri 6f; |
711 | /* Return to kernel state. */ | 616 | /* Return to kernel state. */ |
712 | 2: VM_OFF; | 617 | 2: set_bip; /* Ints masked for state restore */ |
618 | VM_OFF; | ||
713 | tophys(r1,r1); | 619 | tophys(r1,r1); |
714 | lwi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */ | ||
715 | lwi r4, r1, PTO+PT_R4; | ||
716 | RESTORE_REGS; | 620 | RESTORE_REGS; |
717 | addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */ | 621 | addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */ |
718 | 622 | ||
@@ -736,36 +640,23 @@ C_ENTRY(_interrupt): | |||
736 | /* MS: we are in physical address */ | 640 | /* MS: we are in physical address */ |
737 | /* Save registers, switch to proper stack, convert SP to virtual.*/ | 641 | /* Save registers, switch to proper stack, convert SP to virtual.*/ |
738 | swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)) | 642 | swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)) |
739 | swi r11, r0, TOPHYS(PER_CPU(R11_SAVE)); | ||
740 | /* MS: See if already in kernel mode. */ | 643 | /* MS: See if already in kernel mode. */ |
741 | lwi r11, r0, TOPHYS(PER_CPU(KM)); | 644 | mfs r1, rmsr |
742 | beqi r11, 1f; /* MS: Jump ahead if coming from user */ | 645 | nop |
646 | andi r1, r1, MSR_UMS | ||
647 | bnei r1, 1f | ||
743 | 648 | ||
744 | /* Kernel-mode state save. */ | 649 | /* Kernel-mode state save. */ |
745 | or r11, r1, r0 | 650 | lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)) |
746 | tophys(r1,r11); /* MS: I have in r1 physical address where stack is */ | 651 | tophys(r1,r1); /* MS: I have in r1 physical address where stack is */ |
747 | /* MS: Save original SP - position PT_R1 to next stack frame 4 *1 - 152*/ | ||
748 | swi r11, r1, (PT_R1 - PT_SIZE); | ||
749 | /* MS: restore r11 because of saving in SAVE_REGS */ | ||
750 | lwi r11, r0, TOPHYS(PER_CPU(R11_SAVE)); | ||
751 | /* save registers */ | 652 | /* save registers */ |
752 | /* MS: Make room on the stack -> activation record */ | 653 | /* MS: Make room on the stack -> activation record */ |
753 | addik r1, r1, -STATE_SAVE_SIZE; | 654 | addik r1, r1, -STATE_SAVE_SIZE; |
754 | /* MS: store return registers separately because | ||
755 | * this macros is use for others exceptions */ | ||
756 | swi r3, r1, PTO + PT_R3; | ||
757 | swi r4, r1, PTO + PT_R4; | ||
758 | SAVE_REGS | 655 | SAVE_REGS |
759 | /* MS: store mode */ | ||
760 | addi r11, r0, 1; /* MS: Was in kernel-mode. */ | ||
761 | swi r11, r1, PTO + PT_MODE; /* MS: and save it */ | ||
762 | brid 2f; | 656 | brid 2f; |
763 | nop; /* MS: Fill delay slot */ | 657 | swi r1, r1, PTO + PT_MODE; /* 0 - user mode, 1 - kernel mode */ |
764 | |||
765 | 1: | 658 | 1: |
766 | /* User-mode state save. */ | 659 | /* User-mode state save. */ |
767 | /* MS: restore r11 -> FIXME move before SAVE_REG */ | ||
768 | lwi r11, r0, TOPHYS(PER_CPU(R11_SAVE)); | ||
769 | /* MS: get the saved current */ | 660 | /* MS: get the saved current */ |
770 | lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); | 661 | lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); |
771 | tophys(r1,r1); | 662 | tophys(r1,r1); |
@@ -774,27 +665,18 @@ C_ENTRY(_interrupt): | |||
774 | tophys(r1,r1); | 665 | tophys(r1,r1); |
775 | /* save registers */ | 666 | /* save registers */ |
776 | addik r1, r1, -STATE_SAVE_SIZE; | 667 | addik r1, r1, -STATE_SAVE_SIZE; |
777 | swi r3, r1, PTO+PT_R3; | ||
778 | swi r4, r1, PTO+PT_R4; | ||
779 | SAVE_REGS | 668 | SAVE_REGS |
780 | /* calculate mode */ | 669 | /* calculate mode */ |
781 | swi r0, r1, PTO + PT_MODE; | 670 | swi r0, r1, PTO + PT_MODE; |
782 | lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); | 671 | lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); |
783 | swi r11, r1, PTO+PT_R1; | 672 | swi r11, r1, PTO+PT_R1; |
784 | /* setup kernel mode to KM */ | 673 | clear_ums; |
785 | addi r11, r0, 1; | ||
786 | swi r11, r0, TOPHYS(PER_CPU(KM)); | ||
787 | |||
788 | 2: | 674 | 2: |
789 | lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); | 675 | lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); |
790 | swi r0, r1, PTO + PT_R0; | ||
791 | tovirt(r1,r1) | 676 | tovirt(r1,r1) |
792 | la r5, r1, PTO; | 677 | addik r15, r0, irq_call; |
793 | set_vms; | 678 | irq_call:rtbd r0, do_IRQ; |
794 | la r11, r0, do_IRQ; | 679 | addik r5, r1, PTO; |
795 | la r15, r0, irq_call; | ||
796 | irq_call:rtbd r11, 0; | ||
797 | nop; | ||
798 | 680 | ||
799 | /* MS: we are in virtual mode */ | 681 | /* MS: we are in virtual mode */ |
800 | ret_from_irq: | 682 | ret_from_irq: |
@@ -815,7 +697,7 @@ ret_from_irq: | |||
815 | beqid r11, no_intr_resched | 697 | beqid r11, no_intr_resched |
816 | /* Handle a signal return; Pending signals should be in r18. */ | 698 | /* Handle a signal return; Pending signals should be in r18. */ |
817 | addi r7, r0, 0; /* Arg 3: int in_syscall */ | 699 | addi r7, r0, 0; /* Arg 3: int in_syscall */ |
818 | la r5, r1, PTO; /* Arg 1: struct pt_regs *regs */ | 700 | addik r5, r1, PTO; /* Arg 1: struct pt_regs *regs */ |
819 | bralid r15, do_signal; /* Handle any signals */ | 701 | bralid r15, do_signal; /* Handle any signals */ |
820 | add r6, r0, r0; /* Arg 2: sigset_t *oldset */ | 702 | add r6, r0, r0; /* Arg 2: sigset_t *oldset */ |
821 | 703 | ||
@@ -823,12 +705,9 @@ ret_from_irq: | |||
823 | no_intr_resched: | 705 | no_intr_resched: |
824 | /* Disable interrupts, we are now committed to the state restore */ | 706 | /* Disable interrupts, we are now committed to the state restore */ |
825 | disable_irq | 707 | disable_irq |
826 | swi r0, r0, PER_CPU(KM); /* MS: Now officially in user state. */ | ||
827 | swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); | 708 | swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); |
828 | VM_OFF; | 709 | VM_OFF; |
829 | tophys(r1,r1); | 710 | tophys(r1,r1); |
830 | lwi r3, r1, PTO + PT_R3; /* MS: restore saved r3, r4 registers */ | ||
831 | lwi r4, r1, PTO + PT_R4; | ||
832 | RESTORE_REGS | 711 | RESTORE_REGS |
833 | addik r1, r1, STATE_SAVE_SIZE /* MS: Clean up stack space. */ | 712 | addik r1, r1, STATE_SAVE_SIZE /* MS: Clean up stack space. */ |
834 | lwi r1, r1, PT_R1 - PT_SIZE; | 713 | lwi r1, r1, PT_R1 - PT_SIZE; |
@@ -857,8 +736,6 @@ restore: | |||
857 | #endif | 736 | #endif |
858 | VM_OFF /* MS: turn off MMU */ | 737 | VM_OFF /* MS: turn off MMU */ |
859 | tophys(r1,r1) | 738 | tophys(r1,r1) |
860 | lwi r3, r1, PTO + PT_R3; /* MS: restore saved r3, r4 registers */ | ||
861 | lwi r4, r1, PTO + PT_R4; | ||
862 | RESTORE_REGS | 739 | RESTORE_REGS |
863 | addik r1, r1, STATE_SAVE_SIZE /* MS: Clean up stack space. */ | 740 | addik r1, r1, STATE_SAVE_SIZE /* MS: Clean up stack space. */ |
864 | tovirt(r1,r1); | 741 | tovirt(r1,r1); |
@@ -868,86 +745,91 @@ IRQ_return: /* MS: Make global symbol for debugging */ | |||
868 | nop | 745 | nop |
869 | 746 | ||
870 | /* | 747 | /* |
871 | * `Debug' trap | 748 | * Debug trap for KGDB. Enter to _debug_exception by brki r16, 0x18 |
872 | * We enter dbtrap in "BIP" (breakpoint) mode. | 749 | * and call handling function with saved pt_regs |
873 | * So we exit the breakpoint mode with an 'rtbd' and proceed with the | ||
874 | * original dbtrap. | ||
875 | * however, wait to save state first | ||
876 | */ | 750 | */ |
877 | C_ENTRY(_debug_exception): | 751 | C_ENTRY(_debug_exception): |
878 | /* BIP bit is set on entry, no interrupts can occur */ | 752 | /* BIP bit is set on entry, no interrupts can occur */ |
879 | swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)) | 753 | swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)) |
880 | 754 | ||
881 | swi r11, r0, TOPHYS(r0_ram + PTO + PT_R11); /* Save r11 */ | 755 | mfs r1, rmsr |
882 | set_bip; /*equalize initial state for all possible entries*/ | 756 | nop |
883 | clear_eip; | 757 | andi r1, r1, MSR_UMS |
884 | enable_irq; | 758 | bnei r1, 1f |
885 | lwi r11, r0, TOPHYS(PER_CPU(KM));/* See if already in kernel mode.*/ | 759 | /* MS: Kernel-mode state save - kgdb */ |
886 | beqi r11, 1f; /* Jump ahead if coming from user */ | 760 | lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* Reload kernel stack-ptr*/ |
887 | /* Kernel-mode state save. */ | ||
888 | lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* Reload kernel stack-ptr*/ | ||
889 | tophys(r1,r11); | ||
890 | swi r11, r1, (PT_R1-PT_SIZE); /* Save original SP. */ | ||
891 | lwi r11, r0, TOPHYS(r0_ram + PTO + PT_R11); /* restore r11 */ | ||
892 | 761 | ||
893 | addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */ | 762 | /* BIP bit is set on entry, no interrupts can occur */ |
894 | swi r3, r1, PTO + PT_R3; | 763 | addik r1, r1, CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE; |
895 | swi r4, r1, PTO + PT_R4; | ||
896 | SAVE_REGS; | 764 | SAVE_REGS; |
765 | /* save all regs to pt_reg structure */ | ||
766 | swi r0, r1, PTO+PT_R0; /* R0 must be saved too */ | ||
767 | swi r14, r1, PTO+PT_R14 /* rewrite saved R14 value */ | ||
768 | swi r16, r1, PTO+PT_R16 | ||
769 | swi r16, r1, PTO+PT_PC; /* PC and r16 are the same */ | ||
770 | swi r17, r1, PTO+PT_R17 | ||
771 | /* save special purpose registers to pt_regs */ | ||
772 | mfs r11, rear; | ||
773 | swi r11, r1, PTO+PT_EAR; | ||
774 | mfs r11, resr; | ||
775 | swi r11, r1, PTO+PT_ESR; | ||
776 | mfs r11, rfsr; | ||
777 | swi r11, r1, PTO+PT_FSR; | ||
778 | |||
779 | /* stack pointer is in physical address at it is decrease | ||
780 | * by STATE_SAVE_SIZE but we need to get correct R1 value */ | ||
781 | addik r11, r1, CONFIG_KERNEL_START - CONFIG_KERNEL_BASE_ADDR + STATE_SAVE_SIZE; | ||
782 | swi r11, r1, PTO+PT_R1 | ||
783 | /* MS: r31 - current pointer isn't changed */ | ||
784 | tovirt(r1,r1) | ||
785 | #ifdef CONFIG_KGDB | ||
786 | addi r5, r1, PTO /* pass pt_reg address as the first arg */ | ||
787 | la r15, r0, dbtrap_call; /* return address */ | ||
788 | rtbd r0, microblaze_kgdb_break | ||
789 | nop; | ||
790 | #endif | ||
791 | /* MS: Place handler for brki from kernel space if KGDB is OFF. | ||
792 | * It is very unlikely that another brki instruction is called. */ | ||
793 | bri 0 | ||
897 | 794 | ||
898 | addi r11, r0, 1; /* Was in kernel-mode. */ | 795 | /* MS: User-mode state save - gdb */ |
899 | swi r11, r1, PTO + PT_MODE; | 796 | 1: lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */ |
900 | brid 2f; | ||
901 | nop; /* Fill delay slot */ | ||
902 | 1: /* User-mode state save. */ | ||
903 | lwi r11, r0, TOPHYS(r0_ram + PTO + PT_R11); /* restore r11 */ | ||
904 | lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */ | ||
905 | tophys(r1,r1); | 797 | tophys(r1,r1); |
906 | lwi r1, r1, TS_THREAD_INFO; /* get the thread info */ | 798 | lwi r1, r1, TS_THREAD_INFO; /* get the thread info */ |
907 | addik r1, r1, THREAD_SIZE; /* calculate kernel stack pointer */ | 799 | addik r1, r1, THREAD_SIZE; /* calculate kernel stack pointer */ |
908 | tophys(r1,r1); | 800 | tophys(r1,r1); |
909 | 801 | ||
910 | addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */ | 802 | addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */ |
911 | swi r3, r1, PTO + PT_R3; | ||
912 | swi r4, r1, PTO + PT_R4; | ||
913 | SAVE_REGS; | 803 | SAVE_REGS; |
914 | 804 | swi r17, r1, PTO+PT_R17; | |
915 | swi r0, r1, PTO+PT_MODE; /* Was in user-mode. */ | 805 | swi r16, r1, PTO+PT_R16; |
806 | swi r16, r1, PTO+PT_PC; /* Save LP */ | ||
807 | swi r0, r1, PTO + PT_MODE; /* Was in user-mode. */ | ||
916 | lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); | 808 | lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); |
917 | swi r11, r1, PTO+PT_R1; /* Store user SP. */ | 809 | swi r11, r1, PTO+PT_R1; /* Store user SP. */ |
918 | addi r11, r0, 1; | 810 | lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); |
919 | swi r11, r0, TOPHYS(PER_CPU(KM)); /* Now we're in kernel-mode. */ | ||
920 | 2: lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); | ||
921 | /* Save away the syscall number. */ | ||
922 | swi r0, r1, PTO+PT_R0; | ||
923 | tovirt(r1,r1) | 811 | tovirt(r1,r1) |
924 | |||
925 | addi r5, r0, SIGTRAP /* send the trap signal */ | ||
926 | add r6, r0, CURRENT_TASK; /* Get current task ptr into r11 */ | ||
927 | addk r7, r0, r0 /* 3rd param zero */ | ||
928 | |||
929 | set_vms; | 812 | set_vms; |
930 | la r11, r0, send_sig; | 813 | addik r5, r1, PTO; |
931 | la r15, r0, dbtrap_call; | 814 | addik r15, r0, dbtrap_call; |
932 | dbtrap_call: rtbd r11, 0; | 815 | dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */ |
933 | nop; | 816 | rtbd r0, sw_exception |
817 | nop | ||
934 | 818 | ||
935 | set_bip; /* Ints masked for state restore*/ | 819 | /* MS: The first instruction for the second part of the gdb/kgdb */ |
936 | lwi r11, r1, PTO+PT_MODE; | 820 | set_bip; /* Ints masked for state restore */ |
821 | lwi r11, r1, PTO + PT_MODE; | ||
937 | bnei r11, 2f; | 822 | bnei r11, 2f; |
938 | 823 | /* MS: Return to user space - gdb */ | |
939 | /* Get current task ptr into r11 */ | 824 | /* Get current task ptr into r11 */ |
940 | lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */ | 825 | lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */ |
941 | lwi r11, r11, TI_FLAGS; /* get flags in thread info */ | 826 | lwi r11, r11, TI_FLAGS; /* get flags in thread info */ |
942 | andi r11, r11, _TIF_NEED_RESCHED; | 827 | andi r11, r11, _TIF_NEED_RESCHED; |
943 | beqi r11, 5f; | 828 | beqi r11, 5f; |
944 | 829 | ||
945 | /* Call the scheduler before returning from a syscall/trap. */ | 830 | /* Call the scheduler before returning from a syscall/trap. */ |
946 | |||
947 | bralid r15, schedule; /* Call scheduler */ | 831 | bralid r15, schedule; /* Call scheduler */ |
948 | nop; /* delay slot */ | 832 | nop; /* delay slot */ |
949 | /* XXX Is PT_DTRACE handling needed here? */ | ||
950 | /* XXX m68knommu also checks TASK_STATE & TASK_COUNTER here. */ | ||
951 | 833 | ||
952 | /* Maybe handle a signal */ | 834 | /* Maybe handle a signal */ |
953 | 5: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */ | 835 | 5: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */ |
@@ -955,54 +837,40 @@ dbtrap_call: rtbd r11, 0; | |||
955 | andi r11, r11, _TIF_SIGPENDING; | 837 | andi r11, r11, _TIF_SIGPENDING; |
956 | beqi r11, 1f; /* Signals to handle, handle them */ | 838 | beqi r11, 1f; /* Signals to handle, handle them */ |
957 | 839 | ||
958 | /* Handle a signal return; Pending signals should be in r18. */ | 840 | addik r5, r1, PTO; /* Arg 1: struct pt_regs *regs */ |
959 | /* Not all registers are saved by the normal trap/interrupt entry | ||
960 | points (for instance, call-saved registers (because the normal | ||
961 | C-compiler calling sequence in the kernel makes sure they're | ||
962 | preserved), and call-clobbered registers in the case of | ||
963 | traps), but signal handlers may want to examine or change the | ||
964 | complete register state. Here we save anything not saved by | ||
965 | the normal entry sequence, so that it may be safely restored | ||
966 | (in a possibly modified form) after do_signal returns. */ | ||
967 | |||
968 | la r5, r1, PTO; /* Arg 1: struct pt_regs *regs */ | ||
969 | addi r7, r0, 0; /* Arg 3: int in_syscall */ | 841 | addi r7, r0, 0; /* Arg 3: int in_syscall */ |
970 | bralid r15, do_signal; /* Handle any signals */ | 842 | bralid r15, do_signal; /* Handle any signals */ |
971 | add r6, r0, r0; /* Arg 2: sigset_t *oldset */ | 843 | add r6, r0, r0; /* Arg 2: sigset_t *oldset */ |
972 | 844 | ||
973 | |||
974 | /* Finally, return to user state. */ | 845 | /* Finally, return to user state. */ |
975 | 1: swi r0, r0, PER_CPU(KM); /* Now officially in user state. */ | 846 | 1: swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */ |
976 | swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */ | ||
977 | VM_OFF; | 847 | VM_OFF; |
978 | tophys(r1,r1); | 848 | tophys(r1,r1); |
979 | 849 | /* MS: Restore all regs */ | |
980 | lwi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */ | ||
981 | lwi r4, r1, PTO+PT_R4; | ||
982 | RESTORE_REGS | 850 | RESTORE_REGS |
983 | addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */ | 851 | lwi r17, r1, PTO+PT_R17; |
984 | 852 | lwi r16, r1, PTO+PT_R16; | |
985 | 853 | addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space */ | |
986 | lwi r1, r1, PT_R1 - PT_SIZE; | 854 | lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer */ |
987 | /* Restore user stack pointer. */ | 855 | DBTRAP_return_user: /* MS: Make global symbol for debugging */ |
988 | bri 6f; | 856 | rtbd r16, 0; /* MS: Instructions to return from a debug trap */ |
857 | nop; | ||
989 | 858 | ||
990 | /* Return to kernel state. */ | 859 | /* MS: Return to kernel state - kgdb */ |
991 | 2: VM_OFF; | 860 | 2: VM_OFF; |
992 | tophys(r1,r1); | 861 | tophys(r1,r1); |
993 | lwi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */ | 862 | /* MS: Restore all regs */ |
994 | lwi r4, r1, PTO+PT_R4; | ||
995 | RESTORE_REGS | 863 | RESTORE_REGS |
996 | addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */ | 864 | lwi r14, r1, PTO+PT_R14; |
997 | 865 | lwi r16, r1, PTO+PT_PC; | |
866 | lwi r17, r1, PTO+PT_R17; | ||
867 | addik r1, r1, STATE_SAVE_SIZE; /* MS: Clean up stack space */ | ||
998 | tovirt(r1,r1); | 868 | tovirt(r1,r1); |
999 | 6: | 869 | DBTRAP_return_kernel: /* MS: Make global symbol for debugging */ |
1000 | DBTRAP_return: /* Make global symbol for debugging */ | 870 | rtbd r16, 0; /* MS: Instructions to return from a debug trap */ |
1001 | rtbd r14, 0; /* Instructions to return from an IRQ */ | ||
1002 | nop; | 871 | nop; |
1003 | 872 | ||
1004 | 873 | ||
1005 | |||
1006 | ENTRY(_switch_to) | 874 | ENTRY(_switch_to) |
1007 | /* prepare return value */ | 875 | /* prepare return value */ |
1008 | addk r3, r0, CURRENT_TASK | 876 | addk r3, r0, CURRENT_TASK |
@@ -1037,16 +905,12 @@ ENTRY(_switch_to) | |||
1037 | swi r30, r11, CC_R30 | 905 | swi r30, r11, CC_R30 |
1038 | /* special purpose registers */ | 906 | /* special purpose registers */ |
1039 | mfs r12, rmsr | 907 | mfs r12, rmsr |
1040 | nop | ||
1041 | swi r12, r11, CC_MSR | 908 | swi r12, r11, CC_MSR |
1042 | mfs r12, rear | 909 | mfs r12, rear |
1043 | nop | ||
1044 | swi r12, r11, CC_EAR | 910 | swi r12, r11, CC_EAR |
1045 | mfs r12, resr | 911 | mfs r12, resr |
1046 | nop | ||
1047 | swi r12, r11, CC_ESR | 912 | swi r12, r11, CC_ESR |
1048 | mfs r12, rfsr | 913 | mfs r12, rfsr |
1049 | nop | ||
1050 | swi r12, r11, CC_FSR | 914 | swi r12, r11, CC_FSR |
1051 | 915 | ||
1052 | /* update r31, the current-give me pointer to task which will be next */ | 916 | /* update r31, the current-give me pointer to task which will be next */ |
@@ -1085,10 +949,8 @@ ENTRY(_switch_to) | |||
1085 | /* special purpose registers */ | 949 | /* special purpose registers */ |
1086 | lwi r12, r11, CC_FSR | 950 | lwi r12, r11, CC_FSR |
1087 | mts rfsr, r12 | 951 | mts rfsr, r12 |
1088 | nop | ||
1089 | lwi r12, r11, CC_MSR | 952 | lwi r12, r11, CC_MSR |
1090 | mts rmsr, r12 | 953 | mts rmsr, r12 |
1091 | nop | ||
1092 | 954 | ||
1093 | rtsd r15, 8 | 955 | rtsd r15, 8 |
1094 | nop | 956 | nop |
@@ -1096,15 +958,6 @@ ENTRY(_switch_to) | |||
1096 | ENTRY(_reset) | 958 | ENTRY(_reset) |
1097 | brai 0x70; /* Jump back to FS-boot */ | 959 | brai 0x70; /* Jump back to FS-boot */ |
1098 | 960 | ||
1099 | ENTRY(_break) | ||
1100 | mfs r5, rmsr | ||
1101 | nop | ||
1102 | swi r5, r0, 0x250 + TOPHYS(r0_ram) | ||
1103 | mfs r5, resr | ||
1104 | nop | ||
1105 | swi r5, r0, 0x254 + TOPHYS(r0_ram) | ||
1106 | bri 0 | ||
1107 | |||
1108 | /* These are compiled and loaded into high memory, then | 961 | /* These are compiled and loaded into high memory, then |
1109 | * copied into place in mach_early_setup */ | 962 | * copied into place in mach_early_setup */ |
1110 | .section .init.ivt, "ax" | 963 | .section .init.ivt, "ax" |
@@ -1116,14 +969,38 @@ ENTRY(_break) | |||
1116 | nop | 969 | nop |
1117 | brai TOPHYS(_user_exception); /* syscall handler */ | 970 | brai TOPHYS(_user_exception); /* syscall handler */ |
1118 | brai TOPHYS(_interrupt); /* Interrupt handler */ | 971 | brai TOPHYS(_interrupt); /* Interrupt handler */ |
1119 | brai TOPHYS(_break); /* nmi trap handler */ | 972 | brai TOPHYS(_debug_exception); /* debug trap handler */ |
1120 | brai TOPHYS(_hw_exception_handler); /* HW exception handler */ | 973 | brai TOPHYS(_hw_exception_handler); /* HW exception handler */ |
1121 | 974 | ||
1122 | .org 0x60 | ||
1123 | brai TOPHYS(_debug_exception); /* debug trap handler*/ | ||
1124 | |||
1125 | .section .rodata,"a" | 975 | .section .rodata,"a" |
1126 | #include "syscall_table.S" | 976 | #include "syscall_table.S" |
1127 | 977 | ||
1128 | syscall_table_size=(.-sys_call_table) | 978 | syscall_table_size=(.-sys_call_table) |
1129 | 979 | ||
980 | type_SYSCALL: | ||
981 | .ascii "SYSCALL\0" | ||
982 | type_IRQ: | ||
983 | .ascii "IRQ\0" | ||
984 | type_IRQ_PREEMPT: | ||
985 | .ascii "IRQ (PREEMPTED)\0" | ||
986 | type_SYSCALL_PREEMPT: | ||
987 | .ascii " SYSCALL (PREEMPTED)\0" | ||
988 | |||
989 | /* | ||
990 | * Trap decoding for stack unwinder | ||
991 | * Tuples are (start addr, end addr, string) | ||
992 | * If return address lies on [start addr, end addr], | ||
993 | * unwinder displays 'string' | ||
994 | */ | ||
995 | |||
996 | .align 4 | ||
997 | .global microblaze_trap_handlers | ||
998 | microblaze_trap_handlers: | ||
999 | /* Exact matches come first */ | ||
1000 | .word ret_from_trap; .word ret_from_trap ; .word type_SYSCALL | ||
1001 | .word ret_from_irq ; .word ret_from_irq ; .word type_IRQ | ||
1002 | /* Fuzzy matches go here */ | ||
1003 | .word ret_from_irq ; .word no_intr_resched ; .word type_IRQ_PREEMPT | ||
1004 | .word ret_from_trap; .word TRAP_return ; .word type_SYSCALL_PREEMPT | ||
1005 | /* End of table */ | ||
1006 | .word 0 ; .word 0 ; .word 0 | ||