diff options
Diffstat (limited to 'arch/ia64/kernel/entry.S')
| -rw-r--r-- | arch/ia64/kernel/entry.S | 110 |
1 files changed, 52 insertions, 58 deletions
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 785a51b0ad8e..69f88d561d62 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S | |||
| @@ -470,18 +470,6 @@ ENTRY(load_switch_stack) | |||
| 470 | br.cond.sptk.many b7 | 470 | br.cond.sptk.many b7 |
| 471 | END(load_switch_stack) | 471 | END(load_switch_stack) |
| 472 | 472 | ||
| 473 | GLOBAL_ENTRY(__ia64_syscall) | ||
| 474 | .regstk 6,0,0,0 | ||
| 475 | mov r15=in5 // put syscall number in place | ||
| 476 | break __BREAK_SYSCALL | ||
| 477 | movl r2=errno | ||
| 478 | cmp.eq p6,p7=-1,r10 | ||
| 479 | ;; | ||
| 480 | (p6) st4 [r2]=r8 | ||
| 481 | (p6) mov r8=-1 | ||
| 482 | br.ret.sptk.many rp | ||
| 483 | END(__ia64_syscall) | ||
| 484 | |||
| 485 | GLOBAL_ENTRY(execve) | 473 | GLOBAL_ENTRY(execve) |
| 486 | mov r15=__NR_execve // put syscall number in place | 474 | mov r15=__NR_execve // put syscall number in place |
| 487 | break __BREAK_SYSCALL | 475 | break __BREAK_SYSCALL |
| @@ -637,7 +625,7 @@ END(ia64_ret_from_syscall) | |||
| 637 | * r8-r11: restored (syscall return value(s)) | 625 | * r8-r11: restored (syscall return value(s)) |
| 638 | * r12: restored (user-level stack pointer) | 626 | * r12: restored (user-level stack pointer) |
| 639 | * r13: restored (user-level thread pointer) | 627 | * r13: restored (user-level thread pointer) |
| 640 | * r14: cleared | 628 | * r14: set to __kernel_syscall_via_epc |
| 641 | * r15: restored (syscall #) | 629 | * r15: restored (syscall #) |
| 642 | * r16-r17: cleared | 630 | * r16-r17: cleared |
| 643 | * r18: user-level b6 | 631 | * r18: user-level b6 |
| @@ -658,7 +646,7 @@ END(ia64_ret_from_syscall) | |||
| 658 | * pr: restored (user-level pr) | 646 | * pr: restored (user-level pr) |
| 659 | * b0: restored (user-level rp) | 647 | * b0: restored (user-level rp) |
| 660 | * b6: restored | 648 | * b6: restored |
| 661 | * b7: cleared | 649 | * b7: set to __kernel_syscall_via_epc |
| 662 | * ar.unat: restored (user-level ar.unat) | 650 | * ar.unat: restored (user-level ar.unat) |
| 663 | * ar.pfs: restored (user-level ar.pfs) | 651 | * ar.pfs: restored (user-level ar.pfs) |
| 664 | * ar.rsc: restored (user-level ar.rsc) | 652 | * ar.rsc: restored (user-level ar.rsc) |
| @@ -704,72 +692,79 @@ ENTRY(ia64_leave_syscall) | |||
| 704 | ;; | 692 | ;; |
| 705 | (p6) ld4 r31=[r18] // load current_thread_info()->flags | 693 | (p6) ld4 r31=[r18] // load current_thread_info()->flags |
| 706 | ld8 r19=[r2],PT(B6)-PT(LOADRS) // load ar.rsc value for "loadrs" | 694 | ld8 r19=[r2],PT(B6)-PT(LOADRS) // load ar.rsc value for "loadrs" |
| 707 | mov b7=r0 // clear b7 | 695 | nop.i 0 |
| 708 | ;; | 696 | ;; |
| 709 | ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE) // load ar.bspstore (may be garbage) | 697 | mov r16=ar.bsp // M2 get existing backing store pointer |
| 710 | ld8 r18=[r2],PT(R9)-PT(B6) // load b6 | 698 | ld8 r18=[r2],PT(R9)-PT(B6) // load b6 |
| 711 | (p6) and r15=TIF_WORK_MASK,r31 // any work other than TIF_SYSCALL_TRACE? | 699 | (p6) and r15=TIF_WORK_MASK,r31 // any work other than TIF_SYSCALL_TRACE? |
| 712 | ;; | 700 | ;; |
| 713 | mov r16=ar.bsp // M2 get existing backing store pointer | 701 | ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE) // load ar.bspstore (may be garbage) |
| 714 | (p6) cmp4.ne.unc p6,p0=r15, r0 // any special work pending? | 702 | (p6) cmp4.ne.unc p6,p0=r15, r0 // any special work pending? |
| 715 | (p6) br.cond.spnt .work_pending_syscall | 703 | (p6) br.cond.spnt .work_pending_syscall |
| 716 | ;; | 704 | ;; |
| 717 | // start restoring the state saved on the kernel stack (struct pt_regs): | 705 | // start restoring the state saved on the kernel stack (struct pt_regs): |
| 718 | ld8 r9=[r2],PT(CR_IPSR)-PT(R9) | 706 | ld8 r9=[r2],PT(CR_IPSR)-PT(R9) |
| 719 | ld8 r11=[r3],PT(CR_IIP)-PT(R11) | 707 | ld8 r11=[r3],PT(CR_IIP)-PT(R11) |
| 720 | mov f6=f0 // clear f6 | 708 | (pNonSys) break 0 // bug check: we shouldn't be here if pNonSys is TRUE! |
| 721 | ;; | 709 | ;; |
| 722 | invala // M0|1 invalidate ALAT | 710 | invala // M0|1 invalidate ALAT |
| 723 | rsm psr.i | psr.ic // M2 initiate turning off of interrupt and interruption collection | 711 | rsm psr.i | psr.ic // M2 turn off interrupts and interruption collection |
| 724 | mov f9=f0 // clear f9 | 712 | cmp.eq p9,p0=r0,r0 // A set p9 to indicate that we should restore cr.ifs |
| 725 | 713 | ||
| 726 | ld8 r29=[r2],16 // load cr.ipsr | 714 | ld8 r29=[r2],16 // M0|1 load cr.ipsr |
| 727 | ld8 r28=[r3],16 // load cr.iip | 715 | ld8 r28=[r3],16 // M0|1 load cr.iip |
| 728 | mov f8=f0 // clear f8 | 716 | mov r22=r0 // A clear r22 |
| 729 | ;; | 717 | ;; |
| 730 | ld8 r30=[r2],16 // M0|1 load cr.ifs | 718 | ld8 r30=[r2],16 // M0|1 load cr.ifs |
| 731 | ld8 r25=[r3],16 // M0|1 load ar.unat | 719 | ld8 r25=[r3],16 // M0|1 load ar.unat |
| 732 | cmp.eq p9,p0=r0,r0 // set p9 to indicate that we should restore cr.ifs | 720 | (pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13 |
| 733 | ;; | 721 | ;; |
| 734 | ld8 r26=[r2],PT(B0)-PT(AR_PFS) // M0|1 load ar.pfs | 722 | ld8 r26=[r2],PT(B0)-PT(AR_PFS) // M0|1 load ar.pfs |
| 735 | (pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled | 723 | (pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled |
| 736 | mov f10=f0 // clear f10 | 724 | nop 0 |
| 737 | ;; | 725 | ;; |
| 738 | ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // load b0 | 726 | ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // M0|1 load b0 |
| 739 | ld8 r27=[r3],PT(PR)-PT(AR_RSC) // load ar.rsc | 727 | ld8 r27=[r3],PT(PR)-PT(AR_RSC) // M0|1 load ar.rsc |
| 740 | mov f11=f0 // clear f11 | 728 | mov f6=f0 // F clear f6 |
| 741 | ;; | 729 | ;; |
| 742 | ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT) // load ar.rnat (may be garbage) | 730 | ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT) // M0|1 load ar.rnat (may be garbage) |
| 743 | ld8 r31=[r3],PT(R1)-PT(PR) // load predicates | 731 | ld8 r31=[r3],PT(R1)-PT(PR) // M0|1 load predicates |
| 744 | (pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13 | 732 | mov f7=f0 // F clear f7 |
| 745 | ;; | 733 | ;; |
| 746 | ld8 r20=[r2],PT(R12)-PT(AR_FPSR) // load ar.fpsr | 734 | ld8 r20=[r2],PT(R12)-PT(AR_FPSR) // M0|1 load ar.fpsr |
| 747 | ld8.fill r1=[r3],16 // load r1 | 735 | ld8.fill r1=[r3],16 // M0|1 load r1 |
| 748 | (pUStk) mov r17=1 | 736 | (pUStk) mov r17=1 // A |
| 749 | ;; | 737 | ;; |
| 750 | srlz.d // M0 ensure interruption collection is off | 738 | (pUStk) st1 [r14]=r17 // M2|3 |
| 751 | ld8.fill r13=[r3],16 | 739 | ld8.fill r13=[r3],16 // M0|1 |
| 752 | mov f7=f0 // clear f7 | 740 | mov f8=f0 // F clear f8 |
| 753 | ;; | 741 | ;; |
| 754 | ld8.fill r12=[r2] // restore r12 (sp) | 742 | ld8.fill r12=[r2] // M0|1 restore r12 (sp) |
| 755 | mov.m ar.ssd=r0 // M2 clear ar.ssd | 743 | ld8.fill r15=[r3] // M0|1 restore r15 |
| 756 | mov r22=r0 // clear r22 | 744 | mov b6=r18 // I0 restore b6 |
| 757 | 745 | ||
| 758 | ld8.fill r15=[r3] // restore r15 | 746 | addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 // A |
| 759 | (pUStk) st1 [r14]=r17 | 747 | mov f9=f0 // F clear f9 |
| 760 | addl r3=THIS_CPU(ia64_phys_stacked_size_p8),r0 | 748 | (pKStk) br.cond.dpnt.many skip_rbs_switch // B |
| 749 | |||
| 750 | srlz.d // M0 ensure interruption collection is off (for cover) | ||
| 751 | shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition | ||
| 752 | cover // B add current frame into dirty partition & set cr.ifs | ||
| 761 | ;; | 753 | ;; |
| 762 | (pUStk) ld4 r17=[r3] // r17 = cpu_data->phys_stacked_size_p8 | 754 | (pUStk) ld4 r17=[r17] // M0|1 r17 = cpu_data->phys_stacked_size_p8 |
| 763 | mov.m ar.csd=r0 // M2 clear ar.csd | 755 | mov r19=ar.bsp // M2 get new backing store pointer |
| 764 | mov b6=r18 // I0 restore b6 | 756 | mov f10=f0 // F clear f10 |
| 757 | |||
| 758 | nop.m 0 | ||
| 759 | movl r14=__kernel_syscall_via_epc // X | ||
| 765 | ;; | 760 | ;; |
| 766 | mov r14=r0 // clear r14 | 761 | mov.m ar.csd=r0 // M2 clear ar.csd |
| 767 | shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition | 762 | mov.m ar.ccv=r0 // M2 clear ar.ccv |
| 768 | (pKStk) br.cond.dpnt.many skip_rbs_switch | 763 | mov b7=r14 // I0 clear b7 (hint with __kernel_syscall_via_epc) |
| 769 | 764 | ||
| 770 | mov.m ar.ccv=r0 // clear ar.ccv | 765 | mov.m ar.ssd=r0 // M2 clear ar.ssd |
| 771 | (pNonSys) br.cond.dpnt.many dont_preserve_current_frame | 766 | mov f11=f0 // F clear f11 |
| 772 | br.cond.sptk.many rbs_switch | 767 | br.cond.sptk.many rbs_switch // B |
| 773 | END(ia64_leave_syscall) | 768 | END(ia64_leave_syscall) |
| 774 | 769 | ||
| 775 | #ifdef CONFIG_IA32_SUPPORT | 770 | #ifdef CONFIG_IA32_SUPPORT |
| @@ -885,7 +880,7 @@ GLOBAL_ENTRY(ia64_leave_kernel) | |||
| 885 | ldf.fill f7=[r2],PT(F11)-PT(F7) | 880 | ldf.fill f7=[r2],PT(F11)-PT(F7) |
| 886 | ldf.fill f8=[r3],32 | 881 | ldf.fill f8=[r3],32 |
| 887 | ;; | 882 | ;; |
| 888 | srlz.i // ensure interruption collection is off | 883 | srlz.d // ensure that inter. collection is off (VHPT is don't care, since text is pinned) |
| 889 | mov ar.ccv=r15 | 884 | mov ar.ccv=r15 |
| 890 | ;; | 885 | ;; |
| 891 | ldf.fill f11=[r2] | 886 | ldf.fill f11=[r2] |
| @@ -945,11 +940,10 @@ GLOBAL_ENTRY(ia64_leave_kernel) | |||
| 945 | * NOTE: alloc, loadrs, and cover can't be predicated. | 940 | * NOTE: alloc, loadrs, and cover can't be predicated. |
| 946 | */ | 941 | */ |
| 947 | (pNonSys) br.cond.dpnt dont_preserve_current_frame | 942 | (pNonSys) br.cond.dpnt dont_preserve_current_frame |
| 948 | |||
| 949 | rbs_switch: | ||
| 950 | cover // add current frame into dirty partition and set cr.ifs | 943 | cover // add current frame into dirty partition and set cr.ifs |
| 951 | ;; | 944 | ;; |
| 952 | mov r19=ar.bsp // get new backing store pointer | 945 | mov r19=ar.bsp // get new backing store pointer |
| 946 | rbs_switch: | ||
| 953 | sub r16=r16,r18 // krbs = old bsp - size of dirty partition | 947 | sub r16=r16,r18 // krbs = old bsp - size of dirty partition |
| 954 | cmp.ne p9,p0=r0,r0 // clear p9 to skip restore of cr.ifs | 948 | cmp.ne p9,p0=r0,r0 // clear p9 to skip restore of cr.ifs |
| 955 | ;; | 949 | ;; |
| @@ -1024,14 +1018,14 @@ rse_clear_invalid: | |||
| 1024 | mov loc5=0 | 1018 | mov loc5=0 |
| 1025 | mov loc6=0 | 1019 | mov loc6=0 |
| 1026 | mov loc7=0 | 1020 | mov loc7=0 |
| 1027 | (pRecurse) br.call.sptk.few b0=rse_clear_invalid | 1021 | (pRecurse) br.call.dptk.few b0=rse_clear_invalid |
| 1028 | ;; | 1022 | ;; |
| 1029 | mov loc8=0 | 1023 | mov loc8=0 |
| 1030 | mov loc9=0 | 1024 | mov loc9=0 |
| 1031 | cmp.ne pReturn,p0=r0,in1 // if recursion count != 0, we need to do a br.ret | 1025 | cmp.ne pReturn,p0=r0,in1 // if recursion count != 0, we need to do a br.ret |
| 1032 | mov loc10=0 | 1026 | mov loc10=0 |
| 1033 | mov loc11=0 | 1027 | mov loc11=0 |
| 1034 | (pReturn) br.ret.sptk.many b0 | 1028 | (pReturn) br.ret.dptk.many b0 |
| 1035 | #endif /* !CONFIG_ITANIUM */ | 1029 | #endif /* !CONFIG_ITANIUM */ |
| 1036 | # undef pRecurse | 1030 | # undef pRecurse |
| 1037 | # undef pReturn | 1031 | # undef pReturn |
