aboutsummaryrefslogtreecommitdiffstats
path: root/arch/microblaze/kernel/entry.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/microblaze/kernel/entry.S')
-rw-r--r--arch/microblaze/kernel/entry.S368
1 files changed, 201 insertions, 167 deletions
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
index 304882e56459..ca15bc5c7449 100644
--- a/arch/microblaze/kernel/entry.S
+++ b/arch/microblaze/kernel/entry.S
@@ -33,11 +33,14 @@
33 33
34#undef DEBUG 34#undef DEBUG
35 35
36/* The size of a state save frame. */ 36#ifdef DEBUG
37#define STATE_SAVE_SIZE (PT_SIZE + STATE_SAVE_ARG_SPACE) 37/* Create space for syscalls counting. */
38 38.section .data
39/* The offset of the struct pt_regs in a `state save frame' on the stack. */ 39.global syscall_debug_table
40#define PTO STATE_SAVE_ARG_SPACE /* 24 the space for args */ 40.align 4
41syscall_debug_table:
42 .space (__NR_syscalls * 4)
43#endif /* DEBUG */
41 44
42#define C_ENTRY(name) .globl name; .align 4; name 45#define C_ENTRY(name) .globl name; .align 4; name
43 46
@@ -172,68 +175,72 @@
1721: 1751:
173 176
174#define SAVE_REGS \ 177#define SAVE_REGS \
175 swi r2, r1, PTO+PT_R2; /* Save SDA */ \ 178 swi r2, r1, PT_R2; /* Save SDA */ \
176 swi r3, r1, PTO+PT_R3; \ 179 swi r3, r1, PT_R3; \
177 swi r4, r1, PTO+PT_R4; \ 180 swi r4, r1, PT_R4; \
178 swi r5, r1, PTO+PT_R5; \ 181 swi r5, r1, PT_R5; \
179 swi r6, r1, PTO+PT_R6; \ 182 swi r6, r1, PT_R6; \
180 swi r7, r1, PTO+PT_R7; \ 183 swi r7, r1, PT_R7; \
181 swi r8, r1, PTO+PT_R8; \ 184 swi r8, r1, PT_R8; \
182 swi r9, r1, PTO+PT_R9; \ 185 swi r9, r1, PT_R9; \
183 swi r10, r1, PTO+PT_R10; \ 186 swi r10, r1, PT_R10; \
184 swi r11, r1, PTO+PT_R11; /* save clobbered regs after rval */\ 187 swi r11, r1, PT_R11; /* save clobbered regs after rval */\
185 swi r12, r1, PTO+PT_R12; \ 188 swi r12, r1, PT_R12; \
186 swi r13, r1, PTO+PT_R13; /* Save SDA2 */ \ 189 swi r13, r1, PT_R13; /* Save SDA2 */ \
187 swi r14, r1, PTO+PT_PC; /* PC, before IRQ/trap */ \ 190 swi r14, r1, PT_PC; /* PC, before IRQ/trap */ \
188 swi r15, r1, PTO+PT_R15; /* Save LP */ \ 191 swi r15, r1, PT_R15; /* Save LP */ \
189 swi r18, r1, PTO+PT_R18; /* Save asm scratch reg */ \ 192 swi r16, r1, PT_R16; \
190 swi r19, r1, PTO+PT_R19; \ 193 swi r17, r1, PT_R17; \
191 swi r20, r1, PTO+PT_R20; \ 194 swi r18, r1, PT_R18; /* Save asm scratch reg */ \
192 swi r21, r1, PTO+PT_R21; \ 195 swi r19, r1, PT_R19; \
193 swi r22, r1, PTO+PT_R22; \ 196 swi r20, r1, PT_R20; \
194 swi r23, r1, PTO+PT_R23; \ 197 swi r21, r1, PT_R21; \
195 swi r24, r1, PTO+PT_R24; \ 198 swi r22, r1, PT_R22; \
196 swi r25, r1, PTO+PT_R25; \ 199 swi r23, r1, PT_R23; \
197 swi r26, r1, PTO+PT_R26; \ 200 swi r24, r1, PT_R24; \
198 swi r27, r1, PTO+PT_R27; \ 201 swi r25, r1, PT_R25; \
199 swi r28, r1, PTO+PT_R28; \ 202 swi r26, r1, PT_R26; \
200 swi r29, r1, PTO+PT_R29; \ 203 swi r27, r1, PT_R27; \
201 swi r30, r1, PTO+PT_R30; \ 204 swi r28, r1, PT_R28; \
202 swi r31, r1, PTO+PT_R31; /* Save current task reg */ \ 205 swi r29, r1, PT_R29; \
206 swi r30, r1, PT_R30; \
207 swi r31, r1, PT_R31; /* Save current task reg */ \
203 mfs r11, rmsr; /* save MSR */ \ 208 mfs r11, rmsr; /* save MSR */ \
204 swi r11, r1, PTO+PT_MSR; 209 swi r11, r1, PT_MSR;
205 210
206#define RESTORE_REGS \ 211#define RESTORE_REGS \
207 lwi r11, r1, PTO+PT_MSR; \ 212 lwi r11, r1, PT_MSR; \
208 mts rmsr , r11; \ 213 mts rmsr , r11; \
209 lwi r2, r1, PTO+PT_R2; /* restore SDA */ \ 214 lwi r2, r1, PT_R2; /* restore SDA */ \
210 lwi r3, r1, PTO+PT_R3; \ 215 lwi r3, r1, PT_R3; \
211 lwi r4, r1, PTO+PT_R4; \ 216 lwi r4, r1, PT_R4; \
212 lwi r5, r1, PTO+PT_R5; \ 217 lwi r5, r1, PT_R5; \
213 lwi r6, r1, PTO+PT_R6; \ 218 lwi r6, r1, PT_R6; \
214 lwi r7, r1, PTO+PT_R7; \ 219 lwi r7, r1, PT_R7; \
215 lwi r8, r1, PTO+PT_R8; \ 220 lwi r8, r1, PT_R8; \
216 lwi r9, r1, PTO+PT_R9; \ 221 lwi r9, r1, PT_R9; \
217 lwi r10, r1, PTO+PT_R10; \ 222 lwi r10, r1, PT_R10; \
218 lwi r11, r1, PTO+PT_R11; /* restore clobbered regs after rval */\ 223 lwi r11, r1, PT_R11; /* restore clobbered regs after rval */\
219 lwi r12, r1, PTO+PT_R12; \ 224 lwi r12, r1, PT_R12; \
220 lwi r13, r1, PTO+PT_R13; /* restore SDA2 */ \ 225 lwi r13, r1, PT_R13; /* restore SDA2 */ \
221 lwi r14, r1, PTO+PT_PC; /* RESTORE_LINK PC, before IRQ/trap */\ 226 lwi r14, r1, PT_PC; /* RESTORE_LINK PC, before IRQ/trap */\
222 lwi r15, r1, PTO+PT_R15; /* restore LP */ \ 227 lwi r15, r1, PT_R15; /* restore LP */ \
223 lwi r18, r1, PTO+PT_R18; /* restore asm scratch reg */ \ 228 lwi r16, r1, PT_R16; \
224 lwi r19, r1, PTO+PT_R19; \ 229 lwi r17, r1, PT_R17; \
225 lwi r20, r1, PTO+PT_R20; \ 230 lwi r18, r1, PT_R18; /* restore asm scratch reg */ \
226 lwi r21, r1, PTO+PT_R21; \ 231 lwi r19, r1, PT_R19; \
227 lwi r22, r1, PTO+PT_R22; \ 232 lwi r20, r1, PT_R20; \
228 lwi r23, r1, PTO+PT_R23; \ 233 lwi r21, r1, PT_R21; \
229 lwi r24, r1, PTO+PT_R24; \ 234 lwi r22, r1, PT_R22; \
230 lwi r25, r1, PTO+PT_R25; \ 235 lwi r23, r1, PT_R23; \
231 lwi r26, r1, PTO+PT_R26; \ 236 lwi r24, r1, PT_R24; \
232 lwi r27, r1, PTO+PT_R27; \ 237 lwi r25, r1, PT_R25; \
233 lwi r28, r1, PTO+PT_R28; \ 238 lwi r26, r1, PT_R26; \
234 lwi r29, r1, PTO+PT_R29; \ 239 lwi r27, r1, PT_R27; \
235 lwi r30, r1, PTO+PT_R30; \ 240 lwi r28, r1, PT_R28; \
236 lwi r31, r1, PTO+PT_R31; /* Restore cur task reg */ 241 lwi r29, r1, PT_R29; \
242 lwi r30, r1, PT_R30; \
243 lwi r31, r1, PT_R31; /* Restore cur task reg */
237 244
238#define SAVE_STATE \ 245#define SAVE_STATE \
239 swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* save stack */ \ 246 swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* save stack */ \
@@ -246,11 +253,11 @@
246 lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); \ 253 lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); \
247 /* FIXME: I can add these two lines to one */ \ 254 /* FIXME: I can add these two lines to one */ \
248 /* tophys(r1,r1); */ \ 255 /* tophys(r1,r1); */ \
249 /* addik r1, r1, -STATE_SAVE_SIZE; */ \ 256 /* addik r1, r1, -PT_SIZE; */ \
250 addik r1, r1, CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE; \ 257 addik r1, r1, CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - PT_SIZE; \
251 SAVE_REGS \ 258 SAVE_REGS \
252 brid 2f; \ 259 brid 2f; \
253 swi r1, r1, PTO+PT_MODE; \ 260 swi r1, r1, PT_MODE; \
2541: /* User-mode state save. */ \ 2611: /* User-mode state save. */ \
255 lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */\ 262 lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */\
256 tophys(r1,r1); \ 263 tophys(r1,r1); \
@@ -258,12 +265,12 @@
258 /* MS these three instructions can be added to one */ \ 265 /* MS these three instructions can be added to one */ \
259 /* addik r1, r1, THREAD_SIZE; */ \ 266 /* addik r1, r1, THREAD_SIZE; */ \
260 /* tophys(r1,r1); */ \ 267 /* tophys(r1,r1); */ \
261 /* addik r1, r1, -STATE_SAVE_SIZE; */ \ 268 /* addik r1, r1, -PT_SIZE; */ \
262 addik r1, r1, THREAD_SIZE + CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE; \ 269 addik r1, r1, THREAD_SIZE + CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - PT_SIZE; \
263 SAVE_REGS \ 270 SAVE_REGS \
264 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); \ 271 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); \
265 swi r11, r1, PTO+PT_R1; /* Store user SP. */ \ 272 swi r11, r1, PT_R1; /* Store user SP. */ \
266 swi r0, r1, PTO + PT_MODE; /* Was in user-mode. */ \ 273 swi r0, r1, PT_MODE; /* Was in user-mode. */ \
267 /* MS: I am clearing UMS even in case when I come from kernel space */ \ 274 /* MS: I am clearing UMS even in case when I come from kernel space */ \
268 clear_ums; \ 275 clear_ums; \
2692: lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); 2762: lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
@@ -283,25 +290,46 @@
283 * are masked. This is nice, means we don't have to CLI before state save 290 * are masked. This is nice, means we don't have to CLI before state save
284 */ 291 */
285C_ENTRY(_user_exception): 292C_ENTRY(_user_exception):
286 addi r14, r14, 4 /* return address is 4 byte after call */
287 swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)) /* save stack */ 293 swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)) /* save stack */
294 addi r14, r14, 4 /* return address is 4 byte after call */
295
296 mfs r1, rmsr
297 nop
298 andi r1, r1, MSR_UMS
299 bnei r1, 1f
288 300
301/* Kernel-mode state save - kernel execve */
302 lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* Reload kernel stack-ptr*/
303 tophys(r1,r1);
304
305 addik r1, r1, -PT_SIZE; /* Make room on the stack. */
306 SAVE_REGS
307
308 swi r1, r1, PT_MODE; /* pt_regs -> kernel mode */
309 brid 2f;
310 nop; /* Fill delay slot */
311
312/* User-mode state save. */
3131:
289 lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */ 314 lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */
290 tophys(r1,r1); 315 tophys(r1,r1);
291 lwi r1, r1, TS_THREAD_INFO; /* get stack from task_struct */ 316 lwi r1, r1, TS_THREAD_INFO; /* get stack from task_struct */
292 /* MS these three instructions can be added to one */ 317/* calculate kernel stack pointer from task struct 8k */
293 /* addik r1, r1, THREAD_SIZE; */ 318 addik r1, r1, THREAD_SIZE;
294 /* tophys(r1,r1); */ 319 tophys(r1,r1);
295 /* addik r1, r1, -STATE_SAVE_SIZE; */ 320
296 addik r1, r1, THREAD_SIZE + CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE; 321 addik r1, r1, -PT_SIZE; /* Make room on the stack. */
297 SAVE_REGS 322 SAVE_REGS
323 swi r0, r1, PT_R3
324 swi r0, r1, PT_R4
298 325
326 swi r0, r1, PT_MODE; /* Was in user-mode. */
299 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); 327 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
300 swi r11, r1, PTO+PT_R1; /* Store user SP. */ 328 swi r11, r1, PT_R1; /* Store user SP. */
301 clear_ums; 329 clear_ums;
302 lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); 3302: lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
303 /* Save away the syscall number. */ 331 /* Save away the syscall number. */
304 swi r12, r1, PTO+PT_R0; 332 swi r12, r1, PT_R0;
305 tovirt(r1,r1) 333 tovirt(r1,r1)
306 334
307/* where the trap should return need -8 to adjust for rtsd r15, 8*/ 335/* where the trap should return need -8 to adjust for rtsd r15, 8*/
@@ -320,18 +348,18 @@ C_ENTRY(_user_exception):
320 beqi r11, 4f 348 beqi r11, 4f
321 349
322 addik r3, r0, -ENOSYS 350 addik r3, r0, -ENOSYS
323 swi r3, r1, PTO + PT_R3 351 swi r3, r1, PT_R3
324 brlid r15, do_syscall_trace_enter 352 brlid r15, do_syscall_trace_enter
325 addik r5, r1, PTO + PT_R0 353 addik r5, r1, PT_R0
326 354
327 # do_syscall_trace_enter returns the new syscall nr. 355 # do_syscall_trace_enter returns the new syscall nr.
328 addk r12, r0, r3 356 addk r12, r0, r3
329 lwi r5, r1, PTO+PT_R5; 357 lwi r5, r1, PT_R5;
330 lwi r6, r1, PTO+PT_R6; 358 lwi r6, r1, PT_R6;
331 lwi r7, r1, PTO+PT_R7; 359 lwi r7, r1, PT_R7;
332 lwi r8, r1, PTO+PT_R8; 360 lwi r8, r1, PT_R8;
333 lwi r9, r1, PTO+PT_R9; 361 lwi r9, r1, PT_R9;
334 lwi r10, r1, PTO+PT_R10; 362 lwi r10, r1, PT_R10;
3354: 3634:
336/* Jump to the appropriate function for the system call number in r12 364/* Jump to the appropriate function for the system call number in r12
337 * (r12 is not preserved), or return an error if r12 is not valid. 365 * (r12 is not preserved), or return an error if r12 is not valid.
@@ -346,10 +374,14 @@ C_ENTRY(_user_exception):
346 add r12, r12, r12; 374 add r12, r12, r12;
347 375
348#ifdef DEBUG 376#ifdef DEBUG
349 /* Trac syscalls and stored them to r0_ram */ 377 /* Trac syscalls and stored them to syscall_debug_table */
350 lwi r3, r12, 0x400 + r0_ram 378 /* The first syscall location stores total syscall number */
379 lwi r3, r0, syscall_debug_table
380 addi r3, r3, 1
381 swi r3, r0, syscall_debug_table
382 lwi r3, r12, syscall_debug_table
351 addi r3, r3, 1 383 addi r3, r3, 1
352 swi r3, r12, 0x400 + r0_ram 384 swi r3, r12, syscall_debug_table
353#endif 385#endif
354 386
355 # Find and jump into the syscall handler. 387 # Find and jump into the syscall handler.
@@ -366,9 +398,12 @@ C_ENTRY(_user_exception):
366/* Entry point used to return from a syscall/trap */ 398/* Entry point used to return from a syscall/trap */
367/* We re-enable BIP bit before state restore */ 399/* We re-enable BIP bit before state restore */
368C_ENTRY(ret_from_trap): 400C_ENTRY(ret_from_trap):
369 swi r3, r1, PTO + PT_R3 401 swi r3, r1, PT_R3
370 swi r4, r1, PTO + PT_R4 402 swi r4, r1, PT_R4
371 403
404 lwi r11, r1, PT_MODE;
405/* See if returning to kernel mode, if so, skip resched &c. */
406 bnei r11, 2f;
372 /* We're returning to user mode, so check for various conditions that 407 /* We're returning to user mode, so check for various conditions that
373 * trigger rescheduling. */ 408 * trigger rescheduling. */
374 /* FIXME: Restructure all these flag checks. */ 409 /* FIXME: Restructure all these flag checks. */
@@ -378,7 +413,7 @@ C_ENTRY(ret_from_trap):
378 beqi r11, 1f 413 beqi r11, 1f
379 414
380 brlid r15, do_syscall_trace_leave 415 brlid r15, do_syscall_trace_leave
381 addik r5, r1, PTO + PT_R0 416 addik r5, r1, PT_R0
3821: 4171:
383 /* We're returning to user mode, so check for various conditions that 418 /* We're returning to user mode, so check for various conditions that
384 * trigger rescheduling. */ 419 * trigger rescheduling. */
@@ -398,7 +433,7 @@ C_ENTRY(ret_from_trap):
398 andi r11, r11, _TIF_SIGPENDING; 433 andi r11, r11, _TIF_SIGPENDING;
399 beqi r11, 1f; /* Signals to handle, handle them */ 434 beqi r11, 1f; /* Signals to handle, handle them */
400 435
401 addik r5, r1, PTO; /* Arg 1: struct pt_regs *regs */ 436 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
402 addi r7, r0, 1; /* Arg 3: int in_syscall */ 437 addi r7, r0, 1; /* Arg 3: int in_syscall */
403 bralid r15, do_signal; /* Handle any signals */ 438 bralid r15, do_signal; /* Handle any signals */
404 add r6, r0, r0; /* Arg 2: sigset_t *oldset */ 439 add r6, r0, r0; /* Arg 2: sigset_t *oldset */
@@ -409,8 +444,18 @@ C_ENTRY(ret_from_trap):
409 VM_OFF; 444 VM_OFF;
410 tophys(r1,r1); 445 tophys(r1,r1);
411 RESTORE_REGS; 446 RESTORE_REGS;
412 addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */ 447 addik r1, r1, PT_SIZE /* Clean up stack space. */
413 lwi r1, r1, PT_R1 - PT_SIZE;/* Restore user stack pointer. */ 448 lwi r1, r1, PT_R1 - PT_SIZE;/* Restore user stack pointer. */
449 bri 6f;
450
451/* Return to kernel state. */
4522: set_bip; /* Ints masked for state restore */
453 VM_OFF;
454 tophys(r1,r1);
455 RESTORE_REGS;
456 addik r1, r1, PT_SIZE /* Clean up stack space. */
457 tovirt(r1,r1);
4586:
414TRAP_return: /* Make global symbol for debugging */ 459TRAP_return: /* Make global symbol for debugging */
415 rtbd r14, 0; /* Instructions to return from an IRQ */ 460 rtbd r14, 0; /* Instructions to return from an IRQ */
416 nop; 461 nop;
@@ -421,8 +466,8 @@ TRAP_return: /* Make global symbol for debugging */
421 466
422C_ENTRY(sys_fork_wrapper): 467C_ENTRY(sys_fork_wrapper):
423 addi r5, r0, SIGCHLD /* Arg 0: flags */ 468 addi r5, r0, SIGCHLD /* Arg 0: flags */
424 lwi r6, r1, PTO+PT_R1 /* Arg 1: child SP (use parent's) */ 469 lwi r6, r1, PT_R1 /* Arg 1: child SP (use parent's) */
425 addik r7, r1, PTO /* Arg 2: parent context */ 470 addik r7, r1, 0 /* Arg 2: parent context */
426 add r8. r0, r0 /* Arg 3: (unused) */ 471 add r8. r0, r0 /* Arg 3: (unused) */
427 add r9, r0, r0; /* Arg 4: (unused) */ 472 add r9, r0, r0; /* Arg 4: (unused) */
428 brid do_fork /* Do real work (tail-call) */ 473 brid do_fork /* Do real work (tail-call) */
@@ -442,12 +487,12 @@ C_ENTRY(ret_from_fork):
442 487
443C_ENTRY(sys_vfork): 488C_ENTRY(sys_vfork):
444 brid microblaze_vfork /* Do real work (tail-call) */ 489 brid microblaze_vfork /* Do real work (tail-call) */
445 addik r5, r1, PTO 490 addik r5, r1, 0
446 491
447C_ENTRY(sys_clone): 492C_ENTRY(sys_clone):
448 bnei r6, 1f; /* See if child SP arg (arg 1) is 0. */ 493 bnei r6, 1f; /* See if child SP arg (arg 1) is 0. */
449 lwi r6, r1, PTO + PT_R1; /* If so, use paret's stack ptr */ 494 lwi r6, r1, PT_R1; /* If so, use paret's stack ptr */
4501: addik r7, r1, PTO; /* Arg 2: parent context */ 4951: addik r7, r1, 0; /* Arg 2: parent context */
451 add r8, r0, r0; /* Arg 3: (unused) */ 496 add r8, r0, r0; /* Arg 3: (unused) */
452 add r9, r0, r0; /* Arg 4: (unused) */ 497 add r9, r0, r0; /* Arg 4: (unused) */
453 brid do_fork /* Do real work (tail-call) */ 498 brid do_fork /* Do real work (tail-call) */
@@ -455,17 +500,11 @@ C_ENTRY(sys_clone):
455 500
456C_ENTRY(sys_execve): 501C_ENTRY(sys_execve):
457 brid microblaze_execve; /* Do real work (tail-call).*/ 502 brid microblaze_execve; /* Do real work (tail-call).*/
458 addik r8, r1, PTO; /* add user context as 4th arg */ 503 addik r8, r1, 0; /* add user context as 4th arg */
459 504
460C_ENTRY(sys_rt_sigreturn_wrapper): 505C_ENTRY(sys_rt_sigreturn_wrapper):
461 swi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */ 506 brid sys_rt_sigreturn /* Do real work */
462 swi r4, r1, PTO+PT_R4; 507 addik r5, r1, 0; /* add user context as 1st arg */
463 brlid r15, sys_rt_sigreturn /* Do real work */
464 addik r5, r1, PTO; /* add user context as 1st arg */
465 lwi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */
466 lwi r4, r1, PTO+PT_R4;
467 bri ret_from_trap /* fall through will not work here due to align */
468 nop;
469 508
470/* 509/*
471 * HW EXCEPTION rutine start 510 * HW EXCEPTION rutine start
@@ -476,7 +515,7 @@ C_ENTRY(full_exception_trap):
476 addik r17, r17, -4 515 addik r17, r17, -4
477 SAVE_STATE /* Save registers */ 516 SAVE_STATE /* Save registers */
478 /* PC, before IRQ/trap - this is one instruction above */ 517 /* PC, before IRQ/trap - this is one instruction above */
479 swi r17, r1, PTO+PT_PC; 518 swi r17, r1, PT_PC;
480 tovirt(r1,r1) 519 tovirt(r1,r1)
481 /* FIXME this can be store directly in PT_ESR reg. 520 /* FIXME this can be store directly in PT_ESR reg.
482 * I tested it but there is a fault */ 521 * I tested it but there is a fault */
@@ -486,7 +525,7 @@ C_ENTRY(full_exception_trap):
486 mfs r7, rfsr; /* save FSR */ 525 mfs r7, rfsr; /* save FSR */
487 mts rfsr, r0; /* Clear sticky fsr */ 526 mts rfsr, r0; /* Clear sticky fsr */
488 rted r0, full_exception 527 rted r0, full_exception
489 addik r5, r1, PTO /* parameter struct pt_regs * regs */ 528 addik r5, r1, 0 /* parameter struct pt_regs * regs */
490 529
491/* 530/*
492 * Unaligned data trap. 531 * Unaligned data trap.
@@ -512,14 +551,14 @@ C_ENTRY(unaligned_data_trap):
512 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); 551 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
513 SAVE_STATE /* Save registers.*/ 552 SAVE_STATE /* Save registers.*/
514 /* PC, before IRQ/trap - this is one instruction above */ 553 /* PC, before IRQ/trap - this is one instruction above */
515 swi r17, r1, PTO+PT_PC; 554 swi r17, r1, PT_PC;
516 tovirt(r1,r1) 555 tovirt(r1,r1)
517 /* where the trap should return need -8 to adjust for rtsd r15, 8 */ 556 /* where the trap should return need -8 to adjust for rtsd r15, 8 */
518 addik r15, r0, ret_from_exc-8 557 addik r15, r0, ret_from_exc-8
519 mfs r3, resr /* ESR */ 558 mfs r3, resr /* ESR */
520 mfs r4, rear /* EAR */ 559 mfs r4, rear /* EAR */
521 rtbd r0, _unaligned_data_exception 560 rtbd r0, _unaligned_data_exception
522 addik r7, r1, PTO /* parameter struct pt_regs * regs */ 561 addik r7, r1, 0 /* parameter struct pt_regs * regs */
523 562
524/* 563/*
525 * Page fault traps. 564 * Page fault traps.
@@ -542,30 +581,30 @@ C_ENTRY(unaligned_data_trap):
542C_ENTRY(page_fault_data_trap): 581C_ENTRY(page_fault_data_trap):
543 SAVE_STATE /* Save registers.*/ 582 SAVE_STATE /* Save registers.*/
544 /* PC, before IRQ/trap - this is one instruction above */ 583 /* PC, before IRQ/trap - this is one instruction above */
545 swi r17, r1, PTO+PT_PC; 584 swi r17, r1, PT_PC;
546 tovirt(r1,r1) 585 tovirt(r1,r1)
547 /* where the trap should return need -8 to adjust for rtsd r15, 8 */ 586 /* where the trap should return need -8 to adjust for rtsd r15, 8 */
548 addik r15, r0, ret_from_exc-8 587 addik r15, r0, ret_from_exc-8
549 mfs r6, rear /* parameter unsigned long address */ 588 mfs r6, rear /* parameter unsigned long address */
550 mfs r7, resr /* parameter unsigned long error_code */ 589 mfs r7, resr /* parameter unsigned long error_code */
551 rted r0, do_page_fault 590 rted r0, do_page_fault
552 addik r5, r1, PTO /* parameter struct pt_regs * regs */ 591 addik r5, r1, 0 /* parameter struct pt_regs * regs */
553 592
554C_ENTRY(page_fault_instr_trap): 593C_ENTRY(page_fault_instr_trap):
555 SAVE_STATE /* Save registers.*/ 594 SAVE_STATE /* Save registers.*/
556 /* PC, before IRQ/trap - this is one instruction above */ 595 /* PC, before IRQ/trap - this is one instruction above */
557 swi r17, r1, PTO+PT_PC; 596 swi r17, r1, PT_PC;
558 tovirt(r1,r1) 597 tovirt(r1,r1)
559 /* where the trap should return need -8 to adjust for rtsd r15, 8 */ 598 /* where the trap should return need -8 to adjust for rtsd r15, 8 */
560 addik r15, r0, ret_from_exc-8 599 addik r15, r0, ret_from_exc-8
561 mfs r6, rear /* parameter unsigned long address */ 600 mfs r6, rear /* parameter unsigned long address */
562 ori r7, r0, 0 /* parameter unsigned long error_code */ 601 ori r7, r0, 0 /* parameter unsigned long error_code */
563 rted r0, do_page_fault 602 rted r0, do_page_fault
564 addik r5, r1, PTO /* parameter struct pt_regs * regs */ 603 addik r5, r1, 0 /* parameter struct pt_regs * regs */
565 604
566/* Entry point used to return from an exception. */ 605/* Entry point used to return from an exception. */
567C_ENTRY(ret_from_exc): 606C_ENTRY(ret_from_exc):
568 lwi r11, r1, PTO + PT_MODE; 607 lwi r11, r1, PT_MODE;
569 bnei r11, 2f; /* See if returning to kernel mode, */ 608 bnei r11, 2f; /* See if returning to kernel mode, */
570 /* ... if so, skip resched &c. */ 609 /* ... if so, skip resched &c. */
571 610
@@ -597,7 +636,7 @@ C_ENTRY(ret_from_exc):
597 * complete register state. Here we save anything not saved by 636 * complete register state. Here we save anything not saved by
598 * the normal entry sequence, so that it may be safely restored 637 * the normal entry sequence, so that it may be safely restored
599 * (in a possibly modified form) after do_signal returns. */ 638 * (in a possibly modified form) after do_signal returns. */
600 addik r5, r1, PTO; /* Arg 1: struct pt_regs *regs */ 639 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
601 addi r7, r0, 0; /* Arg 3: int in_syscall */ 640 addi r7, r0, 0; /* Arg 3: int in_syscall */
602 bralid r15, do_signal; /* Handle any signals */ 641 bralid r15, do_signal; /* Handle any signals */
603 add r6, r0, r0; /* Arg 2: sigset_t *oldset */ 642 add r6, r0, r0; /* Arg 2: sigset_t *oldset */
@@ -609,7 +648,7 @@ C_ENTRY(ret_from_exc):
609 tophys(r1,r1); 648 tophys(r1,r1);
610 649
611 RESTORE_REGS; 650 RESTORE_REGS;
612 addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */ 651 addik r1, r1, PT_SIZE /* Clean up stack space. */
613 652
614 lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer. */ 653 lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer. */
615 bri 6f; 654 bri 6f;
@@ -618,7 +657,7 @@ C_ENTRY(ret_from_exc):
618 VM_OFF; 657 VM_OFF;
619 tophys(r1,r1); 658 tophys(r1,r1);
620 RESTORE_REGS; 659 RESTORE_REGS;
621 addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */ 660 addik r1, r1, PT_SIZE /* Clean up stack space. */
622 661
623 tovirt(r1,r1); 662 tovirt(r1,r1);
6246: 6636:
@@ -651,10 +690,10 @@ C_ENTRY(_interrupt):
651 tophys(r1,r1); /* MS: I have in r1 physical address where stack is */ 690 tophys(r1,r1); /* MS: I have in r1 physical address where stack is */
652 /* save registers */ 691 /* save registers */
653/* MS: Make room on the stack -> activation record */ 692/* MS: Make room on the stack -> activation record */
654 addik r1, r1, -STATE_SAVE_SIZE; 693 addik r1, r1, -PT_SIZE;
655 SAVE_REGS 694 SAVE_REGS
656 brid 2f; 695 brid 2f;
657 swi r1, r1, PTO + PT_MODE; /* 0 - user mode, 1 - kernel mode */ 696 swi r1, r1, PT_MODE; /* 0 - user mode, 1 - kernel mode */
6581: 6971:
659/* User-mode state save. */ 698/* User-mode state save. */
660 /* MS: get the saved current */ 699 /* MS: get the saved current */
@@ -664,23 +703,23 @@ C_ENTRY(_interrupt):
664 addik r1, r1, THREAD_SIZE; 703 addik r1, r1, THREAD_SIZE;
665 tophys(r1,r1); 704 tophys(r1,r1);
666 /* save registers */ 705 /* save registers */
667 addik r1, r1, -STATE_SAVE_SIZE; 706 addik r1, r1, -PT_SIZE;
668 SAVE_REGS 707 SAVE_REGS
669 /* calculate mode */ 708 /* calculate mode */
670 swi r0, r1, PTO + PT_MODE; 709 swi r0, r1, PT_MODE;
671 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); 710 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
672 swi r11, r1, PTO+PT_R1; 711 swi r11, r1, PT_R1;
673 clear_ums; 712 clear_ums;
6742: 7132:
675 lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); 714 lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
676 tovirt(r1,r1) 715 tovirt(r1,r1)
677 addik r15, r0, irq_call; 716 addik r15, r0, irq_call;
678irq_call:rtbd r0, do_IRQ; 717irq_call:rtbd r0, do_IRQ;
679 addik r5, r1, PTO; 718 addik r5, r1, 0;
680 719
681/* MS: we are in virtual mode */ 720/* MS: we are in virtual mode */
682ret_from_irq: 721ret_from_irq:
683 lwi r11, r1, PTO + PT_MODE; 722 lwi r11, r1, PT_MODE;
684 bnei r11, 2f; 723 bnei r11, 2f;
685 724
686 lwi r11, CURRENT_TASK, TS_THREAD_INFO; 725 lwi r11, CURRENT_TASK, TS_THREAD_INFO;
@@ -697,7 +736,7 @@ ret_from_irq:
697 beqid r11, no_intr_resched 736 beqid r11, no_intr_resched
698/* Handle a signal return; Pending signals should be in r18. */ 737/* Handle a signal return; Pending signals should be in r18. */
699 addi r7, r0, 0; /* Arg 3: int in_syscall */ 738 addi r7, r0, 0; /* Arg 3: int in_syscall */
700 addik r5, r1, PTO; /* Arg 1: struct pt_regs *regs */ 739 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
701 bralid r15, do_signal; /* Handle any signals */ 740 bralid r15, do_signal; /* Handle any signals */
702 add r6, r0, r0; /* Arg 2: sigset_t *oldset */ 741 add r6, r0, r0; /* Arg 2: sigset_t *oldset */
703 742
@@ -709,7 +748,7 @@ no_intr_resched:
709 VM_OFF; 748 VM_OFF;
710 tophys(r1,r1); 749 tophys(r1,r1);
711 RESTORE_REGS 750 RESTORE_REGS
712 addik r1, r1, STATE_SAVE_SIZE /* MS: Clean up stack space. */ 751 addik r1, r1, PT_SIZE /* MS: Clean up stack space. */
713 lwi r1, r1, PT_R1 - PT_SIZE; 752 lwi r1, r1, PT_R1 - PT_SIZE;
714 bri 6f; 753 bri 6f;
715/* MS: Return to kernel state. */ 754/* MS: Return to kernel state. */
@@ -737,7 +776,7 @@ restore:
737 VM_OFF /* MS: turn off MMU */ 776 VM_OFF /* MS: turn off MMU */
738 tophys(r1,r1) 777 tophys(r1,r1)
739 RESTORE_REGS 778 RESTORE_REGS
740 addik r1, r1, STATE_SAVE_SIZE /* MS: Clean up stack space. */ 779 addik r1, r1, PT_SIZE /* MS: Clean up stack space. */
741 tovirt(r1,r1); 780 tovirt(r1,r1);
7426: 7816:
743IRQ_return: /* MS: Make global symbol for debugging */ 782IRQ_return: /* MS: Make global symbol for debugging */
@@ -760,31 +799,29 @@ C_ENTRY(_debug_exception):
760 lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* Reload kernel stack-ptr*/ 799 lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* Reload kernel stack-ptr*/
761 800
762 /* BIP bit is set on entry, no interrupts can occur */ 801 /* BIP bit is set on entry, no interrupts can occur */
763 addik r1, r1, CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE; 802 addik r1, r1, CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - PT_SIZE;
764 SAVE_REGS; 803 SAVE_REGS;
765 /* save all regs to pt_reg structure */ 804 /* save all regs to pt_reg structure */
766 swi r0, r1, PTO+PT_R0; /* R0 must be saved too */ 805 swi r0, r1, PT_R0; /* R0 must be saved too */
767 swi r14, r1, PTO+PT_R14 /* rewrite saved R14 value */ 806 swi r14, r1, PT_R14 /* rewrite saved R14 value */
768 swi r16, r1, PTO+PT_R16 807 swi r16, r1, PT_PC; /* PC and r16 are the same */
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 */ 808 /* save special purpose registers to pt_regs */
772 mfs r11, rear; 809 mfs r11, rear;
773 swi r11, r1, PTO+PT_EAR; 810 swi r11, r1, PT_EAR;
774 mfs r11, resr; 811 mfs r11, resr;
775 swi r11, r1, PTO+PT_ESR; 812 swi r11, r1, PT_ESR;
776 mfs r11, rfsr; 813 mfs r11, rfsr;
777 swi r11, r1, PTO+PT_FSR; 814 swi r11, r1, PT_FSR;
778 815
779 /* stack pointer is in physical address at it is decrease 816 /* stack pointer is in physical address at it is decrease
780 * by STATE_SAVE_SIZE but we need to get correct R1 value */ 817 * by PT_SIZE but we need to get correct R1 value */
781 addik r11, r1, CONFIG_KERNEL_START - CONFIG_KERNEL_BASE_ADDR + STATE_SAVE_SIZE; 818 addik r11, r1, CONFIG_KERNEL_START - CONFIG_KERNEL_BASE_ADDR + PT_SIZE;
782 swi r11, r1, PTO+PT_R1 819 swi r11, r1, PT_R1
783 /* MS: r31 - current pointer isn't changed */ 820 /* MS: r31 - current pointer isn't changed */
784 tovirt(r1,r1) 821 tovirt(r1,r1)
785#ifdef CONFIG_KGDB 822#ifdef CONFIG_KGDB
786 addi r5, r1, PTO /* pass pt_reg address as the first arg */ 823 addi r5, r1, 0 /* pass pt_reg address as the first arg */
787 la r15, r0, dbtrap_call; /* return address */ 824 addik r15, r0, dbtrap_call; /* return address */
788 rtbd r0, microblaze_kgdb_break 825 rtbd r0, microblaze_kgdb_break
789 nop; 826 nop;
790#endif 827#endif
@@ -799,18 +836,16 @@ C_ENTRY(_debug_exception):
799 addik r1, r1, THREAD_SIZE; /* calculate kernel stack pointer */ 836 addik r1, r1, THREAD_SIZE; /* calculate kernel stack pointer */
800 tophys(r1,r1); 837 tophys(r1,r1);
801 838
802 addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */ 839 addik r1, r1, -PT_SIZE; /* Make room on the stack. */
803 SAVE_REGS; 840 SAVE_REGS;
804 swi r17, r1, PTO+PT_R17; 841 swi r16, r1, PT_PC; /* Save LP */
805 swi r16, r1, PTO+PT_R16; 842 swi r0, r1, PT_MODE; /* Was in user-mode. */
806 swi r16, r1, PTO+PT_PC; /* Save LP */
807 swi r0, r1, PTO + PT_MODE; /* Was in user-mode. */
808 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); 843 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
809 swi r11, r1, PTO+PT_R1; /* Store user SP. */ 844 swi r11, r1, PT_R1; /* Store user SP. */
810 lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); 845 lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
811 tovirt(r1,r1) 846 tovirt(r1,r1)
812 set_vms; 847 set_vms;
813 addik r5, r1, PTO; 848 addik r5, r1, 0;
814 addik r15, r0, dbtrap_call; 849 addik r15, r0, dbtrap_call;
815dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */ 850dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
816 rtbd r0, sw_exception 851 rtbd r0, sw_exception
@@ -818,7 +853,7 @@ dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
818 853
819 /* MS: The first instruction for the second part of the gdb/kgdb */ 854 /* MS: The first instruction for the second part of the gdb/kgdb */
820 set_bip; /* Ints masked for state restore */ 855 set_bip; /* Ints masked for state restore */
821 lwi r11, r1, PTO + PT_MODE; 856 lwi r11, r1, PT_MODE;
822 bnei r11, 2f; 857 bnei r11, 2f;
823/* MS: Return to user space - gdb */ 858/* MS: Return to user space - gdb */
824 /* Get current task ptr into r11 */ 859 /* Get current task ptr into r11 */
@@ -837,7 +872,7 @@ dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
837 andi r11, r11, _TIF_SIGPENDING; 872 andi r11, r11, _TIF_SIGPENDING;
838 beqi r11, 1f; /* Signals to handle, handle them */ 873 beqi r11, 1f; /* Signals to handle, handle them */
839 874
840 addik r5, r1, PTO; /* Arg 1: struct pt_regs *regs */ 875 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
841 addi r7, r0, 0; /* Arg 3: int in_syscall */ 876 addi r7, r0, 0; /* Arg 3: int in_syscall */
842 bralid r15, do_signal; /* Handle any signals */ 877 bralid r15, do_signal; /* Handle any signals */
843 add r6, r0, r0; /* Arg 2: sigset_t *oldset */ 878 add r6, r0, r0; /* Arg 2: sigset_t *oldset */
@@ -848,9 +883,7 @@ dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
848 tophys(r1,r1); 883 tophys(r1,r1);
849 /* MS: Restore all regs */ 884 /* MS: Restore all regs */
850 RESTORE_REGS 885 RESTORE_REGS
851 lwi r17, r1, PTO+PT_R17; 886 addik r1, r1, PT_SIZE /* Clean up stack space */
852 lwi r16, r1, PTO+PT_R16;
853 addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space */
854 lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer */ 887 lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer */
855DBTRAP_return_user: /* MS: Make global symbol for debugging */ 888DBTRAP_return_user: /* MS: Make global symbol for debugging */
856 rtbd r16, 0; /* MS: Instructions to return from a debug trap */ 889 rtbd r16, 0; /* MS: Instructions to return from a debug trap */
@@ -861,10 +894,9 @@ DBTRAP_return_user: /* MS: Make global symbol for debugging */
861 tophys(r1,r1); 894 tophys(r1,r1);
862 /* MS: Restore all regs */ 895 /* MS: Restore all regs */
863 RESTORE_REGS 896 RESTORE_REGS
864 lwi r14, r1, PTO+PT_R14; 897 lwi r14, r1, PT_R14;
865 lwi r16, r1, PTO+PT_PC; 898 lwi r16, r1, PT_PC;
866 lwi r17, r1, PTO+PT_R17; 899 addik r1, r1, PT_SIZE; /* MS: Clean up stack space */
867 addik r1, r1, STATE_SAVE_SIZE; /* MS: Clean up stack space */
868 tovirt(r1,r1); 900 tovirt(r1,r1);
869DBTRAP_return_kernel: /* MS: Make global symbol for debugging */ 901DBTRAP_return_kernel: /* MS: Make global symbol for debugging */
870 rtbd r16, 0; /* MS: Instructions to return from a debug trap */ 902 rtbd r16, 0; /* MS: Instructions to return from a debug trap */
@@ -956,20 +988,22 @@ ENTRY(_switch_to)
956 nop 988 nop
957 989
958ENTRY(_reset) 990ENTRY(_reset)
959 brai 0x70; /* Jump back to FS-boot */ 991 brai 0; /* Jump to reset vector */
960 992
961 /* These are compiled and loaded into high memory, then 993 /* These are compiled and loaded into high memory, then
962 * copied into place in mach_early_setup */ 994 * copied into place in mach_early_setup */
963 .section .init.ivt, "ax" 995 .section .init.ivt, "ax"
996#if CONFIG_MANUAL_RESET_VECTOR
964 .org 0x0 997 .org 0x0
965 /* this is very important - here is the reset vector */ 998 brai CONFIG_MANUAL_RESET_VECTOR
966 /* in current MMU branch you don't care what is here - it is 999#endif
967 * used from bootloader site - but this is correct for FS-BOOT */ 1000 .org 0x8
968 brai 0x70
969 nop
970 brai TOPHYS(_user_exception); /* syscall handler */ 1001 brai TOPHYS(_user_exception); /* syscall handler */
1002 .org 0x10
971 brai TOPHYS(_interrupt); /* Interrupt handler */ 1003 brai TOPHYS(_interrupt); /* Interrupt handler */
1004 .org 0x18
972 brai TOPHYS(_debug_exception); /* debug trap handler */ 1005 brai TOPHYS(_debug_exception); /* debug trap handler */
1006 .org 0x20
973 brai TOPHYS(_hw_exception_handler); /* HW exception handler */ 1007 brai TOPHYS(_hw_exception_handler); /* HW exception handler */
974 1008
975.section .rodata,"a" 1009.section .rodata,"a"