patch-2.4.22 linux-2.4.22/include/asm-mips/mipsregs.h

Next file: linux-2.4.22/include/asm-mips/mmu.h
Previous file: linux-2.4.22/include/asm-mips/mips32_cache.h
Back to the patch index
Back to the overall index

diff -urN linux-2.4.21/include/asm-mips/mipsregs.h linux-2.4.22/include/asm-mips/mipsregs.h
@@ -8,6 +8,7 @@
  * Modified for further R[236]000 support by Paul M. Antoine, 1996.
  * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
  * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 2003  Maciej W. Rozycki
  */
 #ifndef _ASM_MIPSREGS_H
 #define _ASM_MIPSREGS_H
@@ -27,6 +28,15 @@
 #endif
 
 /*
+ *  Configure language
+ */
+#ifdef __ASSEMBLY__
+#define _ULCAST_
+#else
+#define _ULCAST_ (unsigned long)
+#endif
+
+/*
  * Coprocessor 0 register names
  */
 #define CP0_INDEX $0
@@ -118,7 +128,7 @@
  * E the exception enable
  * S the sticky/flag bit
 */
-#define FPU_CSR_ALL_X 0x0003f000
+#define FPU_CSR_ALL_X   0x0003f000
 #define FPU_CSR_UNI_X   0x00020000
 #define FPU_CSR_INV_X   0x00010000
 #define FPU_CSR_DIV_X   0x00008000
@@ -190,26 +200,26 @@
 /*
  * R4x00 interrupt enable / cause bits
  */
-#define IE_SW0          (1<< 8)
-#define IE_SW1          (1<< 9)
-#define IE_IRQ0         (1<<10)
-#define IE_IRQ1         (1<<11)
-#define IE_IRQ2         (1<<12)
-#define IE_IRQ3         (1<<13)
-#define IE_IRQ4         (1<<14)
-#define IE_IRQ5         (1<<15)
+#define IE_SW0          (_ULCAST_(1) <<  8)
+#define IE_SW1          (_ULCAST_(1) <<  9)
+#define IE_IRQ0         (_ULCAST_(1) << 10)
+#define IE_IRQ1         (_ULCAST_(1) << 11)
+#define IE_IRQ2         (_ULCAST_(1) << 12)
+#define IE_IRQ3         (_ULCAST_(1) << 13)
+#define IE_IRQ4         (_ULCAST_(1) << 14)
+#define IE_IRQ5         (_ULCAST_(1) << 15)
 
 /*
  * R4x00 interrupt cause bits
  */
-#define C_SW0           (1<< 8)
-#define C_SW1           (1<< 9)
-#define C_IRQ0          (1<<10)
-#define C_IRQ1          (1<<11)
-#define C_IRQ2          (1<<12)
-#define C_IRQ3          (1<<13)
-#define C_IRQ4          (1<<14)
-#define C_IRQ5          (1<<15)
+#define C_SW0           (_ULCAST_(1) <<  8)
+#define C_SW1           (_ULCAST_(1) <<  9)
+#define C_IRQ0          (_ULCAST_(1) << 10)
+#define C_IRQ1          (_ULCAST_(1) << 11)
+#define C_IRQ2          (_ULCAST_(1) << 12)
+#define C_IRQ3          (_ULCAST_(1) << 13)
+#define C_IRQ4          (_ULCAST_(1) << 14)
+#define C_IRQ5          (_ULCAST_(1) << 15)
 
 /*
  * Bitfields in the R4xx0 cp0 status register
@@ -244,9 +254,9 @@
 /*
  * Bits specific to the R4640/R4650
  */
-#define ST0_UM                 (1   <<  4)
-#define ST0_IL                 (1   << 23)
-#define ST0_DL                 (1   << 24)
+#define ST0_UM			(_ULCAST_(1) <<  4)
+#define ST0_IL			(_ULCAST_(1) << 23)
+#define ST0_DL			(_ULCAST_(1) << 24)
 
 /*
  * Bitfields in the TX39 family CP0 Configuration Register 3
@@ -286,37 +296,37 @@
  */
 #define ST0_IM			0x0000ff00
 #define  STATUSB_IP0		8
-#define  STATUSF_IP0		(1   <<  8)
+#define  STATUSF_IP0		(_ULCAST_(1) <<  8)
 #define  STATUSB_IP1		9
-#define  STATUSF_IP1		(1   <<  9)
+#define  STATUSF_IP1		(_ULCAST_(1) <<  9)
 #define  STATUSB_IP2		10
-#define  STATUSF_IP2		(1   << 10)
+#define  STATUSF_IP2		(_ULCAST_(1) << 10)
 #define  STATUSB_IP3		11
-#define  STATUSF_IP3		(1   << 11)
+#define  STATUSF_IP3		(_ULCAST_(1) << 11)
 #define  STATUSB_IP4		12
-#define  STATUSF_IP4		(1   << 12)
+#define  STATUSF_IP4		(_ULCAST_(1) << 12)
 #define  STATUSB_IP5		13
-#define  STATUSF_IP5		(1   << 13)
+#define  STATUSF_IP5		(_ULCAST_(1) << 13)
 #define  STATUSB_IP6		14
-#define  STATUSF_IP6		(1   << 14)
+#define  STATUSF_IP6		(_ULCAST_(1) << 14)
 #define  STATUSB_IP7		15
