aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2015-04-13 16:03:32 +0200
committerRalf Baechle <ralf@linux-mips.org>2015-04-13 16:03:32 +0200
commit3e20a26b02bd4f24945c87407df51948dd488620 (patch)
treef466d3b2a47a98ec2910724e17ee2f3a93c1a49e /arch/mips/kernel
parentMerge branch '4.1-fp' into mips-for-linux-next (diff)
parentMIPS: Makefile: Fix MIPS ASE detection code (diff)
downloadlinux-dev-3e20a26b02bd4f24945c87407df51948dd488620.tar.xz
linux-dev-3e20a26b02bd4f24945c87407df51948dd488620.zip
Merge branch '4.0-fixes' into mips-for-linux-next
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r--arch/mips/kernel/cpu-probe.c4
-rw-r--r--arch/mips/kernel/entry.S3
-rw-r--r--arch/mips/kernel/proc.c1
-rw-r--r--arch/mips/kernel/smp-cps.c6
-rw-r--r--arch/mips/kernel/unaligned.c340
5 files changed, 244 insertions, 110 deletions
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 73ab840f13bd..e36515dcd3b2 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -600,6 +600,10 @@ static inline unsigned int decode_config5(struct cpuinfo_mips *c)
c->options |= MIPS_CPU_MAAR;
if (config5 & MIPS_CONF5_LLB)
c->options |= MIPS_CPU_RW_LLB;
+#ifdef CONFIG_XPA
+ if (config5 & MIPS_CONF5_MVH)
+ c->options |= MIPS_CPU_XPA;
+#endif
return config5 & MIPS_CONF_M;
}
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S
index af41ba6db960..7791840cf22c 100644
--- a/arch/mips/kernel/entry.S
+++ b/arch/mips/kernel/entry.S
@@ -10,6 +10,7 @@
#include <asm/asm.h>
#include <asm/asmmacro.h>
+#include <asm/compiler.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
#include <asm/stackframe.h>
@@ -185,7 +186,7 @@ syscall_exit_work:
* For C code use the inline version named instruction_hazard().
*/
LEAF(mips_ihb)
- .set mips32r2
+ .set MIPS_ISA_LEVEL_RAW
jr.hb ra
nop
END(mips_ihb)
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c
index 130af7d26a9c..298b2b773d12 100644
--- a/arch/mips/kernel/proc.c
+++ b/arch/mips/kernel/proc.c
@@ -120,6 +120,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
if (cpu_has_msa) seq_printf(m, "%s", " msa");
if (cpu_has_eva) seq_printf(m, "%s", " eva");
if (cpu_has_htw) seq_printf(m, "%s", " htw");
+ if (cpu_has_xpa) seq_printf(m, "%s", " xpa");
seq_printf(m, "\n");
if (cpu_has_mmips) {
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index bed7590e475f..d5589bedd0a4 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -88,6 +88,12 @@ static void __init cps_smp_setup(void)
/* Make core 0 coherent with everything */
write_gcr_cl_coherence(0xff);
+
+#ifdef CONFIG_MIPS_MT_FPAFF
+ /* If we have an FPU, enroll ourselves in the FPU-full mask */
+ if (cpu_has_fpu)
+ cpu_set(0, mt_fpu_cpumask);
+#endif /* CONFIG_MIPS_MT_FPAFF */
}
static void __init cps_prepare_cpus(unsigned int max_cpus)
diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c
index 27af5634a69b..af84bef0c90d 100644
--- a/arch/mips/kernel/unaligned.c
+++ b/arch/mips/kernel/unaligned.c
@@ -107,10 +107,11 @@ static u32 unaligned_action;
extern void show_registers(struct pt_regs *regs);
#ifdef __BIG_ENDIAN
-#define LoadHW(addr, value, res) \
+#define _LoadHW(addr, value, res, type) \
+do { \
__asm__ __volatile__ (".set\tnoat\n" \
- "1:\t"user_lb("%0", "0(%2)")"\n" \
- "2:\t"user_lbu("$1", "1(%2)")"\n\t" \
+ "1:\t"type##_lb("%0", "0(%2)")"\n" \
+ "2:\t"type##_lbu("$1", "1(%2)")"\n\t"\
"sll\t%0, 0x8\n\t" \
"or\t%0, $1\n\t" \
"li\t%1, 0\n" \
@@ -125,13 +126,15 @@ extern void show_registers(struct pt_regs *regs);
STR(PTR)"\t2b, 4b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
- : "r" (addr), "i" (-EFAULT));
+ : "r" (addr), "i" (-EFAULT)); \
+} while(0)
#ifndef CONFIG_CPU_MIPSR6
-#define LoadW(addr, value, res) \
+#define _LoadW(addr, value, res, type) \
+do { \
__asm__ __volatile__ ( \
- "1:\t"user_lwl("%0", "(%2)")"\n" \
- "2:\t"user_lwr("%0", "3(%2)")"\n\t" \
+ "1:\t"type##_lwl("%0", "(%2)")"\n" \
+ "2:\t"type##_lwr("%0", "3(%2)")"\n\t"\
"li\t%1, 0\n" \
"3:\n\t" \
".insn\n\t" \
@@ -144,21 +147,24 @@ extern void show_registers(struct pt_regs *regs);
STR(PTR)"\t2b, 4b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
- : "r" (addr), "i" (-EFAULT));
+ : "r" (addr), "i" (-EFAULT)); \
+} while(0)
+
#else
/* MIPSR6 has no lwl instruction */
-#define LoadW(addr, value, res) \
+#define _LoadW(addr, value, res, type) \
+do { \
__asm__ __volatile__ ( \
".set\tpush\n" \
".set\tnoat\n\t" \
- "1:"user_lb("%0", "0(%2)")"\n\t" \
- "2:"user_lbu("$1", "1(%2)")"\n\t" \
+ "1:"type##_lb("%0", "0(%2)")"\n\t" \
+ "2:"type##_lbu("$1", "1(%2)")"\n\t" \
"sll\t%0, 0x8\n\t" \
"or\t%0, $1\n\t" \
- "3:"user_lbu("$1", "2(%2)")"\n\t" \
+ "3:"type##_lbu("$1", "2(%2)")"\n\t" \
"sll\t%0, 0x8\n\t" \
"or\t%0, $1\n\t" \
- "4:"user_lbu("$1", "3(%2)")"\n\t" \
+ "4:"type##_lbu("$1", "3(%2)")"\n\t" \
"sll\t%0, 0x8\n\t" \
"or\t%0, $1\n\t" \
"li\t%1, 0\n" \
@@ -176,14 +182,17 @@ extern void show_registers(struct pt_regs *regs);
STR(PTR)"\t4b, 11b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
- : "r" (addr), "i" (-EFAULT));
+ : "r" (addr), "i" (-EFAULT)); \
+} while(0)
+
#endif /* CONFIG_CPU_MIPSR6 */
-#define LoadHWU(addr, value, res) \
+#define _LoadHWU(addr, value, res, type) \
+do { \
__asm__ __volatile__ ( \
".set\tnoat\n" \
- "1:\t"user_lbu("%0", "0(%2)")"\n" \
- "2:\t"user_lbu("$1", "1(%2)")"\n\t" \
+ "1:\t"type##_lbu("%0", "0(%2)")"\n" \
+ "2:\t"type##_lbu("$1", "1(%2)")"\n\t"\
"sll\t%0, 0x8\n\t" \
"or\t%0, $1\n\t" \
"li\t%1, 0\n" \
@@ -199,13 +208,15 @@ extern void show_registers(struct pt_regs *regs);
STR(PTR)"\t2b, 4b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
- : "r" (addr), "i" (-EFAULT));
+ : "r" (addr), "i" (-EFAULT)); \
+} while(0)
#ifndef CONFIG_CPU_MIPSR6
-#define LoadWU(addr, value, res) \
+#define _LoadWU(addr, value, res, type) \
+do { \
__asm__ __volatile__ ( \
- "1:\t"user_lwl("%0", "(%2)")"\n" \
- "2:\t"user_lwr("%0", "3(%2)")"\n\t" \
+ "1:\t"type##_lwl("%0", "(%2)")"\n" \
+ "2:\t"type##_lwr("%0", "3(%2)")"\n\t"\
"dsll\t%0, %0, 32\n\t" \
"dsrl\t%0, %0, 32\n\t" \
"li\t%1, 0\n" \
@@ -220,9 +231,11 @@ extern void show_registers(struct pt_regs *regs);
STR(PTR)"\t2b, 4b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
- : "r" (addr), "i" (-EFAULT));
+ : "r" (addr), "i" (-EFAULT)); \
+} while(0)
-#define LoadDW(addr, value, res) \
+#define _LoadDW(addr, value, res) \
+do { \
__asm__ __volatile__ ( \
"1:\tldl\t%0, (%2)\n" \
"2:\tldr\t%0, 7(%2)\n\t" \
@@ -238,21 +251,24 @@ extern void show_registers(struct pt_regs *regs);
STR(PTR)"\t2b, 4b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
- : "r" (addr), "i" (-EFAULT));
+ : "r" (addr), "i" (-EFAULT)); \
+} while(0)
+
#else
/* MIPSR6 has not lwl and ldl instructions */
-#define LoadWU(addr, value, res) \
+#define _LoadWU(addr, value, res, type) \
+do { \
__asm__ __volatile__ ( \
".set\tpush\n\t" \
".set\tnoat\n\t" \
- "1:"user_lbu("%0", "0(%2)")"\n\t" \
- "2:"user_lbu("$1", "1(%2)")"\n\t" \
+ "1:"type##_lbu("%0", "0(%2)")"\n\t" \
+ "2:"type##_lbu("$1", "1(%2)")"\n\t" \
"sll\t%0, 0x8\n\t" \
"or\t%0, $1\n\t" \
- "3:"user_lbu("$1", "2(%2)")"\n\t" \
+ "3:"type##_lbu("$1", "2(%2)")"\n\t" \
"sll\t%0, 0x8\n\t" \
"or\t%0, $1\n\t" \
- "4:"user_lbu("$1", "3(%2)")"\n\t" \
+ "4:"type##_lbu("$1", "3(%2)")"\n\t" \
"sll\t%0, 0x8\n\t" \
"or\t%0, $1\n\t" \
"li\t%1, 0\n" \
@@ -270,9 +286,11 @@ extern void show_registers(struct pt_regs *regs);
STR(PTR)"\t4b, 11b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
- : "r" (addr), "i" (-EFAULT));
+ : "r" (addr), "i" (-EFAULT)); \
+} while(0)
-#define LoadDW(addr, value, res) \
+#define _LoadDW(addr, value, res) \
+do { \
__asm__ __volatile__ ( \
".set\tpush\n\t" \
".set\tnoat\n\t" \
@@ -317,16 +335,19 @@ extern void show_registers(struct pt_regs *regs);
STR(PTR)"\t8b, 11b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
- : "r" (addr), "i" (-EFAULT));
+ : "r" (addr), "i" (-EFAULT)); \
+} while(0)
+
#endif /* CONFIG_CPU_MIPSR6 */
-#define StoreHW(addr, value, res) \
+#define _StoreHW(addr, value, res, type) \
+do { \
__asm__ __volatile__ ( \
".set\tnoat\n" \
- "1:\t"user_sb("%1", "1(%2)")"\n" \
+ "1:\t"type##_sb("%1", "1(%2)")"\n" \
"srl\t$1, %1, 0x8\n" \
- "2:\t"user_sb("$1", "0(%2)")"\n" \
+ "2:\t"type##_sb("$1", "0(%2)")"\n" \
".set\tat\n\t" \
"li\t%0, 0\n" \
"3:\n\t" \
@@ -340,13 +361,15 @@ extern void show_registers(struct pt_regs *regs);
STR(PTR)"\t2b, 4b\n\t" \
".previous" \
: "=r" (res) \
- : "r" (value), "r" (addr), "i" (-EFAULT));
+ : "r" (value), "r" (addr), "i" (-EFAULT));\
+} while(0)
#ifndef CONFIG_CPU_MIPSR6
-#define StoreW(addr, value, res) \
+#define _StoreW(addr, value, res, type) \
+do { \
__asm__ __volatile__ ( \
- "1:\t"user_swl("%1", "(%2)")"\n" \
- "2:\t"user_swr("%1", "3(%2)")"\n\t" \
+ "1:\t"type##_swl("%1", "(%2)")"\n" \
+ "2:\t"type##_swr("%1", "3(%2)")"\n\t"\
"li\t%0, 0\n" \
"3:\n\t" \
".insn\n\t" \
@@ -359,9 +382,11 @@ extern void show_registers(struct pt_regs *regs);
STR(PTR)"\t2b, 4b\n\t" \
".previous" \
: "=r" (res) \
- : "r" (value), "r" (addr), "i" (-EFAULT));
+ : "r" (value), "r" (addr), "i" (-EFAULT)); \
+} while(0)
-#define StoreDW(addr, value, res) \
+#define _StoreDW(addr, value, res) \
+do { \
__asm__ __volatile__ ( \
"1:\tsdl\t%1,(%2)\n" \
"2:\tsdr\t%1, 7(%2)\n\t" \
@@ -377,20 +402,23 @@ extern void show_registers(struct pt_regs *regs);
STR(PTR)"\t2b, 4b\n\t" \
".previous" \
: "=r" (res) \
- : "r" (value), "r" (addr), "i" (-EFAULT));
+ : "r" (value), "r" (addr), "i" (-EFAULT)); \
+} while(0)
+
#else
/* MIPSR6 has no swl and sdl instructions */
-#define StoreW(addr, value, res) \
+#define _StoreW(addr, value, res, type) \
+do { \
__asm__ __volatile__ ( \
".set\tpush\n\t" \
".set\tnoat\n\t" \
- "1:"user_sb("%1", "3(%2)")"\n\t" \
+ "1:"type##_sb("%1", "3(%2)")"\n\t" \
"srl\t$1, %1, 0x8\n\t" \
- "2:"user_sb("$1", "2(%2)")"\n\t" \
+ "2:"type##_sb("$1", "2(%2)")"\n\t" \
"srl\t$1, $1, 0x8\n\t" \
- "3:"user_sb("$1", "1(%2)")"\n\t" \
+ "3:"type##_sb("$1", "1(%2)")"\n\t" \
"srl\t$1, $1, 0x8\n\t" \
- "4:"user_sb("$1", "0(%2)")"\n\t" \
+ "4:"type##_sb("$1", "0(%2)")"\n\t" \
".set\tpop\n\t" \
"li\t%0, 0\n" \
"10:\n\t" \
@@ -407,9 +435,11 @@ extern void show_registers(struct pt_regs *regs);
".previous" \
: "=&r" (res) \
: "r" (value), "r" (addr), "i" (-EFAULT) \
- : "memory");
+ : "memory"); \
+} while(0)
#define StoreDW(addr, value, res) \
+do { \
__asm__ __volatile__ ( \
".set\tpush\n\t" \
".set\tnoat\n\t" \
@@ -449,15 +479,18 @@ extern void show_registers(struct pt_regs *regs);
".previous" \
: "=&r" (res) \
: "r" (value), "r" (addr), "i" (-EFAULT) \
- : "memory");
+ : "memory"); \
+} while(0)
+
#endif /* CONFIG_CPU_MIPSR6 */
#else /* __BIG_ENDIAN */
-#define LoadHW(addr, value, res) \
+#define _LoadHW(addr, value, res, type) \
+do { \
__asm__ __volatile__ (".set\tnoat\n" \
- "1:\t"user_lb("%0", "1(%2)")"\n" \
- "2:\t"user_lbu("$1", "0(%2)")"\n\t" \
+ "1:\t"type##_lb("%0", "1(%2)")"\n" \
+ "2:\t"type##_lbu("$1", "0(%2)")"\n\t"\
"sll\t%0, 0x8\n\t" \
"or\t%0, $1\n\t" \
"li\t%1, 0\n" \
@@ -472,13 +505,15 @@ extern void show_registers(struct pt_regs *regs);
STR(PTR)"\t2b, 4b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
- : "r" (addr), "i" (-EFAULT));
+ : "r" (addr), "i" (-EFAULT)); \
+} while(0)
#ifndef CONFIG_CPU_MIPSR6
-#define LoadW(addr, value, res) \
+#define _LoadW(addr, value, res, type) \
+do { \
__asm__ __volatile__ ( \
- "1:\t"user_lwl("%0", "3(%2)")"\n" \
- "2:\t"user_lwr("%0", "(%2)")"\n\t" \
+ "1:\t"type##_lwl("%0", "3(%2)")"\n" \
+ "2:\t"type##_lwr("%0", "(%2)")"\n\t"\
"li\t%1, 0\n" \
"3:\n\t" \
".insn\n\t" \
@@ -491,21 +526,24 @@ extern void show_registers(struct pt_regs *regs);
STR(PTR)"\t2b, 4b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
- : "r" (addr), "i" (-EFAULT));
+ : "r" (addr), "i" (-EFAULT)); \
+} while(0)
+
#else
/* MIPSR6 has no lwl instruction */
-#define LoadW(addr, value, res) \
+#define _LoadW(addr, value, res, type) \
+do { \
__asm__ __volatile__ ( \
".set\tpush\n" \
".set\tnoat\n\t" \
- "1:"user_lb("%0", "3(%2)")"\n\t" \
- "2:"user_lbu("$1", "2(%2)")"\n\t" \
+ "1:"type##_lb("%0", "3(%2)")"\n\t" \
+ "2:"type##_lbu("$1", "2(%2)")"\n\t" \
"sll\t%0, 0x8\n\t" \
"or\t%0, $1\n\t" \
- "3:"user_lbu("$1", "1(%2)")"\n\t" \
+ "3:"type##_lbu("$1", "1(%2)")"\n\t" \
"sll\t%0, 0x8\n\t" \
"or\t%0, $1\n\t" \
- "4:"user_lbu("$1", "0(%2)")"\n\t" \
+ "4:"type##_lbu("$1", "0(%2)")"\n\t" \
"sll\t%0, 0x8\n\t" \
"or\t%0, $1\n\t" \
"li\t%1, 0\n" \
@@ -523,15 +561,18 @@ extern void show_registers(struct pt_regs *regs);
STR(PTR)"\t4b, 11b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
- : "r" (addr), "i" (-EFAULT));
+ : "r" (addr), "i" (-EFAULT)); \
+} while(0)
+
#endif /* CONFIG_CPU_MIPSR6 */
-#define LoadHWU(addr, value, res) \
+#define _LoadHWU(addr, value, res, type) \
+do { \
__asm__ __volatile__ ( \
".set\tnoat\n" \
- "1:\t"user_lbu("%0", "1(%2)")"\n" \
- "2:\t"user_lbu("$1", "0(%2)")"\n\t" \
+ "1:\t"type##_lbu("%0", "1(%2)")"\n" \
+ "2:\t"type##_lbu("$1", "0(%2)")"\n\t"\
"sll\t%0, 0x8\n\t" \
"or\t%0, $1\n\t" \
"li\t%1, 0\n" \
@@ -547,13 +588,15 @@ extern void show_registers(struct pt_regs *regs);
STR(PTR)"\t2b, 4b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
- : "r" (addr), "i" (-EFAULT));
+ : "r" (addr), "i" (-EFAULT)); \
+} while(0)
#ifndef CONFIG_CPU_MIPSR6
-#define LoadWU(addr, value, res) \
+#define _LoadWU(addr, value, res, type) \
+do { \
__asm__ __volatile__ ( \
- "1:\t"user_lwl("%0", "3(%2)")"\n" \
- "2:\t"user_lwr("%0", "(%2)")"\n\t" \
+ "1:\t"type##_lwl("%0", "3(%2)")"\n" \
+ "2:\t"type##_lwr("%0", "(%2)")"\n\t"\
"dsll\t%0, %0, 32\n\t" \
"dsrl\t%0, %0, 32\n\t" \
"li\t%1, 0\n" \
@@ -568,9 +611,11 @@ extern void show_registers(struct pt_regs *regs);
STR(PTR)"\t2b, 4b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
- : "r" (addr), "i" (-EFAULT));
+ : "r" (addr), "i" (-EFAULT)); \
+} while(0)
-#define LoadDW(addr, value, res) \
+#define _LoadDW(addr, value, res) \
+do { \
__asm__ __volatile__ ( \
"1:\tldl\t%0, 7(%2)\n" \
"2:\tldr\t%0, (%2)\n\t" \
@@ -586,21 +631,24 @@ extern void show_registers(struct pt_regs *regs);
STR(PTR)"\t2b, 4b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
- : "r" (addr), "i" (-EFAULT));
+ : "r" (addr), "i" (-EFAULT)); \
+} while(0)
+
#else
/* MIPSR6 has not lwl and ldl instructions */
-#define LoadWU(addr, value, res) \
+#define _LoadWU(addr, value, res, type) \
+do { \
__asm__ __volatile__ ( \
".set\tpush\n\t" \
".set\tnoat\n\t" \
- "1:"user_lbu("%0", "3(%2)")"\n\t" \
- "2:"user_lbu("$1", "2(%2)")"\n\t" \
+ "1:"type##_lbu("%0", "3(%2)")"\n\t" \
+ "2:"type##_lbu("$1", "2(%2)")"\n\t" \
"sll\t%0, 0x8\n\t" \
"or\t%0, $1\n\t" \
- "3:"user_lbu("$1", "1(%2)")"\n\t" \
+ "3:"type##_lbu("$1", "1(%2)")"\n\t" \
"sll\t%0, 0x8\n\t" \
"or\t%0, $1\n\t" \
- "4:"user_lbu("$1", "0(%2)")"\n\t" \
+ "4:"type##_lbu("$1", "0(%2)")"\n\t" \
"sll\t%0, 0x8\n\t" \
"or\t%0, $1\n\t" \
"li\t%1, 0\n" \
@@ -618,9 +666,11 @@ extern void show_registers(struct pt_regs *regs);
STR(PTR)"\t4b, 11b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
- : "r" (addr), "i" (-EFAULT));
+ : "r" (addr), "i" (-EFAULT)); \
+} while(0)
-#define LoadDW(addr, value, res) \
+#define _LoadDW(addr, value, res) \
+do { \
__asm__ __volatile__ ( \
".set\tpush\n\t" \
".set\tnoat\n\t" \
@@ -665,15 +715,17 @@ extern void show_registers(struct pt_regs *regs);
STR(PTR)"\t8b, 11b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
- : "r" (addr), "i" (-EFAULT));
+ : "r" (addr), "i" (-EFAULT)); \
+} while(0)
#endif /* CONFIG_CPU_MIPSR6 */
-#define StoreHW(addr, value, res) \
+#define _StoreHW(addr, value, res, type) \
+do { \
__asm__ __volatile__ ( \
".set\tnoat\n" \
- "1:\t"user_sb("%1", "0(%2)")"\n" \
+ "1:\t"type##_sb("%1", "0(%2)")"\n" \
"srl\t$1,%1, 0x8\n" \
- "2:\t"user_sb("$1", "1(%2)")"\n" \
+ "2:\t"type##_sb("$1", "1(%2)")"\n" \
".set\tat\n\t" \
"li\t%0, 0\n" \
"3:\n\t" \
@@ -687,12 +739,15 @@ extern void show_registers(struct pt_regs *regs);
STR(PTR)"\t2b, 4b\n\t" \
".previous" \
: "=r" (res) \
- : "r" (value), "r" (addr), "i" (-EFAULT));
+ : "r" (value), "r" (addr), "i" (-EFAULT));\
+} while(0)
+
#ifndef CONFIG_CPU_MIPSR6
-#define StoreW(addr, value, res) \
+#define _StoreW(addr, value, res, type) \
+do { \
__asm__ __volatile__ ( \
- "1:\t"user_swl("%1", "3(%2)")"\n" \
- "2:\t"user_swr("%1", "(%2)")"\n\t" \
+ "1:\t"type##_swl("%1", "3(%2)")"\n" \
+ "2:\t"type##_swr("%1", "(%2)")"\n\t"\
"li\t%0, 0\n" \
"3:\n\t" \
".insn\n\t" \
@@ -705,9 +760,11 @@ extern void show_registers(struct pt_regs *regs);
STR(PTR)"\t2b, 4b\n\t" \
".previous" \
: "=r" (res) \
- : "r" (value), "r" (addr), "i" (-EFAULT));
+ : "r" (value), "r" (addr), "i" (-EFAULT)); \
+} while(0)
-#define StoreDW(addr, value, res) \
+#define _StoreDW(addr, value, res) \
+do { \
__asm__ __volatile__ ( \
"1:\tsdl\t%1, 7(%2)\n" \
"2:\tsdr\t%1, (%2)\n\t" \
@@ -723,20 +780,23 @@ extern void show_registers(struct pt_regs *regs);
STR(PTR)"\t2b, 4b\n\t" \
".previous" \
: "=r" (res) \
- : "r" (value), "r" (addr), "i" (-EFAULT));
+ : "r" (value), "r" (addr), "i" (-EFAULT)); \
+} while(0)
+
#else
/* MIPSR6 has no swl and sdl instructions */
-#define StoreW(addr, value, res) \
+#define _StoreW(addr, value, res, type) \
+do { \
__asm__ __volatile__ ( \
".set\tpush\n\t" \
".set\tnoat\n\t" \
- "1:"user_sb("%1", "0(%2)")"\n\t" \
+ "1:"type##_sb("%1", "0(%2)")"\n\t" \
"srl\t$1, %1, 0x8\n\t" \
- "2:"user_sb("$1", "1(%2)")"\n\t" \
+ "2:"type##_sb("$1", "1(%2)")"\n\t" \
"srl\t$1, $1, 0x8\n\t" \
- "3:"user_sb("$1", "2(%2)")"\n\t" \
+ "3:"type##_sb("$1", "2(%2)")"\n\t" \
"srl\t$1, $1, 0x8\n\t" \
- "4:"user_sb("$1", "3(%2)")"\n\t" \
+ "4:"type##_sb("$1", "3(%2)")"\n\t" \
".set\tpop\n\t" \
"li\t%0, 0\n" \
"10:\n\t" \
@@ -753,9 +813,11 @@ extern void show_registers(struct pt_regs *regs);
".previous" \
: "=&r" (res) \
: "r" (value), "r" (addr), "i" (-EFAULT) \
- : "memory");
+ : "memory"); \
+} while(0)
-#define StoreDW(addr, value, res) \
+#define _StoreDW(addr, value, res) \
+do { \
__asm__ __volatile__ ( \
".set\tpush\n\t" \
".set\tnoat\n\t" \
@@ -795,10 +857,28 @@ extern void show_registers(struct pt_regs *regs);
".previous" \
: "=&r" (res) \
: "r" (value), "r" (addr), "i" (-EFAULT) \
- : "memory");
+ : "memory"); \
+} while(0)
+
#endif /* CONFIG_CPU_MIPSR6 */
#endif
+#define LoadHWU(addr, value, res) _LoadHWU(addr, value, res, kernel)
+#define LoadHWUE(addr, value, res) _LoadHWU(addr, value, res, user)
+#define LoadWU(addr, value, res) _LoadWU(addr, value, res, kernel)
+#define LoadWUE(addr, value, res) _LoadWU(addr, value, res, user)
+#define LoadHW(addr, value, res) _LoadHW(addr, value, res, kernel)
+#define LoadHWE(addr, value, res) _LoadHW(addr, value, res, user)
+#define LoadW(addr, value, res) _LoadW(addr, value, res, kernel)
+#define LoadWE(addr, value, res) _LoadW(addr, value, res, user)
+#define LoadDW(addr, value, res) _LoadDW(addr, value, res)
+
+#define StoreHW(addr, value, res) _StoreHW(addr, value, res, kernel)
+#define StoreHWE(addr, value, res) _StoreHW(addr, value, res, user)
+#define StoreW(addr, value, res) _StoreW(addr, value, res, kernel)
+#define StoreWE(addr, value, res) _StoreW(addr, value, res, user)
+#define StoreDW(addr, value, res) _StoreDW(addr, value, res)
+
static void emulate_load_store_insn(struct pt_regs *regs,
void __user *addr, unsigned int __user *pc)
{
@@ -870,7 +950,7 @@ static void emulate_load_store_insn(struct pt_regs *regs,
set_fs(seg);
goto sigbus;
}
- LoadHW(addr, value, res);
+ LoadHWE(addr, value, res);
if (res) {
set_fs(seg);
goto fault;
@@ -883,7 +963,7 @@ static void emulate_load_store_insn(struct pt_regs *regs,
set_fs(seg);
goto sigbus;
}
- LoadW(addr, value, res);
+ LoadWE(addr, value, res);
if (res) {
set_fs(seg);
goto fault;
@@ -896,7 +976,7 @@ static void emulate_load_store_insn(struct pt_regs *regs,
set_fs(seg);
goto sigbus;
}
- LoadHWU(addr, value, res);
+ LoadHWUE(addr, value, res);
if (res) {
set_fs(seg);
goto fault;
@@ -911,7 +991,7 @@ static void emulate_load_store_insn(struct pt_regs *regs,
}
compute_return_epc(regs);
value = regs->regs[insn.spec3_format.rt];
- StoreHW(addr, value, res);
+ StoreHWE(addr, value, res);
if (res) {
set_fs(seg);
goto fault;
@@ -924,7 +1004,7 @@ static void emulate_load_store_insn(struct pt_regs *regs,
}
compute_return_epc(regs);
value = regs->regs[insn.spec3_format.rt];
- StoreW(addr, value, res);
+ StoreWE(addr, value, res);
if (res) {
set_fs(seg);
goto fault;
@@ -941,7 +1021,15 @@ static void emulate_load_store_insn(struct pt_regs *regs,
if (!access_ok(VERIFY_READ, addr, 2))
goto sigbus;
- LoadHW(addr, value, res);
+ if (config_enabled(CONFIG_EVA)) {
+ if (segment_eq(get_fs(), get_ds()))
+ LoadHW(addr, value, res);
+ else
+ LoadHWE(addr, value, res);
+ } else {
+ LoadHW(addr, value, res);
+ }
+
if (res)
goto fault;
compute_return_epc(regs);
@@ -952,7 +1040,15 @@ static void emulate_load_store_insn(struct pt_regs *regs,
if (!access_ok(VERIFY_READ, addr, 4))
goto sigbus;
- LoadW(addr, value, res);
+ if (config_enabled(CONFIG_EVA)) {
+ if (segment_eq(get_fs(), get_ds()))
+ LoadW(addr, value, res);
+ else
+ LoadWE(addr, value, res);
+ } else {
+ LoadW(addr, value, res);
+ }
+
if (res)
goto fault;
compute_return_epc(regs);
@@ -963,7 +1059,15 @@ static void emulate_load_store_insn(struct pt_regs *regs,
if (!access_ok(VERIFY_READ, addr, 2))
goto sigbus;
- LoadHWU(addr, value, res);
+ if (config_enabled(CONFIG_EVA)) {
+ if (segment_eq(get_fs(), get_ds()))
+ LoadHWU(addr, value, res);
+ else
+ LoadHWUE(addr, value, res);
+ } else {
+ LoadHWU(addr, value, res);
+ }
+
if (res)
goto fault;
compute_return_epc(regs);
@@ -1022,7 +1126,16 @@ static void emulate_load_store_insn(struct pt_regs *regs,
compute_return_epc(regs);
value = regs->regs[insn.i_format.rt];
- StoreHW(addr, value, res);
+
+ if (config_enabled(CONFIG_EVA)) {
+ if (segment_eq(get_fs(), get_ds()))
+ StoreHW(addr, value, res);
+ else
+ StoreHWE(addr, value, res);
+ } else {
+ StoreHW(addr, value, res);
+ }
+
if (res)
goto fault;
break;
@@ -1033,7 +1146,16 @@ static void emulate_load_store_insn(struct pt_regs *regs,
compute_return_epc(regs);
value = regs->regs[insn.i_format.rt];
- StoreW(addr, value, res);
+
+ if (config_enabled(CONFIG_EVA)) {
+ if (segment_eq(get_fs(), get_ds()))
+ StoreW(addr, value, res);
+ else
+ StoreWE(addr, value, res);
+ } else {
+ StoreW(addr, value, res);
+ }
+
if (res)
goto fault;
break;