diff options
Diffstat (limited to 'arch/blackfin/mach-common/entry.S')
-rw-r--r-- | arch/blackfin/mach-common/entry.S | 132 |
1 files changed, 66 insertions, 66 deletions
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index bde6dc4e2614..fae774651374 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/init.h> | 36 | #include <linux/init.h> |
37 | #include <linux/linkage.h> | 37 | #include <linux/linkage.h> |
38 | #include <linux/unistd.h> | 38 | #include <linux/unistd.h> |
39 | #include <linux/threads.h> | ||
39 | #include <asm/blackfin.h> | 40 | #include <asm/blackfin.h> |
40 | #include <asm/errno.h> | 41 | #include <asm/errno.h> |
41 | #include <asm/fixed_code.h> | 42 | #include <asm/fixed_code.h> |
@@ -75,11 +76,11 @@ ENTRY(_ex_workaround_261) | |||
75 | * handle it. | 76 | * handle it. |
76 | */ | 77 | */ |
77 | P4 = R7; /* Store EXCAUSE */ | 78 | P4 = R7; /* Store EXCAUSE */ |
78 | p5.l = _last_cplb_fault_retx; | 79 | |
79 | p5.h = _last_cplb_fault_retx; | 80 | GET_PDA(p5, r7); |
80 | r7 = [p5]; | 81 | r7 = [p5 + PDA_LFRETX]; |
81 | r6 = retx; | 82 | r6 = retx; |
82 | [p5] = r6; | 83 | [p5 + PDA_LFRETX] = r6; |
83 | cc = r6 == r7; | 84 | cc = r6 == r7; |
84 | if !cc jump _bfin_return_from_exception; | 85 | if !cc jump _bfin_return_from_exception; |
85 | /* fall through */ | 86 | /* fall through */ |
@@ -111,24 +112,21 @@ ENTRY(_ex_dcplb_viol) | |||
111 | ENTRY(_ex_dcplb_miss) | 112 | ENTRY(_ex_dcplb_miss) |
112 | ENTRY(_ex_icplb_miss) | 113 | ENTRY(_ex_icplb_miss) |
113 | (R7:6,P5:4) = [sp++]; | 114 | (R7:6,P5:4) = [sp++]; |
114 | ASTAT = [sp++]; | 115 | /* We leave the previously pushed ASTAT on the stack. */ |
115 | SAVE_ALL_SYS | 116 | SAVE_CONTEXT_CPLB |
116 | #ifdef CONFIG_MPU | 117 | |
117 | /* We must load R1 here, _before_ DEBUG_HWTRACE_SAVE, since that | 118 | /* We must load R1 here, _before_ DEBUG_HWTRACE_SAVE, since that |
118 | * will change the stack pointer. */ | 119 | * will change the stack pointer. */ |
119 | R0 = SEQSTAT; | 120 | R0 = SEQSTAT; |
120 | R1 = SP; | 121 | R1 = SP; |
121 | #endif | 122 | |
122 | DEBUG_HWTRACE_SAVE(p5, r7) | 123 | DEBUG_HWTRACE_SAVE(p5, r7) |
123 | #ifdef CONFIG_MPU | 124 | |
124 | sp += -12; | 125 | sp += -12; |
125 | call _cplb_hdr; | 126 | call _cplb_hdr; |
126 | sp += 12; | 127 | sp += 12; |
127 | CC = R0 == 0; | 128 | CC = R0 == 0; |
128 | IF !CC JUMP _handle_bad_cplb; | 129 | IF !CC JUMP _handle_bad_cplb; |
129 | #else | ||
130 | call __cplb_hdr; | ||
131 | #endif | ||
132 | 130 | ||
133 | #ifdef CONFIG_DEBUG_DOUBLEFAULT | 131 | #ifdef CONFIG_DEBUG_DOUBLEFAULT |
134 | /* While we were processing this, did we double fault? */ | 132 | /* While we were processing this, did we double fault? */ |
@@ -142,7 +140,8 @@ ENTRY(_ex_icplb_miss) | |||
142 | #endif | 140 | #endif |
143 | 141 | ||
144 | DEBUG_HWTRACE_RESTORE(p5, r7) | 142 | DEBUG_HWTRACE_RESTORE(p5, r7) |
145 | RESTORE_ALL_SYS | 143 | RESTORE_CONTEXT_CPLB |
144 | ASTAT = [SP++]; | ||
146 | SP = EX_SCRATCH_REG; | 145 | SP = EX_SCRATCH_REG; |
147 | rtx; | 146 | rtx; |
148 | ENDPROC(_ex_icplb_miss) | 147 | ENDPROC(_ex_icplb_miss) |
@@ -297,9 +296,8 @@ ENTRY(_handle_bad_cplb) | |||
297 | * the stack to get ready so, we can fall through - we | 296 | * the stack to get ready so, we can fall through - we |
298 | * need to make a CPLB exception look like a normal exception | 297 | * need to make a CPLB exception look like a normal exception |
299 | */ | 298 | */ |
300 | 299 | RESTORE_CONTEXT_CPLB | |
301 | RESTORE_ALL_SYS | 300 | /* ASTAT is still on the stack, where it is needed. */ |
302 | [--sp] = ASTAT; | ||
303 | [--sp] = (R7:6,P5:4); | 301 | [--sp] = (R7:6,P5:4); |
304 | 302 | ||
305 | ENTRY(_ex_replaceable) | 303 | ENTRY(_ex_replaceable) |
@@ -324,7 +322,9 @@ ENTRY(_ex_trap_c) | |||
324 | [p4] = p5; | 322 | [p4] = p5; |
325 | csync; | 323 | csync; |
326 | 324 | ||
325 | GET_PDA(p5, r6); | ||
327 | #ifndef CONFIG_DEBUG_DOUBLEFAULT | 326 | #ifndef CONFIG_DEBUG_DOUBLEFAULT |
327 | |||
328 | /* | 328 | /* |
329 | * Save these registers, as they are only valid in exception context | 329 | * Save these registers, as they are only valid in exception context |
330 | * (where we are now - as soon as we defer to IRQ5, they can change) | 330 | * (where we are now - as soon as we defer to IRQ5, they can change) |
@@ -335,29 +335,25 @@ ENTRY(_ex_trap_c) | |||
335 | p4.l = lo(DCPLB_FAULT_ADDR); | 335 | p4.l = lo(DCPLB_FAULT_ADDR); |
336 | p4.h = hi(DCPLB_FAULT_ADDR); | 336 | p4.h = hi(DCPLB_FAULT_ADDR); |
337 | r7 = [p4]; | 337 | r7 = [p4]; |
338 | p5.h = _saved_dcplb_fault_addr; | 338 | [p5 + PDA_DCPLB] = r7; |
339 | p5.l = _saved_dcplb_fault_addr; | ||
340 | [p5] = r7; | ||
341 | 339 | ||
342 | r7 = [p4 + (ICPLB_FAULT_ADDR - DCPLB_FAULT_ADDR)]; | 340 | p4.l = lo(ICPLB_FAULT_ADDR); |
343 | p5.h = _saved_icplb_fault_addr; | 341 | p4.h = hi(ICPLB_FAULT_ADDR); |
344 | p5.l = _saved_icplb_fault_addr; | 342 | r6 = [p4]; |
345 | [p5] = r7; | 343 | [p5 + PDA_ICPLB] = r6; |
346 | 344 | ||
347 | r6 = retx; | 345 | r6 = retx; |
348 | p4.l = _saved_retx; | 346 | [p5 + PDA_RETX] = r6; |
349 | p4.h = _saved_retx; | ||
350 | [p4] = r6; | ||
351 | #endif | 347 | #endif |
352 | r6 = SYSCFG; | 348 | r6 = SYSCFG; |
353 | [p4 + 4] = r6; | 349 | [p5 + PDA_SYSCFG] = r6; |
354 | BITCLR(r6, 0); | 350 | BITCLR(r6, 0); |
355 | SYSCFG = r6; | 351 | SYSCFG = r6; |
356 | 352 | ||
357 | /* Disable all interrupts, but make sure level 5 is enabled so | 353 | /* Disable all interrupts, but make sure level 5 is enabled so |
358 | * we can switch to that level. Save the old mask. */ | 354 | * we can switch to that level. Save the old mask. */ |
359 | cli r6; | 355 | cli r6; |
360 | [p4 + 8] = r6; | 356 | [p5 + PDA_EXIMASK] = r6; |
361 | 357 | ||
362 | p4.l = lo(SAFE_USER_INSTRUCTION); | 358 | p4.l = lo(SAFE_USER_INSTRUCTION); |
363 | p4.h = hi(SAFE_USER_INSTRUCTION); | 359 | p4.h = hi(SAFE_USER_INSTRUCTION); |
@@ -371,9 +367,10 @@ ENTRY(_ex_trap_c) | |||
371 | ENDPROC(_ex_trap_c) | 367 | ENDPROC(_ex_trap_c) |
372 | 368 | ||
373 | /* We just realized we got an exception, while we were processing a different | 369 | /* We just realized we got an exception, while we were processing a different |
374 | * exception. This is a unrecoverable event, so crash | 370 | * exception. This is a unrecoverable event, so crash. |
371 | * Note: this cannot be ENTRY() as we jump here with "if cc jump" ... | ||
375 | */ | 372 | */ |
376 | ENTRY(_double_fault) | 373 | _double_fault: |
377 | /* Turn caches & protection off, to ensure we don't get any more | 374 | /* Turn caches & protection off, to ensure we don't get any more |
378 | * double exceptions | 375 | * double exceptions |
379 | */ | 376 | */ |
@@ -424,17 +421,16 @@ ENDPROC(_double_fault) | |||
424 | ENTRY(_exception_to_level5) | 421 | ENTRY(_exception_to_level5) |
425 | SAVE_ALL_SYS | 422 | SAVE_ALL_SYS |
426 | 423 | ||
427 | p4.l = _saved_retx; | 424 | GET_PDA(p4, r7); /* Fetch current PDA */ |
428 | p4.h = _saved_retx; | 425 | r6 = [p4 + PDA_RETX]; |
429 | r6 = [p4]; | ||
430 | [sp + PT_PC] = r6; | 426 | [sp + PT_PC] = r6; |
431 | 427 | ||
432 | r6 = [p4 + 4]; | 428 | r6 = [p4 + PDA_SYSCFG]; |
433 | [sp + PT_SYSCFG] = r6; | 429 | [sp + PT_SYSCFG] = r6; |
434 | 430 | ||
435 | /* Restore interrupt mask. We haven't pushed RETI, so this | 431 | /* Restore interrupt mask. We haven't pushed RETI, so this |
436 | * doesn't enable interrupts until we return from this handler. */ | 432 | * doesn't enable interrupts until we return from this handler. */ |
437 | r6 = [p4 + 8]; | 433 | r6 = [p4 + PDA_EXIMASK]; |
438 | sti r6; | 434 | sti r6; |
439 | 435 | ||
440 | /* Restore the hardware error vector. */ | 436 | /* Restore the hardware error vector. */ |
@@ -478,8 +474,8 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/ | |||
478 | * scratch register (for want of a better option). | 474 | * scratch register (for want of a better option). |
479 | */ | 475 | */ |
480 | EX_SCRATCH_REG = sp; | 476 | EX_SCRATCH_REG = sp; |
481 | sp.l = _exception_stack_top; | 477 | GET_PDA_SAFE(sp); |
482 | sp.h = _exception_stack_top; | 478 | sp = [sp + PDA_EXSTACK] |
483 | /* Try to deal with syscalls quickly. */ | 479 | /* Try to deal with syscalls quickly. */ |
484 | [--sp] = ASTAT; | 480 | [--sp] = ASTAT; |
485 | [--sp] = (R7:6,P5:4); | 481 | [--sp] = (R7:6,P5:4); |
@@ -501,27 +497,22 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/ | |||
501 | * but they are not very interesting, so don't save them | 497 | * but they are not very interesting, so don't save them |
502 | */ | 498 | */ |
503 | 499 | ||
500 | GET_PDA(p5, r7); | ||
504 | p4.l = lo(DCPLB_FAULT_ADDR); | 501 | p4.l = lo(DCPLB_FAULT_ADDR); |
505 | p4.h = hi(DCPLB_FAULT_ADDR); | 502 | p4.h = hi(DCPLB_FAULT_ADDR); |
506 | r7 = [p4]; | 503 | r7 = [p4]; |
507 | p5.h = _saved_dcplb_fault_addr; | 504 | [p5 + PDA_DCPLB] = r7; |
508 | p5.l = _saved_dcplb_fault_addr; | ||
509 | [p5] = r7; | ||
510 | 505 | ||
511 | r7 = [p4 + (ICPLB_FAULT_ADDR - DCPLB_FAULT_ADDR)]; | 506 | p4.l = lo(ICPLB_FAULT_ADDR); |
512 | p5.h = _saved_icplb_fault_addr; | 507 | p4.h = hi(ICPLB_FAULT_ADDR); |
513 | p5.l = _saved_icplb_fault_addr; | 508 | r7 = [p4]; |
514 | [p5] = r7; | 509 | [p5 + PDA_ICPLB] = r7; |
515 | 510 | ||
516 | p4.l = _saved_retx; | ||
517 | p4.h = _saved_retx; | ||
518 | r6 = retx; | 511 | r6 = retx; |
519 | [p4] = r6; | 512 | [p5 + PDA_RETX] = r6; |
520 | 513 | ||
521 | r7 = SEQSTAT; /* reason code is in bit 5:0 */ | 514 | r7 = SEQSTAT; /* reason code is in bit 5:0 */ |
522 | p4.l = _saved_seqstat; | 515 | [p5 + PDA_SEQSTAT] = r7; |
523 | p4.h = _saved_seqstat; | ||
524 | [p4] = r7; | ||
525 | #else | 516 | #else |
526 | r7 = SEQSTAT; /* reason code is in bit 5:0 */ | 517 | r7 = SEQSTAT; /* reason code is in bit 5:0 */ |
527 | #endif | 518 | #endif |
@@ -546,11 +537,11 @@ ENTRY(_kernel_execve) | |||
546 | p0 = sp; | 537 | p0 = sp; |
547 | r3 = SIZEOF_PTREGS / 4; | 538 | r3 = SIZEOF_PTREGS / 4; |
548 | r4 = 0(x); | 539 | r4 = 0(x); |
549 | 0: | 540 | .Lclear_regs: |
550 | [p0++] = r4; | 541 | [p0++] = r4; |
551 | r3 += -1; | 542 | r3 += -1; |
552 | cc = r3 == 0; | 543 | cc = r3 == 0; |
553 | if !cc jump 0b (bp); | 544 | if !cc jump .Lclear_regs (bp); |
554 | 545 | ||
555 | p0 = sp; | 546 | p0 = sp; |
556 | sp += -16; | 547 | sp += -16; |
@@ -558,7 +549,7 @@ ENTRY(_kernel_execve) | |||
558 | call _do_execve; | 549 | call _do_execve; |
559 | SP += 16; | 550 | SP += 16; |
560 | cc = r0 == 0; | 551 | cc = r0 == 0; |
561 | if ! cc jump 1f; | 552 | if ! cc jump .Lexecve_failed; |
562 | /* Success. Copy our temporary pt_regs to the top of the kernel | 553 | /* Success. Copy our temporary pt_regs to the top of the kernel |
563 | * stack and do a normal exception return. | 554 | * stack and do a normal exception return. |
564 | */ | 555 | */ |
@@ -574,12 +565,12 @@ ENTRY(_kernel_execve) | |||
574 | p0 = fp; | 565 | p0 = fp; |
575 | r4 = [p0--]; | 566 | r4 = [p0--]; |
576 | r3 = SIZEOF_PTREGS / 4; | 567 | r3 = SIZEOF_PTREGS / 4; |
577 | 0: | 568 | .Lcopy_regs: |
578 | r4 = [p0--]; | 569 | r4 = [p0--]; |
579 | [p1--] = r4; | 570 | [p1--] = r4; |
580 | r3 += -1; | 571 | r3 += -1; |
581 | cc = r3 == 0; | 572 | cc = r3 == 0; |
582 | if ! cc jump 0b (bp); | 573 | if ! cc jump .Lcopy_regs (bp); |
583 | 574 | ||
584 | r0 = (KERNEL_STACK_SIZE - SIZEOF_PTREGS) (z); | 575 | r0 = (KERNEL_STACK_SIZE - SIZEOF_PTREGS) (z); |
585 | p1 = r0; | 576 | p1 = r0; |
@@ -591,7 +582,7 @@ ENTRY(_kernel_execve) | |||
591 | 582 | ||
592 | RESTORE_CONTEXT; | 583 | RESTORE_CONTEXT; |
593 | rti; | 584 | rti; |
594 | 1: | 585 | .Lexecve_failed: |
595 | unlink; | 586 | unlink; |
596 | rts; | 587 | rts; |
597 | ENDPROC(_kernel_execve) | 588 | ENDPROC(_kernel_execve) |
@@ -925,9 +916,14 @@ _schedule_and_signal_from_int: | |||
925 | p1 = rets; | 916 | p1 = rets; |
926 | [sp + PT_RESERVED] = p1; | 917 | [sp + PT_RESERVED] = p1; |
927 | 918 | ||
928 | p0.l = _irq_flags; | 919 | #ifdef CONFIG_SMP |
929 | p0.h = _irq_flags; | 920 | GET_PDA(p0, r0); /* Fetch current PDA (can't migrate to other CPU here) */ |
921 | r0 = [p0 + PDA_IRQFLAGS]; | ||
922 | #else | ||
923 | p0.l = _bfin_irq_flags; | ||
924 | p0.h = _bfin_irq_flags; | ||
930 | r0 = [p0]; | 925 | r0 = [p0]; |
926 | #endif | ||
931 | sti r0; | 927 | sti r0; |
932 | 928 | ||
933 | r0 = sp; | 929 | r0 = sp; |
@@ -1539,14 +1535,18 @@ ENTRY(_sys_call_table) | |||
1539 | .endr | 1535 | .endr |
1540 | END(_sys_call_table) | 1536 | END(_sys_call_table) |
1541 | 1537 | ||
1542 | _exception_stack: | 1538 | #ifdef CONFIG_EXCEPTION_L1_SCRATCH |
1543 | .rept 1024 | 1539 | /* .section .l1.bss.scratch */ |
1544 | .long 0; | 1540 | .set _exception_stack_top, L1_SCRATCH_START + L1_SCRATCH_LENGTH |
1541 | #else | ||
1542 | #ifdef CONFIG_SYSCALL_TAB_L1 | ||
1543 | .section .l1.bss | ||
1544 | #else | ||
1545 | .bss | ||
1546 | #endif | ||
1547 | ENTRY(_exception_stack) | ||
1548 | .rept 1024 * NR_CPUS | ||
1549 | .long 0 | ||
1545 | .endr | 1550 | .endr |
1546 | _exception_stack_top: | 1551 | _exception_stack_top: |
1547 | |||
1548 | #if ANOMALY_05000261 | ||
1549 | /* Used by the assembly entry point to work around an anomaly. */ | ||
1550 | _last_cplb_fault_retx: | ||
1551 | .long 0; | ||
1552 | #endif | 1552 | #endif |