Commit 911aa5ff authored by Kenneth W. Chen's avatar Kenneth W. Chen Committed by David Mosberger

[PATCH] ia64: change ia64_switch_mode_{phys,virt}() to preserve bsp/sp

Change ia64_switch_mode_phys() and ia64_switch_mode_virt() to preserve
the virtual sp/bsp and update the call-sites accordingly.  This avoids
problems with the init_task pointer which lives in region 5 now.
Signed-off-by: default avatarDavid Mosberger <davidm@hpl.hp.com>
parent 7eb86828
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
GLOBAL_ENTRY(efi_call_phys) GLOBAL_ENTRY(efi_call_phys)
.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8) .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
alloc loc1=ar.pfs,8,5,7,0 alloc loc1=ar.pfs,8,7,7,0
ld8 r2=[in0],8 // load EFI function's entry point ld8 r2=[in0],8 // load EFI function's entry point
mov loc0=rp mov loc0=rp
.body .body
...@@ -70,9 +70,13 @@ GLOBAL_ENTRY(efi_call_phys) ...@@ -70,9 +70,13 @@ GLOBAL_ENTRY(efi_call_phys)
mov out3=in4 mov out3=in4
mov out5=in6 mov out5=in6
mov out6=in7 mov out6=in7
mov loc5=r19
mov loc6=r20
br.call.sptk.many rp=b6 // call the EFI function br.call.sptk.many rp=b6 // call the EFI function
.ret1: mov ar.rsc=0 // put RSE in enforced lazy, LE mode .ret1: mov ar.rsc=0 // put RSE in enforced lazy, LE mode
mov r16=loc3 mov r16=loc3
mov r19=loc5
mov r20=loc6
br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
.ret2: mov ar.rsc=loc4 // restore RSE configuration .ret2: mov ar.rsc=loc4 // restore RSE configuration
mov ar.pfs=loc1 mov ar.pfs=loc1
......
...@@ -706,6 +706,9 @@ END(__ia64_init_fpu) ...@@ -706,6 +706,9 @@ END(__ia64_init_fpu)
* *
* Inputs: * Inputs:
* r16 = new psr to establish * r16 = new psr to establish
* Output:
* r19 = old virtual address of ar.bsp
* r20 = old virtual address of sp
* *
* Note: RSE must already be in enforced lazy mode * Note: RSE must already be in enforced lazy mode
*/ */
...@@ -724,12 +727,13 @@ GLOBAL_ENTRY(ia64_switch_mode_phys) ...@@ -724,12 +727,13 @@ GLOBAL_ENTRY(ia64_switch_mode_phys)
mov cr.ipsr=r16 // set new PSR mov cr.ipsr=r16 // set new PSR
add r3=1f-ia64_switch_mode_phys,r15 add r3=1f-ia64_switch_mode_phys,r15
mov r17=ar.bsp mov r19=ar.bsp
mov r20=sp
mov r14=rp // get return address into a general register mov r14=rp // get return address into a general register
;; ;;
// going to physical mode, use tpa to translate virt->phys // going to physical mode, use tpa to translate virt->phys
tpa r17=r17 tpa r17=r19
tpa r3=r3 tpa r3=r3
tpa sp=sp tpa sp=sp
tpa r14=r14 tpa r14=r14
...@@ -752,6 +756,8 @@ END(ia64_switch_mode_phys) ...@@ -752,6 +756,8 @@ END(ia64_switch_mode_phys)
* *
* Inputs: * Inputs:
* r16 = new psr to establish * r16 = new psr to establish
* r19 = new bspstore to establish
* r20 = new sp to establish
* *
* Note: RSE must already be in enforced lazy mode * Note: RSE must already be in enforced lazy mode
*/ */
...@@ -770,7 +776,6 @@ GLOBAL_ENTRY(ia64_switch_mode_virt) ...@@ -770,7 +776,6 @@ GLOBAL_ENTRY(ia64_switch_mode_virt)
mov cr.ipsr=r16 // set new PSR mov cr.ipsr=r16 // set new PSR
add r3=1f-ia64_switch_mode_virt,r15 add r3=1f-ia64_switch_mode_virt,r15
mov r17=ar.bsp
mov r14=rp // get return address into a general register mov r14=rp // get return address into a general register
;; ;;
...@@ -781,15 +786,14 @@ GLOBAL_ENTRY(ia64_switch_mode_virt) ...@@ -781,15 +786,14 @@ GLOBAL_ENTRY(ia64_switch_mode_virt)
movl r18=KERNEL_START movl r18=KERNEL_START
dep r3=0,r3,KERNEL_TR_PAGE_SHIFT,64-KERNEL_TR_PAGE_SHIFT dep r3=0,r3,KERNEL_TR_PAGE_SHIFT,64-KERNEL_TR_PAGE_SHIFT
dep r14=0,r14,KERNEL_TR_PAGE_SHIFT,64-KERNEL_TR_PAGE_SHIFT dep r14=0,r14,KERNEL_TR_PAGE_SHIFT,64-KERNEL_TR_PAGE_SHIFT
dep r17=-1,r17,61,3 mov sp=r20
dep sp=-1,sp,61,3
;; ;;
or r3=r3,r18 or r3=r3,r18
or r14=r14,r18 or r14=r14,r18
;; ;;
mov r18=ar.rnat // save ar.rnat mov r18=ar.rnat // save ar.rnat
mov ar.bspstore=r17 // this steps on ar.rnat mov ar.bspstore=r19 // this steps on ar.rnat
mov cr.iip=r3 mov cr.iip=r3
mov cr.ifs=r0 mov cr.ifs=r0
;; ;;
......
...@@ -176,10 +176,14 @@ GLOBAL_ENTRY(ia64_pal_call_phys_static) ...@@ -176,10 +176,14 @@ GLOBAL_ENTRY(ia64_pal_call_phys_static)
andcm r16=loc3,r16 // removes bits to clear from psr andcm r16=loc3,r16 // removes bits to clear from psr
br.call.sptk.many rp=ia64_switch_mode_phys br.call.sptk.many rp=ia64_switch_mode_phys
.ret1: mov rp = r8 // install return address (physical) .ret1: mov rp = r8 // install return address (physical)
mov loc5 = r19
mov loc6 = r20
br.cond.sptk.many b7 br.cond.sptk.many b7
1: 1:
mov ar.rsc=0 // put RSE in enforced lazy, LE mode mov ar.rsc=0 // put RSE in enforced lazy, LE mode
mov r16=loc3 // r16= original psr mov r16=loc3 // r16= original psr
mov r19=loc5
mov r20=loc6
br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
.ret2: .ret2:
mov psr.l = loc3 // restore init PSR mov psr.l = loc3 // restore init PSR
...@@ -201,7 +205,7 @@ END(ia64_pal_call_phys_static) ...@@ -201,7 +205,7 @@ END(ia64_pal_call_phys_static)
*/ */
GLOBAL_ENTRY(ia64_pal_call_phys_stacked) GLOBAL_ENTRY(ia64_pal_call_phys_stacked)
.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5) .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5)
alloc loc1 = ar.pfs,5,5,86,0 alloc loc1 = ar.pfs,5,7,4,0
movl loc2 = pal_entry_point movl loc2 = pal_entry_point
1: { 1: {
mov r28 = in0 // copy procedure index mov r28 = in0 // copy procedure index
...@@ -230,10 +234,14 @@ GLOBAL_ENTRY(ia64_pal_call_phys_stacked) ...@@ -230,10 +234,14 @@ GLOBAL_ENTRY(ia64_pal_call_phys_stacked)
andcm r16=loc3,r16 // removes bits to clear from psr andcm r16=loc3,r16 // removes bits to clear from psr
br.call.sptk.many rp=ia64_switch_mode_phys br.call.sptk.many rp=ia64_switch_mode_phys
.ret6: .ret6:
mov loc5 = r19
mov loc6 = r20
br.call.sptk.many rp=b7 // now make the call br.call.sptk.many rp=b7 // now make the call
.ret7: .ret7:
mov ar.rsc=0 // put RSE in enforced lazy, LE mode mov ar.rsc=0 // put RSE in enforced lazy, LE mode
mov r16=loc3 // r16= original psr mov r16=loc3 // r16= original psr
mov r19=loc5
mov r20=loc6
br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
.ret8: mov psr.l = loc3 // restore init PSR .ret8: mov psr.l = loc3 // restore init PSR
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment