summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjake <jake@FreeBSD.org>2003-04-03 18:34:05 +0000
committerjake <jake@FreeBSD.org>2003-04-03 18:34:05 +0000
commit5b5fd1b87a6841f684fa3223c3301f77848da030 (patch)
treea42892bad75aba18a0045be33ee72d620b4550bd
parentd37e1467193889798aa297d78b20582b354c55d7 (diff)
downloadFreeBSD-src-5b5fd1b87a6841f684fa3223c3301f77848da030.zip
FreeBSD-src-5b5fd1b87a6841f684fa3223c3301f77848da030.tar.gz
Add support for saving and restoring kernel floating point state. The state
will be saved if we context switch as a result of an interrupt which occured while using the floating point registers in the kernel (which actually can't happen right now). This allows fp disabled traps in the kernel, which normally shouldn't happen, so make sure the trapping code is what we expect it is.
-rw-r--r--sys/sparc64/sparc64/exception.S32
-rw-r--r--sys/sparc64/sparc64/swtch.S14
2 files changed, 45 insertions, 1 deletions
diff --git a/sys/sparc64/sparc64/exception.S b/sys/sparc64/sparc64/exception.S
index cc0444b..97e0ba8 100644
--- a/sys/sparc64/sparc64/exception.S
+++ b/sys/sparc64/sparc64/exception.S
@@ -1219,6 +1219,36 @@ ENTRY(tl1_insn_exceptn_trap)
mov %g2, %o0
END(tl1_insn_exceptn_trap)
+ .macro tl1_fp_disabled
+ ba,a %xcc, tl1_fp_disabled_1
+ nop
+ .align 32
+ .endm
+
+ENTRY(tl1_fp_disabled_1)
+ rdpr %tpc, %g1
+ set fpu_fault_begin, %g2
+ sub %g1, %g2, %g1
+ cmp %g1, fpu_fault_size
+ bgeu,a,pn %xcc, 1f
+ nop
+
+ wr %g0, FPRS_FEF, %fprs
+ wr %g0, ASI_BLK_S, %asi
+ ldda [PCB_REG + PCB_KFP + (0 * 64)] %asi, %f0
+ ldda [PCB_REG + PCB_KFP + (1 * 64)] %asi, %f16
+ ldda [PCB_REG + PCB_KFP + (2 * 64)] %asi, %f32
+ ldda [PCB_REG + PCB_KFP + (3 * 64)] %asi, %f48
+ membar #Sync
+ retry
+
+1: tl1_split
+ clr %o1
+ set trap, %o2
+ ba %xcc, tl1_trap
+ mov T_FP_DISABLED | T_KERNEL, %o0
+END(tl1_fp_disabled_1)
+
.macro tl1_data_excptn
wrpr %g0, PSTATE_ALT, %pstate
b,a %xcc, tl1_data_excptn_trap
@@ -1913,7 +1943,7 @@ tl1_priv_opcode:
tl1_gen T_PRIVILEGED_OPCODE ! 0x211
tl1_reserved 14 ! 0x212-0x21f
tl1_fp_disabled:
- tl1_gen T_FP_DISABLED ! 0x220
+ tl1_fp_disabled ! 0x220
tl1_fp_ieee:
tl1_gen T_FP_EXCEPTION_IEEE_754 ! 0x221
tl1_fp_other:
diff --git a/sys/sparc64/sparc64/swtch.S b/sys/sparc64/sparc64/swtch.S
index 7cea5ee..222ef75 100644
--- a/sys/sparc64/sparc64/swtch.S
+++ b/sys/sparc64/sparc64/swtch.S
@@ -54,6 +54,20 @@ ENTRY(cpu_switch)
mov %i1, %i0
/*
+ * If the current thread was using floating point in the kernel, save
+ * its context. The userland floating point context has already been
+ * saved.
+ */
+ rd %fprs, %l2
+ andcc %l2, FPRS_FEF, %g0
+ bz,a,pt %xcc, 1f
+ nop
+ call savefpctx
+ add PCB_REG, PCB_KFP, %o0
+ ba,a %xcc, 2f
+ nop
+
+ /*
* If the current thread was using floating point in userland, save
* its context.
*/
OpenPOWER on IntegriCloud