summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2007-07-10 17:33:02 +0100
committerRalf Baechle <ralf@linux-mips.org>2007-07-10 17:33:02 +0100
commita36920200c5b89d56120a5e839fe4a603d51b16c (patch)
treeaefb1fc4b0792ef788024fa596954a5689f15d0a
parentd223a86154f8c66f5a380b17e1c8091d56f47cf8 (diff)
[MIPS] Enable support for the userlocal hardware register
Which will cut down the cost of RDHWR $29 which is used to obtain the TLS pointer and so far being emulated in software down to a single cycle operation. Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/kernel/cpu-probe.c2
-rw-r--r--arch/mips/kernel/syscall.c5
-rw-r--r--arch/mips/kernel/traps.c9
-rw-r--r--include/asm-mips/cpu-features.h4
-rw-r--r--include/asm-mips/cpu.h1
-rw-r--r--include/asm-mips/mipsregs.h6
-rw-r--r--include/asm-mips/system.h2
7 files changed, 24 insertions, 5 deletions
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index b12eeee0e97..27fc1843423 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -588,6 +588,8 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c)
c->options |= MIPS_CPU_VEIC;
if (config3 & MIPS_CONF3_MT)
c->ases |= MIPS_ASE_MIPSMT;
+ if (config3 & MIPS_CONF3_ULRI)
+ c->options |= MIPS_CPU_ULRI;
return config3 & MIPS_CONF_M;
}
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 9dd5a2df8ea..b947c61c0cc 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -272,9 +272,8 @@ asmlinkage int sys_set_thread_area(unsigned long addr)
struct thread_info *ti = task_thread_info(current);
ti->tp_value = addr;
-
- /* If some future MIPS implementation has this register in hardware,
- * we will need to update it here (and in context switches). */
+ if (cpu_has_userlocal)
+ write_c0_userlocal(addr);
return 0;
}
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index c598e890a88..9b19a84d11e 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -1341,7 +1341,14 @@ void __init per_cpu_trap_init(void)
set_c0_status(ST0_MX);
#ifdef CONFIG_CPU_MIPSR2
- write_c0_hwrena (0x0000000f); /* Allow rdhwr to all registers */
+ if (cpu_has_mips_r2) {
+ unsigned int enable = 0x0000000f;
+
+ if (cpu_has_userlocal)
+ enable |= (1 << 29);
+
+ write_c0_hwrena(enable);
+ }
#endif
#ifdef CONFIG_MIPS_MT_SMTC
diff --git a/include/asm-mips/cpu-features.h b/include/asm-mips/cpu-features.h
index 5e4bed123b4..d95a83e3e1d 100644
--- a/include/asm-mips/cpu-features.h
+++ b/include/asm-mips/cpu-features.h
@@ -150,6 +150,10 @@
#define cpu_has_mipsmt (cpu_data[0].ases & MIPS_ASE_MIPSMT)
#endif
+#ifndef cpu_has_userlocal
+#define cpu_has_userlocal (cpu_data[0].options & MIPS_CPU_ULRI)
+#endif
+
#ifdef CONFIG_32BIT
# ifndef cpu_has_nofpuex
# define cpu_has_nofpuex (cpu_data[0].options & MIPS_CPU_NOFPUEX)
diff --git a/include/asm-mips/cpu.h b/include/asm-mips/cpu.h
index 2924069075e..49c1f001186 100644
--- a/include/asm-mips/cpu.h
+++ b/include/asm-mips/cpu.h
@@ -257,6 +257,7 @@
#define MIPS_CPU_PREFETCH 0x00080000 /* CPU has usable prefetch */
#define MIPS_CPU_VINT 0x00100000 /* CPU supports MIPSR2 vectored interrupts */
#define MIPS_CPU_VEIC 0x00200000 /* CPU supports MIPSR2 external interrupt controller mode */
+#define MIPS_CPU_ULRI 0x00400000 /* CPU has ULRI feature */
/*
* CPU ASE encodings
diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h
index 89c81922d47..668db02c280 100644
--- a/include/asm-mips/mipsregs.h
+++ b/include/asm-mips/mipsregs.h
@@ -7,7 +7,7 @@
* Copyright (C) 2000 Silicon Graphics, Inc.
* 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) 2000, 07 MIPS Technologies, Inc.
* Copyright (C) 2003, 2004 Maciej W. Rozycki
*/
#ifndef _ASM_MIPSREGS_H
@@ -533,6 +533,7 @@
#define MIPS_CONF3_VEIC (_ULCAST_(1) << 6)
#define MIPS_CONF3_LPA (_ULCAST_(1) << 7)
#define MIPS_CONF3_DSP (_ULCAST_(1) << 10)
+#define MIPS_CONF3_ULRI (_ULCAST_(1) << 13)
#define MIPS_CONF7_WII (_ULCAST_(1) << 31)
@@ -772,6 +773,9 @@ do { \
#define read_c0_context() __read_ulong_c0_register($4, 0)
#define write_c0_context(val) __write_ulong_c0_register($4, 0, val)
+#define read_c0_userlocal() __read_ulong_c0_register($4, 2)
+#define write_c0_userlocal(val) __write_ulong_c0_register($4, 2, val)
+
#define read_c0_pagemask() __read_32bit_c0_register($5, 0)
#define write_c0_pagemask(val) __write_32bit_c0_register($5, 0, val)
diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h
index 9b3a8dd2c3d..be64fc55562 100644
--- a/include/asm-mips/system.h
+++ b/include/asm-mips/system.h
@@ -67,6 +67,8 @@ do { \
(last) = resume(prev, next, task_thread_info(next)); \
if (cpu_has_dsp) \
__restore_dsp(current); \
+ if (cpu_has_userlocal) \
+ write_c0_userlocal(task_thread_info(current)->tp_value);\
} while(0)
/*