aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-mips/mipsregs.h
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-04-18 19:49:42 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2006-04-18 19:49:42 -0700
commit038e5e2bf2819058fb1b4b52b583bef9ad063356 (patch)
tree3a152b455f845a25d0958af5b461b034c2d565fa /include/asm-mips/mipsregs.h
parentMerge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6 (diff)
parent[MAINTAINERS] The ham radio code now has website at http://www.linux-ax25.org. (diff)
downloadlinux-dev-038e5e2bf2819058fb1b4b52b583bef9ad063356.tar.xz
linux-dev-038e5e2bf2819058fb1b4b52b583bef9ad063356.zip
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus: (47 commits) [MAINTAINERS] The ham radio code now has website at http://www.linux-ax25.org. [MIPS] Use __ffs() instead of ffs() for waybit calculation. [MIPS] Fix Makefile bugs for MIPS32/MIPS64 R1 and R2. [MIPS] Handle IDE PIO cache aliases on SMP. [MIPS] Make mips_srs_init static. [MIPS] MIPS boards: Set HZ to 100. [MIPS] kgdb: Let gcc compute the array size itself. [MIPS] FPU affinity for MT ASE. [MIPS] MT: Improved multithreading support. [MIPS] kpsd and other AP/SP improvements. [MIPS] R2: Instruction hazard barrier. [MIPS] Fix genrtc compilation. [MIPS] R2: Implement shadow register allocation without spinlock. [MIPS] Fix VR41xx build errors. [MIPS] Fix tx49_blast_icache32_page_indexed. [MIPS] Enable SCHED_NO_NO_OMIT_FRAME_POINTER for MIPS. [MIPS] Use "R" constraint for cache_op. [MIPS] Rewrite all the assembler interrupt handlers to C. [MIPS] Fix the crime against humanity that mipsIRQ.S is. [MIPS] Fixup damage done by 22a9835c350782a5c3257343713932af3ac92ee0. ...
Diffstat (limited to 'include/asm-mips/mipsregs.h')
-rw-r--r--include/asm-mips/mipsregs.h136
1 files changed, 136 insertions, 0 deletions
diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h
index 035ba0a9b0df..a2ef579f6b1a 100644
--- a/include/asm-mips/mipsregs.h
+++ b/include/asm-mips/mipsregs.h
@@ -836,6 +836,9 @@ do { \
#define read_c0_cache() __read_32bit_c0_register($7, 0) /* TX39xx */
#define write_c0_cache(val) __write_32bit_c0_register($7, 0, val)
+#define read_c0_badvaddr() __read_ulong_c0_register($8, 0)
+#define write_c0_badvaddr(val) __write_ulong_c0_register($8, 0, val)
+
#define read_c0_count() __read_32bit_c0_register($9, 0)
#define write_c0_count(val) __write_32bit_c0_register($9, 0, val)
@@ -858,7 +861,19 @@ do { \
#define write_c0_compare3(val) __write_32bit_c0_register($11, 7, val)
#define read_c0_status() __read_32bit_c0_register($12, 0)
+#ifdef CONFIG_MIPS_MT_SMTC
+#define write_c0_status(val) \
+do { \
+ __write_32bit_c0_register($12, 0, val); \
+ __ehb(); \
+} while (0)
+#else
+/*
+ * Legacy non-SMTC code, which may be hazardous
+ * but which might not support EHB
+ */
#define write_c0_status(val) __write_32bit_c0_register($12, 0, val)
+#endif /* CONFIG_MIPS_MT_SMTC */
#define read_c0_cause() __read_32bit_c0_register($13, 0)
#define write_c0_cause(val) __write_32bit_c0_register($13, 0, val)
@@ -1001,6 +1016,9 @@ do { \
#define read_c0_taglo() __read_32bit_c0_register($28, 0)
#define write_c0_taglo(val) __write_32bit_c0_register($28, 0, val)
+#define read_c0_dtaglo() __read_32bit_c0_register($28, 2)
+#define write_c0_dtaglo(val) __write_32bit_c0_register($28, 2, val)
+
#define read_c0_taghi() __read_32bit_c0_register($29, 0)
#define write_c0_taghi(val) __write_32bit_c0_register($29, 0, val)
@@ -1354,15 +1372,119 @@ static inline void tlb_write_random(void)
/*
* Manipulate bits in a c0 register.
*/
+#ifndef CONFIG_MIPS_MT_SMTC
+/*
+ * SMTC Linux requires shutting-down microthread scheduling
+ * during CP0 register read-modify-write sequences.
+ */
+#define __BUILD_SET_C0(name) \
+static inline unsigned int \
+set_c0_##name(unsigned int set) \
+{ \
+ unsigned int res; \
+ \
+ res = read_c0_##name(); \
+ res |= set; \
+ write_c0_##name(res); \
+ \
+ return res; \
+} \
+ \
+static inline unsigned int \
+clear_c0_##name(unsigned int clear) \
+{ \
+ unsigned int res; \
+ \
+ res = read_c0_##name(); \
+ res &= ~clear; \
+ write_c0_##name(res); \
+ \
+ return res; \
+} \
+ \
+static inline unsigned int \
+change_c0_##name(unsigned int change, unsigned int new) \
+{ \
+ unsigned int res; \
+ \
+ res = read_c0_##name(); \
+ res &= ~change; \
+ res |= (new & change); \
+ write_c0_##name(res); \
+ \
+ return res; \
+}
+
+#else /* SMTC versions that manage MT scheduling */
+
+#include <asm/interrupt.h>
+
+/*
+ * This is a duplicate of dmt() in mipsmtregs.h to avoid problems with
+ * header file recursion.
+ */
+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;
+}
+
+#define __VPECONTROL_TE_SHIFT 15
+#define __VPECONTROL_TE (1UL << __VPECONTROL_TE_SHIFT)
+
+#define __EMT_ENABLE __VPECONTROL_TE
+
+static inline void __emt(unsigned int previous)
+{
+ if ((previous & __EMT_ENABLE))
+ __asm__ __volatile__(
+ " .set noreorder \n"
+ " .set mips32r2 \n"
+ " .word 0x41600be1 # emt \n"
+ " ehb \n"
+ " .set mips0 \n"
+ " .set reorder \n");
+}
+
+static inline void __ehb(void)
+{
+ __asm__ __volatile__(
+ " ehb \n");
+}
+
+/*
+ * Note that local_irq_save/restore affect TC-specific IXMT state,
+ * not Status.IE as in non-SMTC kernel.
+ */
+
#define __BUILD_SET_C0(name) \
static inline unsigned int \
set_c0_##name(unsigned int set) \
{ \
unsigned int res; \
+ unsigned int omt; \
+ unsigned int flags; \
\
+ local_irq_save(flags); \
+ omt = __dmt(); \
res = read_c0_##name(); \
res |= set; \
write_c0_##name(res); \
+ __emt(omt); \
+ local_irq_restore(flags); \
\
return res; \
} \
@@ -1371,10 +1493,16 @@ static inline unsigned int \
clear_c0_##name(unsigned int clear) \
{ \
unsigned int res; \
+ unsigned int omt; \
+ unsigned int flags; \
\
+ local_irq_save(flags); \
+ omt = __dmt(); \
res = read_c0_##name(); \
res &= ~clear; \
write_c0_##name(res); \
+ __emt(omt); \
+ local_irq_restore(flags); \
\
return res; \
} \
@@ -1383,14 +1511,22 @@ static inline unsigned int \
change_c0_##name(unsigned int change, unsigned int new) \
{ \
unsigned int res; \
+ unsigned int omt; \
+ unsigned int flags; \
\
+ local_irq_save(flags); \
+ \
+ omt = __dmt(); \
res = read_c0_##name(); \
res &= ~change; \
res |= (new & change); \
write_c0_##name(res); \
+ __emt(omt); \
+ local_irq_restore(flags); \
\
return res; \
}
+#endif
__BUILD_SET_C0(status)
__BUILD_SET_C0(cause)