diff options
Diffstat (limited to 'arch/blackfin/mach-common/entry.S')
-rw-r--r-- | arch/blackfin/mach-common/entry.S | 85 |
1 files changed, 55 insertions, 30 deletions
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index b0ed0b487ff2..a5847f5d67c7 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S | |||
@@ -405,7 +405,7 @@ ENTRY(_double_fault) | |||
405 | 405 | ||
406 | r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */ | 406 | r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */ |
407 | SP += -12; | 407 | SP += -12; |
408 | call _double_fault_c; | 408 | pseudo_long_call _double_fault_c, p5; |
409 | SP += 12; | 409 | SP += 12; |
410 | .L_double_fault_panic: | 410 | .L_double_fault_panic: |
411 | JUMP .L_double_fault_panic | 411 | JUMP .L_double_fault_panic |
@@ -447,7 +447,7 @@ ENTRY(_exception_to_level5) | |||
447 | 447 | ||
448 | r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */ | 448 | r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */ |
449 | SP += -12; | 449 | SP += -12; |
450 | call _trap_c; | 450 | pseudo_long_call _trap_c, p4; |
451 | SP += 12; | 451 | SP += 12; |
452 | 452 | ||
453 | /* If interrupts were off during the exception (IPEND[4] = 1), turn them off | 453 | /* If interrupts were off during the exception (IPEND[4] = 1), turn them off |
@@ -482,6 +482,8 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/ | |||
482 | [--sp] = ASTAT; | 482 | [--sp] = ASTAT; |
483 | [--sp] = (R7:6,P5:4); | 483 | [--sp] = (R7:6,P5:4); |
484 | 484 | ||
485 | ANOMALY_283_315_WORKAROUND(p5, r7) | ||
486 | |||
485 | #ifdef CONFIG_EXACT_HWERR | 487 | #ifdef CONFIG_EXACT_HWERR |
486 | /* Make sure all pending read/writes complete. This will ensure any | 488 | /* Make sure all pending read/writes complete. This will ensure any |
487 | * accesses which could cause hardware errors completes, and signal | 489 | * accesses which could cause hardware errors completes, and signal |
@@ -492,8 +494,6 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/ | |||
492 | ssync; | 494 | ssync; |
493 | #endif | 495 | #endif |
494 | 496 | ||
495 | ANOMALY_283_315_WORKAROUND(p5, r7) | ||
496 | |||
497 | #ifdef CONFIG_DEBUG_DOUBLEFAULT | 497 | #ifdef CONFIG_DEBUG_DOUBLEFAULT |
498 | /* | 498 | /* |
499 | * Save these registers, as they are only valid in exception context | 499 | * Save these registers, as they are only valid in exception context |
@@ -551,7 +551,7 @@ ENTRY(_kernel_execve) | |||
551 | p0 = sp; | 551 | p0 = sp; |
552 | sp += -16; | 552 | sp += -16; |
553 | [sp + 12] = p0; | 553 | [sp + 12] = p0; |
554 | call _do_execve; | 554 | pseudo_long_call _do_execve, p5; |
555 | SP += 16; | 555 | SP += 16; |
556 | cc = r0 == 0; | 556 | cc = r0 == 0; |
557 | if ! cc jump .Lexecve_failed; | 557 | if ! cc jump .Lexecve_failed; |
@@ -626,13 +626,6 @@ ENTRY(_system_call) | |||
626 | p0 = [sp + PT_ORIG_P0]; | 626 | p0 = [sp + PT_ORIG_P0]; |
627 | #endif /* CONFIG_IPIPE */ | 627 | #endif /* CONFIG_IPIPE */ |
628 | 628 | ||
629 | /* Check the System Call */ | ||
630 | r7 = __NR_syscall; | ||
631 | /* System call number is passed in P0 */ | ||
632 | r6 = p0; | ||
633 | cc = r6 < r7; | ||
634 | if ! cc jump .Lbadsys; | ||
635 | |||
636 | /* are we tracing syscalls?*/ | 629 | /* are we tracing syscalls?*/ |
637 | r7 = sp; | 630 | r7 = sp; |
638 | r6.l = lo(ALIGN_PAGE_MASK); | 631 | r6.l = lo(ALIGN_PAGE_MASK); |
@@ -642,6 +635,14 @@ ENTRY(_system_call) | |||
642 | r7 = [p2+TI_FLAGS]; | 635 | r7 = [p2+TI_FLAGS]; |
643 | CC = BITTST(r7,TIF_SYSCALL_TRACE); | 636 | CC = BITTST(r7,TIF_SYSCALL_TRACE); |
644 | if CC JUMP _sys_trace; | 637 | if CC JUMP _sys_trace; |
638 | CC = BITTST(r7,TIF_SINGLESTEP); | ||
639 | if CC JUMP _sys_trace; | ||
640 | |||
641 | /* Make sure the system call # is valid */ | ||
642 | p4 = __NR_syscall; | ||
643 | /* System call number is passed in P0 */ | ||
644 | cc = p4 <= p0; | ||
645 | if cc jump .Lbadsys; | ||
645 | 646 | ||
646 | /* Execute the appropriate system call */ | 647 | /* Execute the appropriate system call */ |
647 | 648 | ||
@@ -704,7 +705,7 @@ ENTRY(_system_call) | |||
704 | sp += 4; | 705 | sp += 4; |
705 | 706 | ||
706 | SP += -12; | 707 | SP += -12; |
707 | call _schedule; | 708 | pseudo_long_call _schedule, p4; |
708 | SP += 12; | 709 | SP += 12; |
709 | 710 | ||
710 | jump .Lresume_userspace_1; | 711 | jump .Lresume_userspace_1; |
@@ -723,7 +724,7 @@ ENTRY(_system_call) | |||
723 | 724 | ||
724 | r0 = sp; | 725 | r0 = sp; |
725 | SP += -12; | 726 | SP += -12; |
726 | call _do_notify_resume; | 727 | pseudo_long_call _do_notify_resume, p5; |
727 | SP += 12; | 728 | SP += 12; |
728 | 729 | ||
729 | .Lsyscall_really_exit: | 730 | .Lsyscall_really_exit: |
@@ -736,11 +737,17 @@ ENDPROC(_system_call) | |||
736 | * this symbol need not be global anyways, so ... | 737 | * this symbol need not be global anyways, so ... |
737 | */ | 738 | */ |
738 | _sys_trace: | 739 | _sys_trace: |
739 | call _syscall_trace; | 740 | r0 = sp; |
740 | 741 | pseudo_long_call _syscall_trace_enter, p5; | |
741 | /* Execute the appropriate system call */ | ||
742 | 742 | ||
743 | /* Make sure the system call # is valid */ | ||
743 | p4 = [SP + PT_P0]; | 744 | p4 = [SP + PT_P0]; |
745 | p3 = __NR_syscall; | ||
746 | cc = p3 <= p4; | ||
747 | r0 = -ENOSYS; | ||
748 | if cc jump .Lsys_trace_badsys; | ||
749 | |||
750 | /* Execute the appropriate system call */ | ||
744 | p5.l = _sys_call_table; | 751 | p5.l = _sys_call_table; |
745 | p5.h = _sys_call_table; | 752 | p5.h = _sys_call_table; |
746 | p5 = p5 + (p4 << 2); | 753 | p5 = p5 + (p4 << 2); |
@@ -758,9 +765,11 @@ _sys_trace: | |||
758 | SP += -12; | 765 | SP += -12; |
759 | call (p5); | 766 | call (p5); |
760 | SP += 24; | 767 | SP += 24; |
768 | .Lsys_trace_badsys: | ||
761 | [sp + PT_R0] = r0; | 769 | [sp + PT_R0] = r0; |
762 | 770 | ||
763 | call _syscall_trace; | 771 | r0 = sp; |
772 | pseudo_long_call _syscall_trace_leave, p5; | ||
764 | jump .Lresume_userspace; | 773 | jump .Lresume_userspace; |
765 | ENDPROC(_sys_trace) | 774 | ENDPROC(_sys_trace) |
766 | 775 | ||
@@ -816,8 +825,8 @@ ENDPROC(_resume) | |||
816 | 825 | ||
817 | ENTRY(_ret_from_exception) | 826 | ENTRY(_ret_from_exception) |
818 | #ifdef CONFIG_IPIPE | 827 | #ifdef CONFIG_IPIPE |
819 | p2.l = _per_cpu__ipipe_percpu_domain; | 828 | p2.l = _ipipe_percpu_domain; |
820 | p2.h = _per_cpu__ipipe_percpu_domain; | 829 | p2.h = _ipipe_percpu_domain; |
821 | r0.l = _ipipe_root; | 830 | r0.l = _ipipe_root; |
822 | r0.h = _ipipe_root; | 831 | r0.h = _ipipe_root; |
823 | r2 = [p2]; | 832 | r2 = [p2]; |
@@ -966,6 +975,13 @@ ENTRY(_evt_evt14) | |||
966 | #else | 975 | #else |
967 | cli r0; | 976 | cli r0; |
968 | #endif | 977 | #endif |
978 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
979 | [--sp] = rets; | ||
980 | sp += -12; | ||
981 | call _trace_hardirqs_off; | ||
982 | sp += 12; | ||
983 | rets = [sp++]; | ||
984 | #endif | ||
969 | [--sp] = RETI; | 985 | [--sp] = RETI; |
970 | SP += 4; | 986 | SP += 4; |
971 | rts; | 987 | rts; |
@@ -989,6 +1005,14 @@ ENTRY(_schedule_and_signal_from_int) | |||
989 | p1 = rets; | 1005 | p1 = rets; |
990 | [sp + PT_RESERVED] = p1; | 1006 | [sp + PT_RESERVED] = p1; |
991 | 1007 | ||
1008 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
1009 | /* trace_hardirqs_on() checks if all irqs are disabled. But here IRQ 15 | ||
1010 | * is turned on, so disable all irqs. */ | ||
1011 | cli r0; | ||
1012 | sp += -12; | ||
1013 | call _trace_hardirqs_on; | ||
1014 | sp += 12; | ||
1015 | #endif | ||
992 | #ifdef CONFIG_SMP | 1016 | #ifdef CONFIG_SMP |
993 | GET_PDA(p0, r0); /* Fetch current PDA (can't migrate to other CPU here) */ | 1017 | GET_PDA(p0, r0); /* Fetch current PDA (can't migrate to other CPU here) */ |
994 | r0 = [p0 + PDA_IRQFLAGS]; | 1018 | r0 = [p0 + PDA_IRQFLAGS]; |
@@ -1007,7 +1031,8 @@ ENTRY(_schedule_and_signal_from_int) | |||
1007 | 1031 | ||
1008 | r0 = sp; | 1032 | r0 = sp; |
1009 | sp += -12; | 1033 | sp += -12; |
1010 | call _finish_atomic_sections; | 1034 | |
1035 | pseudo_long_call _finish_atomic_sections, p5; | ||
1011 | sp += 12; | 1036 | sp += 12; |
1012 | jump.s .Lresume_userspace; | 1037 | jump.s .Lresume_userspace; |
1013 | ENDPROC(_schedule_and_signal_from_int) | 1038 | ENDPROC(_schedule_and_signal_from_int) |
@@ -1357,7 +1382,7 @@ ENTRY(_sys_call_table) | |||
1357 | .long _sys_newuname | 1382 | .long _sys_newuname |
1358 | .long _sys_ni_syscall /* old sys_modify_ldt */ | 1383 | .long _sys_ni_syscall /* old sys_modify_ldt */ |
1359 | .long _sys_adjtimex | 1384 | .long _sys_adjtimex |
1360 | .long _sys_ni_syscall /* 125 */ /* sys_mprotect */ | 1385 | .long _sys_mprotect /* 125 */ |
1361 | .long _sys_ni_syscall /* old sys_sigprocmask */ | 1386 | .long _sys_ni_syscall /* old sys_sigprocmask */ |
1362 | .long _sys_ni_syscall /* old "creat_module" */ | 1387 | .long _sys_ni_syscall /* old "creat_module" */ |
1363 | .long _sys_init_module | 1388 | .long _sys_init_module |
@@ -1376,16 +1401,16 @@ ENTRY(_sys_call_table) | |||
1376 | .long _sys_getdents | 1401 | .long _sys_getdents |
1377 | .long _sys_ni_syscall /* sys_select */ | 1402 | .long _sys_ni_syscall /* sys_select */ |
1378 | .long _sys_flock | 1403 | .long _sys_flock |
1379 | .long _sys_ni_syscall /* sys_msync */ | 1404 | .long _sys_msync |
1380 | .long _sys_readv /* 145 */ | 1405 | .long _sys_readv /* 145 */ |
1381 | .long _sys_writev | 1406 | .long _sys_writev |
1382 | .long _sys_getsid | 1407 | .long _sys_getsid |
1383 | .long _sys_fdatasync | 1408 | .long _sys_fdatasync |
1384 | .long _sys_sysctl | 1409 | .long _sys_sysctl |
1385 | .long _sys_ni_syscall /* 150 */ /* sys_mlock */ | 1410 | .long _sys_mlock /* 150 */ |
1386 | .long _sys_ni_syscall /* sys_munlock */ | 1411 | .long _sys_munlock |
1387 | .long _sys_ni_syscall /* sys_mlockall */ | 1412 | .long _sys_mlockall |
1388 | .long _sys_ni_syscall /* sys_munlockall */ | 1413 | .long _sys_munlockall |
1389 | .long _sys_sched_setparam | 1414 | .long _sys_sched_setparam |
1390 | .long _sys_sched_getparam /* 155 */ | 1415 | .long _sys_sched_getparam /* 155 */ |
1391 | .long _sys_sched_setscheduler | 1416 | .long _sys_sched_setscheduler |
@@ -1450,8 +1475,8 @@ ENTRY(_sys_call_table) | |||
1450 | .long _sys_setfsuid /* 215 */ | 1475 | .long _sys_setfsuid /* 215 */ |
1451 | .long _sys_setfsgid | 1476 | .long _sys_setfsgid |
1452 | .long _sys_pivot_root | 1477 | .long _sys_pivot_root |
1453 | .long _sys_ni_syscall /* sys_mincore */ | 1478 | .long _sys_mincore |
1454 | .long _sys_ni_syscall /* sys_madvise */ | 1479 | .long _sys_madvise |
1455 | .long _sys_getdents64 /* 220 */ | 1480 | .long _sys_getdents64 /* 220 */ |
1456 | .long _sys_fcntl64 | 1481 | .long _sys_fcntl64 |
1457 | .long _sys_ni_syscall /* reserved for TUX */ | 1482 | .long _sys_ni_syscall /* reserved for TUX */ |
@@ -1507,7 +1532,7 @@ ENTRY(_sys_call_table) | |||
1507 | .long _sys_utimes | 1532 | .long _sys_utimes |
1508 | .long _sys_fadvise64_64 | 1533 | .long _sys_fadvise64_64 |
1509 | .long _sys_ni_syscall /* vserver */ | 1534 | .long _sys_ni_syscall /* vserver */ |
1510 | .long _sys_ni_syscall /* 275, mbind */ | 1535 | .long _sys_mbind /* 275 */ |
1511 | .long _sys_ni_syscall /* get_mempolicy */ | 1536 | .long _sys_ni_syscall /* get_mempolicy */ |
1512 | .long _sys_ni_syscall /* set_mempolicy */ | 1537 | .long _sys_ni_syscall /* set_mempolicy */ |
1513 | .long _sys_mq_open | 1538 | .long _sys_mq_open |