-#define  STATUSF_IP7		(1   << 15)
+#define  STATUSF_IP7		(_ULCAST_(1) << 15)
 #define  STATUSB_IP8		0
-#define  STATUSF_IP8		(1   << 0)
+#define  STATUSF_IP8		(_ULCAST_(1) <<  0)
 #define  STATUSB_IP9		1
-#define  STATUSF_IP9		(1   << 1)
+#define  STATUSF_IP9		(_ULCAST_(1) <<  1)
 #define  STATUSB_IP10		2
-#define  STATUSF_IP10		(1   << 2)
+#define  STATUSF_IP10		(_ULCAST_(1) <<  2)
 #define  STATUSB_IP11		3
-#define  STATUSF_IP11		(1   << 3)
+#define  STATUSF_IP11		(_ULCAST_(1) <<  3)
 #define  STATUSB_IP12		4
-#define  STATUSF_IP12		(1   << 4)
+#define  STATUSF_IP12		(_ULCAST_(1) <<  4)
 #define  STATUSB_IP13		5
-#define  STATUSF_IP13		(1   << 5)
+#define  STATUSF_IP13		(_ULCAST_(1) <<  5)
 #define  STATUSB_IP14		6
-#define  STATUSF_IP14		(1   << 6)
+#define  STATUSF_IP14		(_ULCAST_(1) <<  6)
 #define  STATUSB_IP15		7
-#define  STATUSF_IP15		(1   << 7)
+#define  STATUSF_IP15		(_ULCAST_(1) <<  7)
 #define ST0_CH			0x00040000
 #define ST0_SR			0x00100000
 #define ST0_TS			0x00200000
@@ -336,35 +346,36 @@
  * Refer to your MIPS R4xx0 manual, chapter 5 for explanation.
  */
 #define  CAUSEB_EXCCODE		2
-#define  CAUSEF_EXCCODE		(31  <<  2)
+#define  CAUSEF_EXCCODE		(_ULCAST_(31)  <<  2)
 #define  CAUSEB_IP		8
-#define  CAUSEF_IP		(255 <<  8)
+#define  CAUSEF_IP		(_ULCAST_(255) <<  8)
 #define  CAUSEB_IP0		8
-#define  CAUSEF_IP0		(1   <<  8)
+#define  CAUSEF_IP0		(_ULCAST_(1)   <<  8)
 #define  CAUSEB_IP1		9
-#define  CAUSEF_IP1		(1   <<  9)
+#define  CAUSEF_IP1		(_ULCAST_(1)   <<  9)
 #define  CAUSEB_IP2		10
-#define  CAUSEF_IP2		(1   << 10)
+#define  CAUSEF_IP2		(_ULCAST_(1)   << 10)
 #define  CAUSEB_IP3		11
-#define  CAUSEF_IP3		(1   << 11)
+#define  CAUSEF_IP3		(_ULCAST_(1)   << 11)
 #define  CAUSEB_IP4		12
-#define  CAUSEF_IP4		(1   << 12)
+#define  CAUSEF_IP4		(_ULCAST_(1)   << 12)
 #define  CAUSEB_IP5		13
-#define  CAUSEF_IP5		(1   << 13)
+#define  CAUSEF_IP5		(_ULCAST_(1)   << 13)
 #define  CAUSEB_IP6		14
-#define  CAUSEF_IP6		(1   << 14)
+#define  CAUSEF_IP6		(_ULCAST_(1)   << 14)
 #define  CAUSEB_IP7		15
-#define  CAUSEF_IP7		(1   << 15)
+#define  CAUSEF_IP7		(_ULCAST_(1)   << 15)
 #define  CAUSEB_IV		23
-#define  CAUSEF_IV		(1   << 23)
+#define  CAUSEF_IV		(_ULCAST_(1)   << 23)
 #define  CAUSEB_CE		28
-#define  CAUSEF_CE		(3   << 28)
+#define  CAUSEF_CE		(_ULCAST_(3)   << 28)
 #define  CAUSEB_BD		31
-#define  CAUSEF_BD		(1   << 31)
+#define  CAUSEF_BD		(_ULCAST_(1)   << 31)
 
 /*
- * Bits in the coprozessor 0 config register.
+ * Bits in the coprocessor 0 config register.
  */
+/* Generic bits.  */
 #define CONF_CM_CACHABLE_NO_WA		0
 #define CONF_CM_CACHABLE_WA		1
 #define CONF_CM_UNCACHED		2
@@ -374,21 +385,72 @@
 #define CONF_CM_CACHABLE_CUW		6
 #define CONF_CM_CACHABLE_ACCELERATED	7
 #define CONF_CM_CMASK			7
-#define CONF_CU				(1 <<  3)
-#define CONF_DB				(1 <<  4)
-#define CONF_IB				(1 <<  5)
-#define CONF_SE 			(1 << 12)
-#define CONF_SC				(1 << 17)
-#define CONF_AC                         (1 << 23)
-#define CONF_HALT                       (1 << 25)
+#define CONF_BE			(_ULCAST_(1) << 15)
 
