summaryrefslogtreecommitdiff
path: root/arch/arc/kernel/fpu.c
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2020-01-18 02:04:03 +0300
committerVineet Gupta <vgupta@synopsys.com>2020-01-18 03:53:44 +0300
commitf45ba2bd6da0dc8000aa7ea7a3858fb51608f766 (patch)
tree3be8113cb45459531bc5ffee5bbbb1de38d5d234 /arch/arc/kernel/fpu.c
parentf05523aa7a1e63bfada5e222c0a57e02dbd4fcfa (diff)
downloadlinux-f45ba2bd6da0dc8000aa7ea7a3858fb51608f766.tar.xz
ARCv2: fpu: preserve userspace fpu state
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Diffstat (limited to 'arch/arc/kernel/fpu.c')
-rw-r--r--arch/arc/kernel/fpu.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/arch/arc/kernel/fpu.c b/arch/arc/kernel/fpu.c
index 7a3b56ce56bb..c67c0f0f5f77 100644
--- a/arch/arc/kernel/fpu.c
+++ b/arch/arc/kernel/fpu.c
@@ -8,6 +8,8 @@
#include <linux/sched.h>
#include <asm/fpu.h>
+#ifdef CONFIG_ISA_ARCOMPACT
+
/*
* To save/restore FPU regs, simplest scheme would use LR/SR insns.
* However since SR serializes the pipeline, an alternate "hack" can be used
@@ -50,3 +52,28 @@ void fpu_save_restore(struct task_struct *prev, struct task_struct *next)
: "r" (zero), "r" (*(readfrom + 3)), "r" (*(readfrom + 2))
);
}
+
+#else
+
+void fpu_init_task(struct pt_regs *regs)
+{
+ /* default rounding mode */
+ write_aux_reg(ARC_REG_FPU_CTRL, 0x100);
+
+ /* set "Write enable" to allow explicit write to exception flags */
+ write_aux_reg(ARC_REG_FPU_STATUS, 0x80000000);
+}
+
+void fpu_save_restore(struct task_struct *prev, struct task_struct *next)
+{
+ struct arc_fpu *save = &prev->thread.fpu;
+ struct arc_fpu *restore = &next->thread.fpu;
+
+ save->ctrl = read_aux_reg(ARC_REG_FPU_CTRL);
+ save->status = read_aux_reg(ARC_REG_FPU_STATUS);
+
+ write_aux_reg(ARC_REG_FPU_CTRL, restore->ctrl);
+ write_aux_reg(ARC_REG_FPU_STATUS, restore->status);
+}
+
+#endif