summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>2001-09-24 17:07:23 +0000
committerdfr <dfr@FreeBSD.org>2001-09-24 17:07:23 +0000
commitf08f7cc358adca3dc4d8e633adec09cf038363b8 (patch)
treecc6081b89940e846684058221bac7df6361705c5 /sys
parenta6b2db14f696e8960f27acd3ff55e62f8d79a85a (diff)
downloadFreeBSD-src-f08f7cc358adca3dc4d8e633adec09cf038363b8.zip
FreeBSD-src-f08f7cc358adca3dc4d8e633adec09cf038363b8.tar.gz
Add some code which can be used to change to/from physical mode when
calling various firmware functions.
Diffstat (limited to 'sys')
-rw-r--r--sys/ia64/ia64/support.S67
-rw-r--r--sys/ia64/ia64/support.s67
2 files changed, 134 insertions, 0 deletions
diff --git a/sys/ia64/ia64/support.S b/sys/ia64/ia64/support.S
index d6c71d5..ad537e8 100644
--- a/sys/ia64/ia64/support.S
+++ b/sys/ia64/ia64/support.S
@@ -53,10 +53,77 @@
*/
#include <machine/asm.h>
+#include <machine/ia64_cpu.h>
#include <assym.s>
.text
+/*
+ * ia64_change_mode: change mode to/from physical mode
+ *
+ * Arguments:
+ * r14 psr for desired mode
+ */
+ENTRY(ia64_change_mode, 0)
+
+ rsm psr.i | psr.ic
+ mov ar.rsc=0 // turn off RSE
+ tbit.nz p6,p7=r14,17 // physical or virtual ?
+ ;;
+(p6) mov r15=7 // RR base for virtual addresses
+(p7) mov r15=0 // RR base for physical addresses
+ flushrs // no dirty registers please
+ srlz.i
+ ;;
+ mov r16=ar.bsp
+ mov r17=rp
+ mov r18=ar.rnat
+ ;;
+ dep r16=r15,r16,61,3 // new address of ar.bsp
+ dep r17=r15,r17,61,3 // new address of rp
+ ;;
+ mov ar.bspstore=r16
+ mov rp=r17
+ ;;
+1: mov r16=ip
+ mov ar.rnat=r18
+ mov cr.ipsr=r14 // psr for physical mode
+ ;;
+ add r16=2f-1b,r16 // address to rfi to
+ ;;
+ dep r16=r15,r16,61,3 // physical
+ ;;
+ mov cr.iip=r16 // setup for rfi
+ mov cr.ifs=r0
+ ;;
+ rfi
+
+2: br.ret.sptk.few rp // now in physical mode
+
+END(ia64_change_mode)
+
+/*
+ * ia64_physical_mode: change mode to physical mode
+ *
+ * Return:
+ * ret0 psr to restore
+ */
+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 r16=IA64_PSR_BN
+ ;;
+ andcm r14=r14,r15 // clear various xT bits
+ ;;
+ or r14=r14,r16 // make sure BN=1
+ or ret0=ret0,r16 // make sure BN=1
+
+ br.cond.sptk.many ia64_change_mode
+
+END(ia64_physical_mode)
+
/**************************************************************************/
/*
diff --git a/sys/ia64/ia64/support.s b/sys/ia64/ia64/support.s
index d6c71d5..ad537e8 100644
--- a/sys/ia64/ia64/support.s
+++ b/sys/ia64/ia64/support.s
@@ -53,10 +53,77 @@
*/
#include <machine/asm.h>
+#include <machine/ia64_cpu.h>
#include <assym.s>
.text
+/*
+ * ia64_change_mode: change mode to/from physical mode
+ *
+ * Arguments:
+ * r14 psr for desired mode
+ */
+ENTRY(ia64_change_mode, 0)
+
+ rsm psr.i | psr.ic
+ mov ar.rsc=0 // turn off RSE
+ tbit.nz p6,p7=r14,17 // physical or virtual ?
+ ;;
+(p6) mov r15=7 // RR base for virtual addresses
+(p7) mov r15=0 // RR base for physical addresses
+ flushrs // no dirty registers please
+ srlz.i
+ ;;
+ mov r16=ar.bsp
+ mov r17=rp
+ mov r18=ar.rnat
+ ;;
+ dep r16=r15,r16,61,3 // new address of ar.bsp
+ dep r17=r15,r17,61,3 // new address of rp
+ ;;
+ mov ar.bspstore=r16
+ mov rp=r17
+ ;;
+1: mov r16=ip
+ mov ar.rnat=r18
+ mov cr.ipsr=r14 // psr for physical mode
+ ;;
+ add r16=2f-1b,r16 // address to rfi to
+ ;;
+ dep r16=r15,r16,61,3 // physical
+ ;;
+ mov cr.iip=r16 // setup for rfi
+ mov cr.ifs=r0
+ ;;
+ rfi
+
+2: br.ret.sptk.few rp // now in physical mode
+
+END(ia64_change_mode)
+
+/*
+ * ia64_physical_mode: change mode to physical mode
+ *
+ * Return:
+ * ret0 psr to restore
+ */
+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 r16=IA64_PSR_BN
+ ;;
+ andcm r14=r14,r15 // clear various xT bits
+ ;;
+ or r14=r14,r16 // make sure BN=1
+ or ret0=ret0,r16 // make sure BN=1
+
+ br.cond.sptk.many ia64_change_mode
+
+END(ia64_physical_mode)
+
/**************************************************************************/
/*
OpenPOWER on IntegriCloud