-/*
- * Bits in the TX49 coprozessor 0 config register.
- */
-#define TX49_CONF_DC			(1 << 16)
-#define TX49_CONF_IC			(1 << 17)  /* conflict with CONF_SC */
-#define TX49_CONF_HALT			(1 << 18)
-#define TX49_CONF_CWFON			(1 << 27)
+/* Bits common to various processors.  */
+#define CONF_CU			(_ULCAST_(1) <<  3)
+#define CONF_DB			(_ULCAST_(1) <<  4)
+#define CONF_IB			(_ULCAST_(1) <<  5)
+#define CONF_DC			(_ULCAST_(7) <<  6)
+#define CONF_IC			(_ULCAST_(7) <<  9)
+#define CONF_EB			(_ULCAST_(1) << 13)
+#define CONF_EM			(_ULCAST_(1) << 14)
+#define CONF_SM			(_ULCAST_(1) << 16)
+#define CONF_SC			(_ULCAST_(1) << 17)
+#define CONF_EW			(_ULCAST_(3) << 18)
+#define CONF_EP			(_ULCAST_(15)<< 24)
+#define CONF_EC			(_ULCAST_(7) << 28)
+#define CONF_CM			(_ULCAST_(1) << 31)
+
+/* Bits specific to the R4xx0.  */
+#define R4K_CONF_SW		(_ULCAST_(1) << 20)
+#define R4K_CONF_SS		(_ULCAST_(1) << 21)
+#define R4K_CONF_SB		(_ULCAST_(3) << 22)
+
+/* Bits specific to the R5000.  */
+#define R5K_CONF_SE		(_ULCAST_(1) << 12)
+#define R5K_CONF_SS		(_ULCAST_(3) << 20)
+
+/* Bits specific to the R10000.  */
+#define R10K_CONF_DN		(_ULCAST_(3) <<  3)
+#define R10K_CONF_CT		(_ULCAST_(1) <<  5)
+#define R10K_CONF_PE		(_ULCAST_(1) <<  6)
+#define R10K_CONF_PM		(_ULCAST_(3) <<  7)
+#define R10K_CONF_EC		(_ULCAST_(15)<<  9)
+#define R10K_CONF_SB		(_ULCAST_(1) << 13)
+#define R10K_CONF_SK		(_ULCAST_(1) << 14)
+#define R10K_CONF_SS		(_ULCAST_(7) << 16)
+#define R10K_CONF_SC		(_ULCAST_(7) << 19)
+#define R10K_CONF_DC		(_ULCAST_(7) << 26)
+#define R10K_CONF_IC		(_ULCAST_(7) << 29)
+
+/* Bits specific to the VR41xx.  */
+#define VR41_CONF_CS		(_ULCAST_(1) << 12)
+#define VR41_CONF_M16		(_ULCAST_(1) << 20)
+#define VR41_CONF_AD		(_ULCAST_(1) << 23)
+
+/* Bits specific to the R30xx.  */
+#define R30XX_CONF_FDM		(_ULCAST_(1) << 19)
+#define R30XX_CONF_REV		(_ULCAST_(1) << 22)
+#define R30XX_CONF_AC		(_ULCAST_(1) << 23)
+#define R30XX_CONF_RF		(_ULCAST_(1) << 24)
+#define R30XX_CONF_HALT		(_ULCAST_(1) << 25)
+#define R30XX_CONF_FPINT	(_ULCAST_(7) << 26)
+#define R30XX_CONF_DBR		(_ULCAST_(1) << 29)
+#define R30XX_CONF_SB		(_ULCAST_(1) << 30)
+#define R30XX_CONF_LOCK		(_ULCAST_(1) << 31)
+
+/* Bits specific to the TX49.  */
+#define TX49_CONF_DC		(_ULCAST_(1) << 16)
+#define TX49_CONF_IC		(_ULCAST_(1) << 17)  /* conflict with CONF_SC */
+#define TX49_CONF_HALT		(_ULCAST_(1) << 18)
+#define TX49_CONF_CWFON		(_ULCAST_(1) << 27)
+
+/* Bits specific to the MIPS32/64 PRA.  */
+#define MIPS_CONF_MT		(_ULCAST_(7) <<  7)
+#define MIPS_CONF_AR		(_ULCAST_(7) << 10)
+#define MIPS_CONF_AT		(_ULCAST_(3) << 13)
+#define MIPS_CONF_M		(_ULCAST_(1) << 31)
 
 /*
  * R10000 performance counter definitions.
@@ -478,553 +540,361 @@
 /*
  * Macros to access the system control coprocessor
  */
