summaryrefslogtreecommitdiffstats
path: root/sys/mips/mips/swtch.S
diff options
context:
space:
mode:
authorgonzo <gonzo@FreeBSD.org>2012-01-06 01:23:26 +0000
committergonzo <gonzo@FreeBSD.org>2012-01-06 01:23:26 +0000
commit3d21003ba1534507e8bfc041be782c59b31ca15e (patch)
tree45dde1707c19803c1cf01dddbc0dea96b24a815c /sys/mips/mips/swtch.S
parent0c24320ceb635484927f19b79b413a85e040aa15 (diff)
downloadFreeBSD-src-3d21003ba1534507e8bfc041be782c59b31ca15e.zip
FreeBSD-src-3d21003ba1534507e8bfc041be782c59b31ca15e.tar.gz
- Add better COP2 (crypto coprocessor) context handler for Octeon. Keep
COP2 disabled and lazily allocate COP2 context structure in exception handler. Keep kernel and userland contexts separated.
Diffstat (limited to 'sys/mips/mips/swtch.S')
-rw-r--r--sys/mips/mips/swtch.S55
1 files changed, 55 insertions, 0 deletions
diff --git a/sys/mips/mips/swtch.S b/sys/mips/mips/swtch.S
index 699c206..8b285dd 100644
--- a/sys/mips/mips/swtch.S
+++ b/sys/mips/mips/swtch.S
@@ -250,6 +250,61 @@ NON_LEAF(cpu_switch, CALLFRAME_SIZ, ra)
getpc:
SAVE_U_PCB_CONTEXT(ra, PREG_PC, a0) # save return address
+#ifdef CPU_CNMIPS
+
+ lw t2, TD_MDFLAGS(a3) # get md_flags
+ and t1, t2, MDTD_COP2USED
+ beqz t1, cop2_untouched
+ nop
+
+ /* Clear cop2used flag */
+ and t2, t2, ~MDTD_COP2USED
+ sw t2, TD_MDFLAGS(a3)
+
+ and t2, t0, ~MIPS_SR_COP_2_BIT # clear COP_2 enable bit
+ SAVE_U_PCB_CONTEXT(t2, PREG_SR, a0) # save status register
+
+ RESTORE_U_PCB_REG(t0, PS, a0) # get CPU status register
+ and t2, t0, ~MIPS_SR_COP_2_BIT # clear COP_2 enable bit
+ SAVE_U_PCB_REG(t2, PS, a0) # save stratus register
+
+ /* preserve a0..a3 */
+ move s0, a0
+ move s1, a1
+ move s2, a2
+ move s3, a3
+
+ /* does kernel own COP2 context? */
+ lw t1, TD_COP2OWNER(a3) # get md_cop2owner
+ beqz t1, userland_cop2 # 0 - it's userland context
+ nop
+
+ PTR_L a0, TD_COP2(a3)
+ beqz a0, no_cop2_context
+ nop
+
+ j do_cop2_save
+ nop
+
+userland_cop2:
+
+ PTR_L a0, TD_UCOP2(a3)
+ beqz a0, no_cop2_context
+ nop
+
+do_cop2_save:
+ jal octeon_cop2_save
+ nop
+
+no_cop2_context:
+ move a3, s3
+ move a2, s2
+ move a1, s1
+ move a0, s0
+
+cop2_untouched:
+#endif
+
PTR_S a2, TD_LOCK(a3) # Switchout td_lock
mips_sw1:
OpenPOWER on IntegriCloud