|
@@ -210,3 +210,199 @@ static inline void __raw_evpe(void)
|
|
|
|
|
|
/* Enable virtual processor execution if previous suggested it should be.
|
|
|
EVPE_ENABLE to force */
|
|
|
+
|
|
|
+#define EVPE_ENABLE MVPCONTROL_EVP
|
|
|
+
|
|
|
+static inline void evpe(int previous)
|
|
|
+{
|
|
|
+ if ((previous & MVPCONTROL_EVP))
|
|
|
+ __raw_evpe();
|
|
|
+}
|
|
|
+
|
|
|
+static inline unsigned int dmt(void)
|
|
|
+{
|
|
|
+ int res;
|
|
|
+
|
|
|
+ __asm__ __volatile__(
|
|
|
+ " .set push \n"
|
|
|
+ " .set mips32r2 \n"
|
|
|
+ " .set noat \n"
|
|
|
+ " .word 0x41610BC1 # dmt $1 \n"
|
|
|
+ " ehb \n"
|
|
|
+ " move %0, $1 \n"
|
|
|
+ " .set pop \n"
|
|
|
+ : "=r" (res));
|
|
|
+
|
|
|
+ instruction_hazard();
|
|
|
+
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+static inline void __raw_emt(void)
|
|
|
+{
|
|
|
+ __asm__ __volatile__(
|
|
|
+ " .set noreorder \n"
|
|
|
+ " .set mips32r2 \n"
|
|
|
+ " .word 0x41600be1 # emt \n"
|
|
|
+ " ehb \n"
|
|
|
+ " .set mips0 \n"
|
|
|
+ " .set reorder");
|
|
|
+}
|
|
|
+
|
|
|
+/* enable multi-threaded execution if previous suggested it should be.
|
|
|
+ EMT_ENABLE to force */
|
|
|
+
|
|
|
+#define EMT_ENABLE VPECONTROL_TE
|
|
|
+
|
|
|
+static inline void emt(int previous)
|
|
|
+{
|
|
|
+ if ((previous & EMT_ENABLE))
|
|
|
+ __raw_emt();
|
|
|
+}
|
|
|
+
|
|
|
+static inline void ehb(void)
|
|
|
+{
|
|
|
+ __asm__ __volatile__(
|
|
|
+ " .set mips32r2 \n"
|
|
|
+ " ehb \n"
|
|
|
+ " .set mips0 \n");
|
|
|
+}
|
|
|
+
|
|
|
+#define mftc0(rt,sel) \
|
|
|
+({ \
|
|
|
+ unsigned long __res; \
|
|
|
+ \
|
|
|
+ __asm__ __volatile__( \
|
|
|
+ " .set push \n" \
|
|
|
+ " .set mips32r2 \n" \
|
|
|
+ " .set noat \n" \
|
|
|
+ " # mftc0 $1, $" #rt ", " #sel " \n" \
|
|
|
+ " .word 0x41000800 | (" #rt " << 16) | " #sel " \n" \
|
|
|
+ " move %0, $1 \n" \
|
|
|
+ " .set pop \n" \
|
|
|
+ : "=r" (__res)); \
|
|
|
+ \
|
|
|
+ __res; \
|
|
|
+})
|
|
|
+
|
|
|
+#define mftgpr(rt) \
|
|
|
+({ \
|
|
|
+ unsigned long __res; \
|
|
|
+ \
|
|
|
+ __asm__ __volatile__( \
|
|
|
+ " .set push \n" \
|
|
|
+ " .set noat \n" \
|
|
|
+ " .set mips32r2 \n" \
|
|
|
+ " # mftgpr $1," #rt " \n" \
|
|
|
+ " .word 0x41000820 | (" #rt " << 16) \n" \
|
|
|
+ " move %0, $1 \n" \
|
|
|
+ " .set pop \n" \
|
|
|
+ : "=r" (__res)); \
|
|
|
+ \
|
|
|
+ __res; \
|
|
|
+})
|
|
|
+
|
|
|
+#define mftr(rt, u, sel) \
|
|
|
+({ \
|
|
|
+ unsigned long __res; \
|
|
|
+ \
|
|
|
+ __asm__ __volatile__( \
|
|
|
+ " mftr %0, " #rt ", " #u ", " #sel " \n" \
|
|
|
+ : "=r" (__res)); \
|
|
|
+ \
|
|
|
+ __res; \
|
|
|
+})
|
|
|
+
|
|
|
+#define mttgpr(rd,v) \
|
|
|
+do { \
|
|
|
+ __asm__ __volatile__( \
|
|
|
+ " .set push \n" \
|
|
|
+ " .set mips32r2 \n" \
|
|
|
+ " .set noat \n" \
|
|
|
+ " move $1, %0 \n" \
|
|
|
+ " # mttgpr $1, " #rd " \n" \
|
|
|
+ " .word 0x41810020 | (" #rd " << 11) \n" \
|
|
|
+ " .set pop \n" \
|
|
|
+ : : "r" (v)); \
|
|
|
+} while (0)
|
|
|
+
|
|
|
+#define mttc0(rd, sel, v) \
|
|
|
+({ \
|
|
|
+ __asm__ __volatile__( \
|
|
|
+ " .set push \n" \
|
|
|
+ " .set mips32r2 \n" \
|
|
|
+ " .set noat \n" \
|
|
|
+ " move $1, %0 \n" \
|
|
|
+ " # mttc0 %0," #rd ", " #sel " \n" \
|
|
|
+ " .word 0x41810000 | (" #rd " << 11) | " #sel " \n" \
|
|
|
+ " .set pop \n" \
|
|
|
+ : \
|
|
|
+ : "r" (v)); \
|
|
|
+})
|
|
|
+
|
|
|
+
|
|
|
+#define mttr(rd, u, sel, v) \
|
|
|
+({ \
|
|
|
+ __asm__ __volatile__( \
|
|
|
+ "mttr %0," #rd ", " #u ", " #sel \
|
|
|
+ : : "r" (v)); \
|
|
|
+})
|
|
|
+
|
|
|
+
|
|
|
+#define settc(tc) \
|
|
|
+do { \
|
|
|
+ write_c0_vpecontrol((read_c0_vpecontrol()&~VPECONTROL_TARGTC) | (tc)); \
|
|
|
+ ehb(); \
|
|
|
+} while (0)
|
|
|
+
|
|
|
+
|
|
|
+/* you *must* set the target tc (settc) before trying to use these */
|
|
|
+#define read_vpe_c0_vpecontrol() mftc0(1, 1)
|
|
|
+#define write_vpe_c0_vpecontrol(val) mttc0(1, 1, val)
|
|
|
+#define read_vpe_c0_vpeconf0() mftc0(1, 2)
|
|
|
+#define write_vpe_c0_vpeconf0(val) mttc0(1, 2, val)
|
|
|
+#define read_vpe_c0_vpeconf1() mftc0(1, 3)
|
|
|
+#define write_vpe_c0_vpeconf1(val) mttc0(1, 3, val)
|
|
|
+#define read_vpe_c0_count() mftc0(9, 0)
|
|
|
+#define write_vpe_c0_count(val) mttc0(9, 0, val)
|
|
|
+#define read_vpe_c0_status() mftc0(12, 0)
|
|
|
+#define write_vpe_c0_status(val) mttc0(12, 0, val)
|
|
|
+#define read_vpe_c0_cause() mftc0(13, 0)
|
|
|
+#define write_vpe_c0_cause(val) mttc0(13, 0, val)
|
|
|
+#define read_vpe_c0_config() mftc0(16, 0)
|
|
|
+#define write_vpe_c0_config(val) mttc0(16, 0, val)
|
|
|
+#define read_vpe_c0_config1() mftc0(16, 1)
|
|
|
+#define write_vpe_c0_config1(val) mttc0(16, 1, val)
|
|
|
+#define read_vpe_c0_config7() mftc0(16, 7)
|
|
|
+#define write_vpe_c0_config7(val) mttc0(16, 7, val)
|
|
|
+#define read_vpe_c0_ebase() mftc0(15, 1)
|
|
|
+#define write_vpe_c0_ebase(val) mttc0(15, 1, val)
|
|
|
+#define write_vpe_c0_compare(val) mttc0(11, 0, val)
|
|
|
+#define read_vpe_c0_badvaddr() mftc0(8, 0)
|
|
|
+#define read_vpe_c0_epc() mftc0(14, 0)
|
|
|
+#define write_vpe_c0_epc(val) mttc0(14, 0, val)
|
|
|
+
|
|
|
+
|
|
|
+/* TC */
|
|
|
+#define read_tc_c0_tcstatus() mftc0(2, 1)
|
|
|
+#define write_tc_c0_tcstatus(val) mttc0(2, 1, val)
|
|
|
+#define read_tc_c0_tcbind() mftc0(2, 2)
|
|
|
+#define write_tc_c0_tcbind(val) mttc0(2, 2, val)
|
|
|
+#define read_tc_c0_tcrestart() mftc0(2, 3)
|
|
|
+#define write_tc_c0_tcrestart(val) mttc0(2, 3, val)
|
|
|
+#define read_tc_c0_tchalt() mftc0(2, 4)
|
|
|
+#define write_tc_c0_tchalt(val) mttc0(2, 4, val)
|
|
|
+#define read_tc_c0_tccontext() mftc0(2, 5)
|
|
|
+#define write_tc_c0_tccontext(val) mttc0(2, 5, val)
|
|
|
+
|
|
|
+/* GPR */
|
|
|
+#define read_tc_gpr_sp() mftgpr(29)
|
|
|
+#define write_tc_gpr_sp(val) mttgpr(29, val)
|
|
|
+#define read_tc_gpr_gp() mftgpr(28)
|
|
|
+#define write_tc_gpr_gp(val) mttgpr(28, val)
|
|
|
+
|
|
|
+__BUILD_SET_C0(mvpcontrol)
|
|
|
+
|
|
|
+#endif /* Not __ASSEMBLY__ */
|
|
|
+
|
|
|
+#endif
|