-#define read_32bit_cp0_register(source)                         \
-({ int __res;                                                   \
-        __asm__ __volatile__(                                   \
-	".set\tpush\n\t"					\
-	".set\treorder\n\t"					\
-        "mfc0\t%0,"STR(source)"\n\t"                            \
-	".set\tpop"						\
-        : "=r" (__res));                                        \
-        __res;})
-
-#define read_32bit_cp0_set1_register(source)                    \
-({ int __res;                                                   \
-        __asm__ __volatile__(                                   \
-	".set\tpush\n\t"					\
-	".set\treorder\n\t"					\
-        "cfc0\t%0,"STR(source)"\n\t"                            \
-	".set\tpop"						\
-        : "=r" (__res));                                        \
-        __res;})
-
-/*
- * For now use this only with interrupts disabled!
- */
-#define read_64bit_cp0_register(source)                         \
-({ unsigned long __res;                                         \
-        __asm__ __volatile__(                                   \
-        ".set\tmips3\n\t"                                       \
-        "dmfc0\t%0,"STR(source)"\n\t"                           \
-        ".set\tmips0"                                           \
-        : "=r" (__res));                                        \
-        __res;})
-
-#define write_32bit_cp0_register(register,value)                \
-        __asm__ __volatile__(                                   \
-        "mtc0\t%0,"STR(register)"\n\t"				\
-	"nop"							\
-        : : "r" (value));
-
-#define write_32bit_cp0_set1_register(register,value)           \
-        __asm__ __volatile__(                                   \
-        "ctc0\t%0,"STR(register)"\n\t"				\
-	"nop"							\
-        : : "r" (value));
-
-#define write_64bit_cp0_register(register,value)                \
-        __asm__ __volatile__(                                   \
-        ".set\tmips3\n\t"                                       \
-        "dmtc0\t%0,"STR(register)"\n\t"                         \
-        ".set\tmips0"                                           \
-        : : "r" (value))
-
-/*
- * This should be changed when we get a compiler that support the MIPS32 ISA.
- */
-#define read_mips32_cp0_config1()                               \
-({ int __res;                                                   \
-        __asm__ __volatile__(                                   \
-	".set\tnoreorder\n\t"                                   \
-	".set\tnoat\n\t"                                        \
-	"#.set\tmips64\n\t"					\
-	"#mfc0\t$1, $16, 1\n\t"					\
-	"#.set\tmips0\n\t"					\
-     	".word\t0x40018001\n\t"                                 \
-	"move\t%0,$1\n\t"                                       \
-	".set\tat\n\t"                                          \
-	".set\treorder"                                         \
-	:"=r" (__res));                                         \
-        __res;})
-
-/*
- * Macros to access the floating point coprocessor control registers
- */
-#define read_32bit_cp1_register(source)                         \
-({ int __res;                                                   \
-        __asm__ __volatile__(                                   \
-	".set\tpush\n\t"					\
-	".set\treorder\n\t"					\
-        "cfc1\t%0,"STR(source)"\n\t"                            \
-	".set\tpop"						\
-        : "=r" (__res));                                        \
-        __res;})
-
-/* TLB operations. */
-static inline void tlb_probe(void)
-{
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"tlbp\n\t"
-		".set pop");
-}
-
-static inline void tlb_read(void)
-{
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"tlbr\n\t"
-		".set pop");
-}
-
-static inline void tlb_write_indexed(void)
-{
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"tlbwi\n\t"
-		".set pop");
-}
-
-static inline void tlb_write_random(void)
-{
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"tlbwr\n\t"
-		".set pop");
-}
 
-/* Dealing with various CP0 mmu/cache related registers. */
+#define __read_32bit_c0_register(source, sel)				\
+({ int __res;								\
+	if (sel == 0)							\
+		__asm__ __volatile__(					\
+			"mfc0\t%0, " #source "\n\t"			\
+			: "=r" (__res));				\
+	else								\
+		__asm__ __volatile__(					\
+			".set\tmips32\n\t"				\
+			"mfc0\t%0, " #source ", " #sel "\n\t"		\
+			".set\tmips0\n\t"				\
+			: "=r" (__res));				\
+	__res;								\
+})
+
+#define __read_64bit_c0_register(source, sel)				\
+({ unsigned long __res;							\
+	if (sel == 0)							\
+		__asm__ __volatile__(					\
+			".set\tmips3\n\t"				\
+			"dmfc0\t%0, " #source "\n\t"			\
+			".set\tmips0"					\
+			: "=r" (__res));				\
+	else								\
+		__asm__ __volatile__(					\
+			".set\tmips64\n\t"				\
+			"dmfc0\t%0, " #source ", " #sel "\n\t"		\
+			".set\tmips0"					\
+			: "=r" (__res));				\
+	__res;								\
+})
 
+#define __write_32bit_c0_register(register, sel, value)			\
+do {									\
+	if (sel == 0)							\
+		__asm__ __volatile__(					\
+			"mtc0\t%z0, " #register "\n\t"			\
+			: : "Jr" (value));				\
+	else								\
+		__asm__ __volatile__(					\
+			".set\tmips32\n\t"				\
+			"mtc0\t%z0, " #register ", " #sel "\n\t"	\
+			".set\tmips0"					\
+			: : "Jr" (value));				\
+} while (0)
 
-static inline unsigned long get_pagemask(void)
-{
-	unsigned long val;
-
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mfc0 %0, $5\n\t"
-		".set pop"
-		: "=r" (val));
-	return val;
-}
-
-static inline void set_pagemask(unsigned long val)
-{
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mtc0 %z0, $5\n\t"
-		".set pop"
-		: : "Jr" (val));
-}
+#define __write_64bit_c0_register(register, sel, value)			\
+do {									\
+	if (sel == 0)							\
+		__asm__ __volatile__(					\
+			".set\tmips3\n\t"				\
+			"dmtc0\t%z0, " #register "\n\t"			\
+			".set\tmips0"					\
+			: : "Jr" (value));				\
+	else								\
+		__asm__ __volatile__(					\
+			".set\tmips64\n\t"				\
+			"dmtc0\t%z0, " #register ", " #sel "\n\t"	\
+			".set\tmips0"					\
+			: : "Jr" (value));				\
+} while (0)
 
