diff options
author | dfr <dfr@FreeBSD.org> | 2001-09-29 09:54:42 +0000 |
---|---|---|
committer | dfr <dfr@FreeBSD.org> | 2001-09-29 09:54:42 +0000 |
commit | d0640e1a8efbcde01ad6b5459743b2425c7c580c (patch) | |
tree | 472a16f79a88d10b716a5b7e0179b98fda472c46 /sys/ia64 | |
parent | 42d058c1597b3750e2d494af6702e6a21356eecd (diff) | |
download | FreeBSD-src-d0640e1a8efbcde01ad6b5459743b2425c7c580c.zip FreeBSD-src-d0640e1a8efbcde01ad6b5459743b2425c7c580c.tar.gz |
* Preserve ar.rsc in ia64_change_mode.
* Convert sp to/from physical in ia64_change_mode.
* Add a shim for calling EFI procedures in virtual mode.
Diffstat (limited to 'sys/ia64')
-rw-r--r-- | sys/ia64/ia64/support.S | 63 | ||||
-rw-r--r-- | sys/ia64/ia64/support.s | 63 |
2 files changed, 120 insertions, 6 deletions
diff --git a/sys/ia64/ia64/support.S b/sys/ia64/ia64/support.S index de4b178..7caaba6 100644 --- a/sys/ia64/ia64/support.S +++ b/sys/ia64/ia64/support.S @@ -63,13 +63,18 @@ * * Arguments: * r14 psr for desired mode + * + * Modifies: + * r15-r19 scratch + * ar.bsp tranlated to new mode */ ENTRY(ia64_change_mode, 0) rsm psr.i | psr.ic - mov ar.rsc=0 // turn off RSE + mov r19=ar.rsc // save rsc while we change mode tbit.nz p6,p7=r14,17 // physical or virtual ? ;; + mov ar.rsc=0 // turn off RSE (p6) mov r15=7 // RR base for virtual addresses (p7) mov r15=0 // RR base for physical addresses flushrs // no dirty registers please @@ -81,6 +86,7 @@ ENTRY(ia64_change_mode, 0) ;; dep r16=r15,r16,61,3 // new address of ar.bsp dep r17=r15,r17,61,3 // new address of rp + dep sp=r15,sp,61,3 // new address of sp ;; mov ar.bspstore=r16 mov rp=r17 @@ -98,7 +104,8 @@ ENTRY(ia64_change_mode, 0) ;; rfi -2: br.ret.sptk.few rp // now in new mode +2: mov ar.rsc=r19 // restore ar.rsc + br.ret.sptk.few rp // now in new mode END(ia64_change_mode) @@ -107,12 +114,17 @@ END(ia64_change_mode) * * Return: * ret0 psr to restore + * + * Modifies: + * r15-r18 scratch + * ar.bsp tranlated to physical mode + * psr.i cleared */ ENTRY(ia64_physical_mode, 0) mov r14=psr mov ret0=psr - movl r15=(IA64_PSR_I|IA64_PSR_IT|IA64_PSR_DT|IA64_PSR_RT) + movl r15=(IA64_PSR_I|IA64_PSR_IT|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFL|IA64_PSR_DFH) movl r16=IA64_PSR_BN ;; andcm r14=r14,r15 // clear various xT bits @@ -124,6 +136,51 @@ ENTRY(ia64_physical_mode, 0) END(ia64_physical_mode) +/* + * ia64_call_efi_physical: call an EFI procedure in physical mode + * + * Arguments: + * in0 Address of EFI procedure descriptor + * in1-in5 Arguments to EFI procedure + * + * Return: + * ret0-ret3 return values from EFI + * + */ +ENTRY(ia64_call_efi_physical, 6) + + alloc loc0=ar.pfs,6,4,5,0 + ;; + mov loc1=rp + ;; + br.call.sptk.many rp=ia64_physical_mode + ;; + mov loc2=r8 // psr to restore mode + mov loc3=gp // save kernel gp + ld8 r14=[in0],8 // function address + ;; + mov out0=in1 + mov out1=in2 + mov out2=in3 + mov out3=in4 + mov out4=in5 + ld8 gp=[in0] // function gp value + ;; + mov b6=r14 + ;; + br.call.sptk.many rp=b6 // call EFI procedure + mov gp=loc3 // restore kernel gp + ;; + mov r14=loc2 // psr to restore mode + br.call.sptk.many rp=ia64_change_mode + ;; + mov rp=loc1 + mov ar.pfs=loc0 + ;; + br.ret.sptk.many rp + +END(ia64_call_efi_physical) + /**************************************************************************/ /* diff --git a/sys/ia64/ia64/support.s b/sys/ia64/ia64/support.s index de4b178..7caaba6 100644 --- a/sys/ia64/ia64/support.s +++ b/sys/ia64/ia64/support.s @@ -63,13 +63,18 @@ * * Arguments: * r14 psr for desired mode + * + * Modifies: + * r15-r19 scratch + * ar.bsp tranlated to new mode */ ENTRY(ia64_change_mode, 0) rsm psr.i | psr.ic - mov ar.rsc=0 // turn off RSE + mov r19=ar.rsc // save rsc while we change mode tbit.nz p6,p7=r14,17 // physical or virtual ? ;; + mov ar.rsc=0 // turn off RSE (p6) mov r15=7 // RR base for virtual addresses (p7) mov r15=0 // RR base for physical addresses flushrs // no dirty registers please @@ -81,6 +86,7 @@ ENTRY(ia64_change_mode, 0) ;; dep r16=r15,r16,61,3 // new address of ar.bsp dep r17=r15,r17,61,3 // new address of rp + dep sp=r15,sp,61,3 // new address of sp ;; mov ar.bspstore=r16 mov rp=r17 @@ -98,7 +104,8 @@ ENTRY(ia64_change_mode, 0) ;; rfi -2: br.ret.sptk.few rp // now in new mode +2: mov ar.rsc=r19 // restore ar.rsc + br.ret.sptk.few rp // now in new mode END(ia64_change_mode) @@ -107,12 +114,17 @@ END(ia64_change_mode) * * Return: * ret0 psr to restore + * + * Modifies: + * r15-r18 scratch + * ar.bsp tranlated to physical mode + * psr.i cleared */ ENTRY(ia64_physical_mode, 0) mov r14=psr mov ret0=psr - movl r15=(IA64_PSR_I|IA64_PSR_IT|IA64_PSR_DT|IA64_PSR_RT) + movl r15=(IA64_PSR_I|IA64_PSR_IT|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFL|IA64_PSR_DFH) movl r16=IA64_PSR_BN ;; andcm r14=r14,r15 // clear various xT bits @@ -124,6 +136,51 @@ ENTRY(ia64_physical_mode, 0) END(ia64_physical_mode) +/* + * ia64_call_efi_physical: call an EFI procedure in physical mode + * + * Arguments: + * in0 Address of EFI procedure descriptor + * in1-in5 Arguments to EFI procedure + * + * Return: + * ret0-ret3 return values from EFI + * + */ +ENTRY(ia64_call_efi_physical, 6) + + alloc loc0=ar.pfs,6,4,5,0 + ;; + mov loc1=rp + ;; + br.call.sptk.many rp=ia64_physical_mode + ;; + mov loc2=r8 // psr to restore mode + mov loc3=gp // save kernel gp + ld8 r14=[in0],8 // function address + ;; + mov out0=in1 + mov out1=in2 + mov out2=in3 + mov out3=in4 + mov out4=in5 + ld8 gp=[in0] // function gp value + ;; + mov b6=r14 + ;; + br.call.sptk.many rp=b6 // call EFI procedure + mov gp=loc3 // restore kernel gp + ;; + mov r14=loc2 // psr to restore mode + br.call.sptk.many rp=ia64_change_mode + ;; + mov rp=loc1 + mov ar.pfs=loc0 + ;; + br.ret.sptk.many rp + +END(ia64_call_efi_physical) + /**************************************************************************/ /* |