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 @@
GLOBAL_ENTRY(efi_call_phys)
.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
mov loc0=rp
.body
......@@ -70,9 +70,13 @@ GLOBAL_ENTRY(efi_call_phys)
mov out3=in4
mov out5=in6
mov out6=in7
mov loc5=r19
mov loc6=r20
br.call.sptk.many rp=b6 // call the EFI function
.ret1: mov ar.rsc=0 // put RSE in enforced lazy, LE mode
mov r16=loc3
mov r19=loc5
mov r20=loc6
br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
.ret2: mov ar.rsc=loc4 // restore RSE configuration
mov ar.pfs=loc1
......
......@@ -706,6 +706,9 @@ END(__ia64_init_fpu)
*
* Inputs:
* 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
*/
......@@ -724,12 +727,13 @@ GLOBAL_ENTRY(ia64_switch_mode_phys)
mov cr.ipsr=r16 // set new PSR
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
;;
// going to physical mode, use tpa to translate virt->phys
tpa r17=r17
tpa r17=r19
tpa r3=r3
tpa sp=sp
tpa r14=r14
......@@ -752,6 +756,8 @@ END(ia64_switch_mode_phys)
*
* Inputs:
* r16 = new psr to establish
* r19 = new bspstore to establish
* r20 = new sp to establish
*
* Note: RSE must already be in enforced lazy mode
*/
......@@ -770,7 +776,6 @@ GLOBAL_ENTRY(ia64_switch_mode_virt)
mov cr.ipsr=r16 // set new PSR
add r3=1f-ia64_switch_mode_virt,r15
mov r17=ar.bsp
mov r14=rp // get return address into a general register
;;
......@@ -781,15 +786,14 @@ GLOBAL_ENTRY(ia64_switch_mode_virt)
movl r18=KERNEL_START
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 r17=-1,r17,61,3
dep sp=-1,sp,61,3
mov sp=r20
;;
or r3=r3,r18
or r14=r14,r18
;;
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.ifs=r0
;;
......
......@@ -176,10 +176,14 @@ GLOBAL_ENTRY(ia64_pal_call_phys_static)
andcm r16=loc3,r16 // removes bits to clear from psr
br.call.sptk.many rp=ia64_switch_mode_phys
.ret1: mov rp = r8 // install return address (physical)
mov loc5 = r19
mov loc6 = r20
br.cond.sptk.many b7
1:
mov ar.rsc=0 // put RSE in enforced lazy, LE mode
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
.ret2:
mov psr.l = loc3 // restore init PSR
......@@ -201,7 +205,7 @@ END(ia64_pal_call_phys_static)
*/
GLOBAL_ENTRY(ia64_pal_call_phys_stacked)
.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
1: {
mov r28 = in0 // copy procedure index
......@@ -230,10 +234,14 @@ GLOBAL_ENTRY(ia64_pal_call_phys_stacked)
andcm r16=loc3,r16 // removes bits to clear from psr
br.call.sptk.many rp=ia64_switch_mode_phys
.ret6:
mov loc5 = r19
mov loc6 = r20
br.call.sptk.many rp=b7 // now make the call
.ret7:
mov ar.rsc=0 // put RSE in enforced lazy, LE mode
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
.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