-#if defined(CONFIG_64BIT_PHYS_ADDR) && !defined(CONFIG_CPU_MIPS32)
+#define __read_ulong_c0_register(reg, sel)				\
+	((sizeof(unsigned long) == 4) ?					\
+	__read_32bit_c0_register(reg, sel) :				\
+	__read_64bit_c0_register(reg, sel))
 
-#include <asm/system.h>
+#define __write_ulong_c0_register(reg, sel, val)			\
+do {									\
+	if (sizeof(unsigned long) == 4)					\
+		__write_32bit_c0_register(reg, sel, val);		\
+	else								\
+		__write_64bit_c0_register(reg, sel, val);		\
+} while (0)
 
 /*
  * These versions are only needed for systems with more than 38 bits of
- * physical address space.
+ * physical address space running the 32-bit kernel.  That's none atm :-)
  */
-static inline void set_entrylo0(unsigned long long val)
-{
-	unsigned long flags;
-
-	__save_and_cli(flags);
-	__asm__ __volatile__(
-		".set\tmips3\n\t"
-		"dsll\t%L0, %L0, 32\n\t"
-		"dsrl\t%L0, %L0, 32\n\t"
-		"dsll\t%M0, %M0, 32\n\t"
-		"or\t%L0, %L0, %M0\n\t"
-		"dmtc0\t%L0, $2\n\t"
-		".set\tmips0"
-		: : "r" (val));
-	__restore_flags(flags);
-}
-
-static inline void set_entrylo1(unsigned long long val)
-{
-	unsigned long flags;
-
-	__save_and_cli(flags);
-	__asm__ __volatile__(
-		".set\tmips3\n\t"
-		"dsll\t%L0, %L0, 32\n\t"
-		"dsrl\t%L0, %L0, 32\n\t"
-		"dsll\t%M0, %M0, 32\n\t"
-		"or\t%L0, %L0, %M0\n\t"
-		"dmtc0\t%L0, $3\n\t"
-		".set\tmips0"
-		: : "r" (val));
-	__restore_flags(flags);
-}
-
-static inline unsigned long long get_entrylo0(void)
-{
-	unsigned long flags, val;
+#define __read_64bit_c0_split(source, sel)				\
+({									\
+	unsigned long long val;						\
+	unsigned long flags;						\
+									\
+	local_irq_save(flags);						\
+	if (sel == 0)							\
+		__asm__ __volatile__(					\
+			".set\tmips64\n\t"				\
+			"dmfc0\t%M0, " #source "\n\t"			\
+			"dsll\t%L0, %M0, 32\n\t"			\
+			"dsrl\t%M0, %M0, 32\n\t"			\
+			"dsrl\t%L0, %L0, 32\n\t"			\
+			".set\tmips0"					\
+			: "=r" (val));					\
+	else								\
+		__asm__ __volatile__(					\
+			".set\tmips64\n\t"				\
+			"dmfc0\t%M0, " #source ", " #sel "\n\t"		\
+			"dsll\t%L0, %M0, 32\n\t"			\
+			"dsrl\t%M0, %M0, 32\n\t"			\
+			"dsrl\t%L0, %L0, 32\n\t"			\
+			".set\tmips0"					\
+			: "=r" (val));					\
+	local_irq_restore(flags);					\
+									\
+	val;								\
+})
 
-	__save_and_cli(flags);
-	__asm__ __volatile__(
-		".set\tmips3\n\t"
-		"dmfc0\t%M0, $2\n\t"
-		"dsll\t%L0, %M0, 32\n\t"
-		"dsrl\t%M0, %M0, 32\n\t"
-		"dsrl\t%L0, %L0, 32\n\t"
-		".set\tmips0"
-		: "=r" (val));
-	__restore_flags(flags);
+#define __write_64bit_c0_split(source, sel, val)			\
+do {									\
+	unsigned long flags;						\
+									\
+	local_irq_save(flags);						\
+	if (sel == 0)							\
+		__asm__ __volatile__(					\
+			".set\tmips64\n\t"				\
+			"dsll\t%L0, %L0, 32\n\t"			\
+			"dsrl\t%L0, %L0, 32\n\t"			\
+			"dsll\t%M0, %M0, 32\n\t"			\
+			"or\t%L0, %L0, %M0\n\t"				\
+			"dmtc0\t%L0, " #source "\n\t"			\
+			".set\tmips0"					\
+			: : "r" (val));					\
+	else								\
+		__asm__ __volatile__(					\
+			".set\tmips64\n\t"				\
+			"dsll\t%L0, %L0, 32\n\t"			\
+			"dsrl\t%L0, %L0, 32\n\t"			\
+			"dsll\t%M0, %M0, 32\n\t"			\
+			"or\t%L0, %L0, %M0\n\t"				\
+			"dmtc0\t%L0, " #source ", " #sel "\n\t"		\
+			".set\tmips0"					\
+			: : "r" (val));					\
+	local_irq_restore(flags);					\
+} while (0)
 
-	return val;
-}
+#define read_c0_index()		__read_32bit_c0_register($0, 0)
+#define write_c0_index(val)	__write_32bit_c0_register($0, 0, val)
 
