diff options
Diffstat (limited to 'arch/ia64/kernel/mca_asm.S')
| -rw-r--r-- | arch/ia64/kernel/mca_asm.S | 96 |
1 files changed, 85 insertions, 11 deletions
diff --git a/arch/ia64/kernel/mca_asm.S b/arch/ia64/kernel/mca_asm.S index 499a065f4e60..db32fc1d3935 100644 --- a/arch/ia64/kernel/mca_asm.S +++ b/arch/ia64/kernel/mca_asm.S | |||
| @@ -489,24 +489,27 @@ ia64_state_save: | |||
| 489 | ;; | 489 | ;; |
| 490 | st8 [temp1]=r17,16 // pal_min_state | 490 | st8 [temp1]=r17,16 // pal_min_state |
| 491 | st8 [temp2]=r6,16 // prev_IA64_KR_CURRENT | 491 | st8 [temp2]=r6,16 // prev_IA64_KR_CURRENT |
| 492 | mov r6=IA64_KR(CURRENT_STACK) | ||
| 493 | ;; | ||
| 494 | st8 [temp1]=r6,16 // prev_IA64_KR_CURRENT_STACK | ||
| 495 | st8 [temp2]=r0,16 // prev_task, starts off as NULL | ||
| 492 | mov r6=cr.ifa | 496 | mov r6=cr.ifa |
| 493 | ;; | 497 | ;; |
| 494 | st8 [temp1]=r0,16 // prev_task, starts off as NULL | 498 | st8 [temp1]=r12,16 // cr.isr |
| 495 | st8 [temp2]=r12,16 // cr.isr | 499 | st8 [temp2]=r6,16 // cr.ifa |
| 496 | mov r12=cr.itir | 500 | mov r12=cr.itir |
| 497 | ;; | 501 | ;; |
| 498 | st8 [temp1]=r6,16 // cr.ifa | 502 | st8 [temp1]=r12,16 // cr.itir |
| 499 | st8 [temp2]=r12,16 // cr.itir | 503 | st8 [temp2]=r11,16 // cr.iipa |
| 500 | mov r12=cr.iim | 504 | mov r12=cr.iim |
| 501 | ;; | 505 | ;; |
| 502 | st8 [temp1]=r11,16 // cr.iipa | 506 | st8 [temp1]=r12,16 // cr.iim |
| 503 | st8 [temp2]=r12,16 // cr.iim | ||
| 504 | mov r6=cr.iha | ||
| 505 | (p1) mov r12=IA64_MCA_COLD_BOOT | 507 | (p1) mov r12=IA64_MCA_COLD_BOOT |
| 506 | (p2) mov r12=IA64_INIT_WARM_BOOT | 508 | (p2) mov r12=IA64_INIT_WARM_BOOT |
| 509 | mov r6=cr.iha | ||
| 507 | ;; | 510 | ;; |
| 508 | st8 [temp1]=r6,16 // cr.iha | 511 | st8 [temp2]=r6,16 // cr.iha |
| 509 | st8 [temp2]=r12 // os_status, default is cold boot | 512 | st8 [temp1]=r12 // os_status, default is cold boot |
| 510 | mov r6=IA64_MCA_SAME_CONTEXT | 513 | mov r6=IA64_MCA_SAME_CONTEXT |
| 511 | ;; | 514 | ;; |
| 512 | st8 [temp1]=r6 // context, default is same context | 515 | st8 [temp1]=r6 // context, default is same context |
| @@ -823,9 +826,12 @@ ia64_state_restore: | |||
| 823 | ld8 r12=[temp1],16 // sal_ra | 826 | ld8 r12=[temp1],16 // sal_ra |
| 824 | ld8 r9=[temp2],16 // sal_gp | 827 | ld8 r9=[temp2],16 // sal_gp |
| 825 | ;; | 828 | ;; |
| 826 | ld8 r22=[temp1],24 // pal_min_state, virtual. skip prev_task | 829 | ld8 r22=[temp1],16 // pal_min_state, virtual |
| 827 | ld8 r21=[temp2],16 // prev_IA64_KR_CURRENT | 830 | ld8 r21=[temp2],16 // prev_IA64_KR_CURRENT |
| 828 | ;; | 831 | ;; |
| 832 | ld8 r16=[temp1],16 // prev_IA64_KR_CURRENT_STACK | ||
| 833 | ld8 r20=[temp2],16 // prev_task | ||
| 834 | ;; | ||
| 829 | ld8 temp3=[temp1],16 // cr.isr | 835 | ld8 temp3=[temp1],16 // cr.isr |
| 830 | ld8 temp4=[temp2],16 // cr.ifa | 836 | ld8 temp4=[temp2],16 // cr.ifa |
| 831 | ;; | 837 | ;; |
| @@ -846,6 +852,45 @@ ia64_state_restore: | |||
| 846 | ld8 r8=[temp1] // os_status | 852 | ld8 r8=[temp1] // os_status |
| 847 | ld8 r10=[temp2] // context | 853 | ld8 r10=[temp2] // context |
| 848 | 854 | ||
| 855 | /* Wire IA64_TR_CURRENT_STACK to the stack that we are resuming to. To | ||
| 856 | * avoid any dependencies on the algorithm in ia64_switch_to(), just | ||
| 857 | * purge any existing CURRENT_STACK mapping and insert the new one. | ||
| 858 | * | ||
| 859 | * r16 contains prev_IA64_KR_CURRENT_STACK, r21 contains | ||
| 860 | * prev_IA64_KR_CURRENT, these values may have been changed by the C | ||
| 861 | * code. Do not use r8, r9, r10, r22, they contain values ready for | ||
| 862 | * the return to SAL. | ||
| 863 | */ | ||
| 864 | |||
| 865 | mov r15=IA64_KR(CURRENT_STACK) // physical granule mapped by IA64_TR_CURRENT_STACK | ||
| 866 | ;; | ||
| 867 | shl r15=r15,IA64_GRANULE_SHIFT | ||
| 868 | ;; | ||
| 869 | dep r15=-1,r15,61,3 // virtual granule | ||
| 870 | mov r18=IA64_GRANULE_SHIFT<<2 // for cr.itir.ps | ||
| 871 | ;; | ||
| 872 | ptr.d r15,r18 | ||
| 873 | ;; | ||
| 874 | srlz.d | ||
| 875 | |||
| 876 | extr.u r19=r21,61,3 // r21 = prev_IA64_KR_CURRENT | ||
| 877 | shl r20=r16,IA64_GRANULE_SHIFT // r16 = prev_IA64_KR_CURRENT_STACK | ||
| 878 | movl r21=PAGE_KERNEL // page properties | ||
| 879 | ;; | ||
| 880 | mov IA64_KR(CURRENT_STACK)=r16 | ||
| 881 | cmp.ne p6,p0=RGN_KERNEL,r19 // new stack is in the kernel region? | ||
| 882 | or r21=r20,r21 // construct PA | page properties | ||
| 883 | (p6) br.spnt 1f // the dreaded cpu 0 idle task in region 5:( | ||
| 884 | ;; | ||
| 885 | mov cr.itir=r18 | ||
| 886 | mov cr.ifa=r21 | ||
| 887 | mov r20=IA64_TR_CURRENT_STACK | ||
| 888 | ;; | ||
| 889 | itr.d dtr[r20]=r21 | ||
| 890 | ;; | ||
| 891 | srlz.d | ||
| 892 | 1: | ||
| 893 | |||
| 849 | br.sptk b0 | 894 | br.sptk b0 |
| 850 | 895 | ||
| 851 | //EndStub////////////////////////////////////////////////////////////////////// | 896 | //EndStub////////////////////////////////////////////////////////////////////// |
| @@ -982,6 +1027,7 @@ ia64_set_kernel_registers: | |||
| 982 | add temp4=temp4, temp1 // &struct ia64_sal_os_state.os_gp | 1027 | add temp4=temp4, temp1 // &struct ia64_sal_os_state.os_gp |
| 983 | add r12=temp1, temp3 // kernel stack pointer on MCA/INIT stack | 1028 | add r12=temp1, temp3 // kernel stack pointer on MCA/INIT stack |
| 984 | add r13=temp1, r3 // set current to start of MCA/INIT stack | 1029 | add r13=temp1, r3 // set current to start of MCA/INIT stack |
| 1030 | add r20=temp1, r3 // physical start of MCA/INIT stack | ||
| 985 | ;; | 1031 | ;; |
| 986 | ld8 r1=[temp4] // OS GP from SAL OS state | 1032 | ld8 r1=[temp4] // OS GP from SAL OS state |
| 987 | ;; | 1033 | ;; |
| @@ -991,7 +1037,35 @@ ia64_set_kernel_registers: | |||
| 991 | ;; | 1037 | ;; |
| 992 | mov IA64_KR(CURRENT)=r13 | 1038 | mov IA64_KR(CURRENT)=r13 |
| 993 | 1039 | ||
| 994 | // FIXME: do I need to wire IA64_KR_CURRENT_STACK and IA64_TR_CURRENT_STACK? | 1040 | /* Wire IA64_TR_CURRENT_STACK to the MCA/INIT handler stack. To avoid |
| 1041 | * any dependencies on the algorithm in ia64_switch_to(), just purge | ||
| 1042 | * any existing CURRENT_STACK mapping and insert the new one. | ||
| 1043 | */ | ||
| 1044 | |||
| 1045 | mov r16=IA64_KR(CURRENT_STACK) // physical granule mapped by IA64_TR_CURRENT_STACK | ||
| 1046 | ;; | ||
| 1047 | shl r16=r16,IA64_GRANULE_SHIFT | ||
| 1048 | ;; | ||
| 1049 | dep r16=-1,r16,61,3 // virtual granule | ||
| 1050 | mov r18=IA64_GRANULE_SHIFT<<2 // for cr.itir.ps | ||
| 1051 | ;; | ||
| 1052 | ptr.d r16,r18 | ||
| 1053 | ;; | ||
| 1054 | srlz.d | ||
| 1055 | |||
| 1056 | shr.u r16=r20,IA64_GRANULE_SHIFT // r20 = physical start of MCA/INIT stack | ||
| 1057 | movl r21=PAGE_KERNEL // page properties | ||
| 1058 | ;; | ||
| 1059 | mov IA64_KR(CURRENT_STACK)=r16 | ||
| 1060 | or r21=r20,r21 // construct PA | page properties | ||
| 1061 | ;; | ||
| 1062 | mov cr.itir=r18 | ||
| 1063 | mov cr.ifa=r13 | ||
| 1064 | mov r20=IA64_TR_CURRENT_STACK | ||
| 1065 | ;; | ||
| 1066 | itr.d dtr[r20]=r21 | ||
| 1067 | ;; | ||
| 1068 | srlz.d | ||
| 995 | 1069 | ||
| 996 | br.sptk b0 | 1070 | br.sptk b0 |
| 997 | 1071 | ||