-static inline unsigned long long get_entrylo1(void)
-{
-	unsigned long flags, val;
+#define read_c0_entrylo0()	__read_ulong_c0_register($2, 0)
+#define write_c0_entrylo0(val)	__write_ulong_c0_register($2, 0, val)
 
-	__save_and_cli(flags);
-	__asm__ __volatile__(
-		".set\tmips3\n\t"
-		"dmfc0\t%M0, $3\n\t"
-		"dsrl\t%L0, %M0, 32\n\t"
-		"dsrl\t%M0, %M0, 32\n\t"
-		"dsll\t%L0, %L0, 32\n\t"
-		".set\tmips0"
-		: "=r" (val));
-	__restore_flags(flags);
+#define read_c0_entrylo1()	__read_ulong_c0_register($3, 0)
+#define write_c0_entrylo1(val)	__write_ulong_c0_register($3, 0, val)
 
-	return val;
-}
+#define read_c0_conf()		__read_32bit_c0_register($3, 0)
+#define write_c0_conf(val)	__write_32bit_c0_register($3, 0, val)
 
-#else
-
-static inline void set_entrylo0(unsigned long val)
-{
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mtc0 %z0, $2\n\t"
-		".set pop"
-		: : "Jr" (val));
-}
+#define read_c0_context()	__read_ulong_c0_register($4, 0)
+#define write_c0_context(val)	__write_ulong_c0_register($4, 0, val)
 
-static inline void set_entrylo1(unsigned long val)
-{
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mtc0 %z0, $3\n\t"
-		".set pop"
-		: : "Jr" (val));
-}
+#define read_c0_pagemask()	__read_32bit_c0_register($5, 0)
+#define write_c0_pagemask(val)	__write_32bit_c0_register($5, 0, val)
 
-static inline unsigned long get_entrylo0(void)
-{
-	unsigned long val;
+#define read_c0_wired()		__read_32bit_c0_register($6, 0)
+#define write_c0_wired(val)	__write_32bit_c0_register($6, 0, val)
 
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mfc0 %0, $2\n\t"
-		".set pop" : "=r" (val));
+#define read_c0_info()		__read_32bit_c0_register($7, 0)
 
-	return val;
-}
+#define read_c0_cache()		__read_32bit_c0_register($7, 0)	/* TX39xx */
+#define write_c0_cache(val)	__write_32bit_c0_register($7, 0, val)
 
-static inline unsigned long get_entrylo1(void)
-{
-	unsigned long val;
+#define read_c0_count()		__read_32bit_c0_register($9, 0)
+#define write_c0_count(val)	__write_32bit_c0_register($9, 0, val)
 
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mfc0 %0, $3\n\t"
-		".set pop" : "=r" (val));
+#define read_c0_entryhi()	__read_ulong_c0_register($10, 0)
+#define write_c0_entryhi(val)	__write_ulong_c0_register($10, 0, val)
 
-	return val;
-}
+#define read_c0_compare()	__read_32bit_c0_register($11, 0)
+#define write_c0_compare(val)	__write_32bit_c0_register($11, 0, val)
 
-#endif
+#define read_c0_status()	__read_32bit_c0_register($12, 0)
+#define write_c0_status(val)	__write_32bit_c0_register($12, 0, val)
 
-/* CP0_ENTRYHI register */
-static inline unsigned long get_entryhi(void)
-{
-	unsigned long val;
+#define read_c0_cause()		__read_32bit_c0_register($13, 0)
+#define write_c0_cause(val)	__write_32bit_c0_register($13, 0, val)
 
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mfc0 %0, $10\n\t"
-		".set pop"
-		: "=r" (val));
+#define read_c0_prid()		__read_32bit_c0_register($15, 0)
 
-	return val;
-}
+#define read_c0_config()	__read_32bit_c0_register($16, 0)
+#define read_c0_config1()	__read_32bit_c0_register($16, 1)
+#define read_c0_config2()	__read_32bit_c0_register($16, 2)
+#define read_c0_config3()	__read_32bit_c0_register($16, 3)
+#define write_c0_config(val)	__write_32bit_c0_register($16, 0, val)
+#define write_c0_config1(val)	__write_32bit_c0_register($16, 1, val)
+#define write_c0_config2(val)	__write_32bit_c0_register($16, 2, val)
+#define write_c0_config3(val)	__write_32bit_c0_register($16, 3, val)
 
-static inline void set_entryhi(unsigned long val)
-{
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mtc0 %z0, $10\n\t"
-		".set pop"
-		: : "Jr" (val));
-}
-
-/* CP0_INDEX register */
-static inline unsigned long get_index(void)
-{
-	unsigned long val;
-
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mfc0 %0, $0\n\t"
-		".set pop"
-		: "=r" (val));
-	return val;
-}
+/*
+ * The WatchLo register.  There may be upto 8 of them.
+ */
+#define read_c0_watchlo0()	__read_ulong_c0_register($18, 0)
+#define read_c0_watchlo1()	__read_ulong_c0_register($18, 1)
+#define read_c0_watchlo2()	__read_ulong_c0_register($18, 2)
+#define read_c0_watchlo3()	__read_ulong_c0_register($18, 3)
+#define read_c0_watchlo4()	__read_ulong_c0_register($18, 4)
+#define read_c0_watchlo5()	__read_ulong_c0_register($18, 5)
+#define read_c0_watchlo6()	__read_ulong_c0_register($18, 6)
+#define read_c0_watchlo7()	__read_ulong_c0_register($18, 7)
+#define write_c0_watchlo0(val)	__write_ulong_c0_register($18, 0, val)
+#define write_c0_watchlo1(val)	__write_ulong_c0_register($18, 1, val)
+#define write_c0_watchlo2(val)	__write_ulong_c0_register($18, 2, val)
+#define write_c0_watchlo3(val)	__write_ulong_c0_register($18, 3, val)
+#define write_c0_watchlo4(val)	__write_ulong_c0_register($18, 4, val)
+#define write_c0_watchlo5(val)	__write_ulong_c0_register($18, 5, val)
+#define write_c0_watchlo6(val)	__write_ulong_c0_register($18, 6, val)
+#define write_c0_watchlo7(val)	__write_ulong_c0_register($18, 7, val)
 
-static inline void set_index(unsigned long val)
-{
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mtc0 %z0, $0\n\t"
-		".set pop"
-		: : "Jr" (val));
-}
+/*
+ * The WatchHi register.  There may be upto 8 of them.
+ */
+#define read_c0_watchhi0()	__read_32bit_c0_register($19, 0)
+#define read_c0_watchhi1()	__read_32bit_c0_register($19, 1)
+#define read_c0_watchhi2()	__read_32bit_c0_register($19, 2)
+#define read_c0_watchhi3()	__read_32bit_c0_register($19, 3)
+#define read_c0_watchhi4()	__read_32bit_c0_register($19, 4)
+#define read_c0_watchhi5()	__read_32bit_c0_register($19, 5)
+#define read_c0_watchhi6()	__read_32bit_c0_register($19, 6)
+#define read_c0_watchhi7()	__read_32bit_c0_register($19, 7)
 
-/* CP0_WIRED register */
-static inline unsigned long get_wired(void)
-{
-	unsigned long val;
+#define write_c0_watchhi0(val)	__write_32bit_c0_register($19, 0, val)
+#define write_c0_watchhi1(val)	__write_32bit_c0_register($19, 1, val)
+#define write_c0_watchhi2(val)	__write_32bit_c0_register($19, 2, val)
+#define write_c0_watchhi3(val)	__write_32bit_c0_register($19, 3, val)
+#define write_c0_watchhi4(val)	__write_32bit_c0_register($19, 4, val)
+#define write_c0_watchhi5(val)	__write_32bit_c0_register($19, 5, val)
+#define write_c0_watchhi6(val)	__write_32bit_c0_register($19, 6, val)
+#define write_c0_watchhi7(val)	__write_32bit_c0_register($19, 7, val)
 
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mfc0 %0, $6\n\t"
-		".set pop"
-		: "=r" (val));
-	return val;
-}
+#define read_c0_xcontext()	__read_ulong_c0_register($20, 0)
+#define write_c0_xcontext(val)	__write_ulong_c0_register($20, 0, val)
 
-static inline void set_wired(unsigned long val)
-{
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mtc0 %z0, $6\n\t"
-		".set pop"
-		: : "Jr" (val));
-}
+#define read_c0_intcontrol()	__read_32bit_c0_register($20, 1)
+#define write_c0_intcontrol(val) __write_32bit_c0_register($20, 1, val)
 
-/* CP0_STATUS register */
-static inline unsigned int get_status(void)
-{
-	unsigned long val;
+#define read_c0_framemask()	__read_32bit_c0_register($21, 0)
+#define write_c0_framemask(val)	__write_32bit_c0_register($21, 0, val)
 
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mfc0 %0, $12\n\t"
-		".set pop"
-		: "=r" (val));
-	return val;
-}
+#define read_c0_debug()		__read_32bit_c0_register($23, 0)
+#define write_c0_debug(val)	__write_32bit_c0_register($23, 0, val)
 
-static inline void set_status(unsigned long val)
-{
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mtc0 %z0, $12\n\t"
-		".set pop"
-		: : "Jr" (val));
-}
+#define read_c0_depc()		__read_ulong_c0_register($24, 0)
+#define write_c0_depc(val)	__write_ulong_c0_register($24, 0, val)
 
-static inline unsigned long get_info(void)
-{
-	unsigned long val;
+#define read_c0_ecc()		__read_32bit_c0_register($26, 0)
+#define write_c0_ecc(val)	__write_32bit_c0_register($26, 0, val)
 
-	__asm__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mfc0 %0, $7\n\t"
-		".set pop"
-		: "=r" (val));
-	return val;
-}
+#define read_c0_derraddr0()	__read_ulong_c0_register($26, 1)
+#define write_c0_derraddr0(val)	__write_ulong_c0_register($26, 1, val)
 
-/* CP0_TAGLO and CP0_TAGHI registers */
-static inline unsigned long get_taglo(void)
-{
-	unsigned long val;
+#define read_c0_cacheerr()	__read_32bit_c0_register($27, 0)
 
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mfc0 %0, $28\n\t"
-		".set pop"
-		: "=r" (val));
-	return val;
-}
+#define read_c0_derraddr1()	__read_ulong_c0_register($27, 1)
+#define write_c0_derraddr1(val)	__write_ulong_c0_register($27, 1, val)
 
-static inline void set_taglo(unsigned long val)
-{
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mtc0 %z0, $28\n\t"
-		".set pop"
-		: : "Jr" (val));
-}
+#define read_c0_taglo()		__read_32bit_c0_register($28, 0)
+#define write_c0_taglo(val)	__write_32bit_c0_register($28, 0, val)
 
-static inline unsigned long get_taghi(void)
-{
-	unsigned long val;
+#define read_c0_taghi()		__read_32bit_c0_register($29, 0)
+#define write_c0_taghi(val)	__write_32bit_c0_register($29, 0, val)
 
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mfc0 %0, $29\n\t"
-		".set pop"
-		: "=r" (val));
-	return val;
-}
+#define read_c0_errorepc()	__read_ulong_c0_register($30, 0)
+#define write_c0_errorepc(val)	__write_ulong_c0_register($30, 0, val)
 
-static inline void set_taghi(unsigned long val)
-{
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mtc0 %z0, $29\n\t"
-		".set pop"
-		: : "Jr" (val));
-}
+/*
+ * Macros to access the floating point coprocessor control registers
+ */
+#define read_32bit_cp1_register(source)                         \
+({ int __res;                                                   \
+	__asm__ __volatile__(                                   \
+	".set\tpush\n\t"					\
+	".set\treorder\n\t"					\
+        "cfc1\t%0,"STR(source)"\n\t"                            \
+	".set\tpop"						\
+        : "=r" (__res));                                        \
+        __res;})
 
-static inline unsigned long get_context(void)
+/* TLB operations. */
+static inline void tlb_probe(void)
 {
-	unsigned long val;
-
 	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mfc0 %0, $4\n\t"
-		".set pop"
-		: "=r" (val));
-
-	return val;
+		".set noreorder\n\t"
+		"tlbp\n\t"
+		".set reorder");
 }
 
-static inline void set_context(unsigned long val)
+static inline void tlb_read(void)
 {
 	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mtc0 %z0, $4\n\t"
-		".set pop"
-		: : "Jr" (val));
+		".set noreorder\n\t"
+		"tlbr\n\t"
+		".set reorder");
 }
 
-static inline unsigned long get_errorepc(void)
+static inline void tlb_write_indexed(void)
 {
-	unsigned long val;
-
 	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mfc0 %0, $30\n\t"
-		".set pop"
-		: "=r" (val));
-
-	return val;
+		".set noreorder\n\t"
+		"tlbwi\n\t"
+		".set reorder");
 }
 
-static inline void set_errorepc(unsigned long val)
+static inline void tlb_write_random(void)
 {
 	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mtc0 %z0, $30\n\t"
-		".set pop"
-		: : "Jr" (val));
+		".set noreorder\n\t"
+		"tlbwr\n\t"
+		".set reorder");
 }
 
 /*
- * Manipulate the status register.
- * Mostly used to access the interrupt bits.
+ * Manipulate bits in a c0 register.
  */
-#define __BUILD_SET_CP0(name,register)				\
+#define __BUILD_SET_C0(name,register)				\
 static inline unsigned int					\
-set_cp0_##name(unsigned int set)				\
+set_c0_##name(unsigned int set)					\
 {								\
 	unsigned int res;					\
 								\
-	res = read_32bit_cp0_register(register);		\
+	res = read_c0_##name();					\
 	res |= set;						\
-	write_32bit_cp0_register(register, res);		\
+	write_c0_##name(res);					\
 								\
 	return res;						\
 }								\
 								\
 static inline unsigned int					\
-clear_cp0_##name(unsigned int clear)				\
+clear_c0_##name(unsigned int clear)				\
 {								\
 	unsigned int res;					\
 								\
-	res = read_32bit_cp0_register(register);		\
+	res = read_c0_##name();					\
 	res &= ~clear;						\
-	write_32bit_cp0_register(register, res);		\
+	write_c0_##name(res);					\
 								\
 	return res;						\
 }								\
 								\
 static inline unsigned int					\
-change_cp0_##name(unsigned int change, unsigned int new)	\
+change_c0_##name(unsigned int change, unsigned int new)		\
 {								\
 	unsigned int res;					\
 								\
-	res = read_32bit_cp0_register(register);		\
+	res = read_c0_##name();					\
 	res &= ~change;						\
 	res |= (new & change);					\
-	write_32bit_cp0_register(register, res);		\
+	write_c0_##name(res);					\
 								\
 	return res;						\
 }
 
-__BUILD_SET_CP0(status,CP0_STATUS)
-__BUILD_SET_CP0(cause,CP0_CAUSE)
-__BUILD_SET_CP0(config,CP0_CONFIG)
-
-#define __enable_fpu()							\
-do {									\
-	set_cp0_status(ST0_CU1);					\
-	asm("nop;nop;nop;nop");		/* max. hazard */		\
-} while (0)
-
-#define __disable_fpu()							\
-do {									\
-	clear_cp0_status(ST0_CU1);					\
-	/* We don't care about the cp0 hazard here  */			\
-} while (0)
-
-#define enable_fpu()							\
-do {									\
-	if (mips_cpu.options & MIPS_CPU_FPU)				\
-		__enable_fpu();						\
-} while (0)
-
-#define disable_fpu()							\
-do {									\
-	if (mips_cpu.options & MIPS_CPU_FPU)				\
-		__disable_fpu();					\
-} while (0)
+__BUILD_SET_C0(status,CP0_STATUS)
+__BUILD_SET_C0(cause,CP0_CAUSE)
+__BUILD_SET_C0(config,CP0_CONFIG)
 
 #endif /* !__ASSEMBLY__ */
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)