summaryrefslogtreecommitdiff
path: root/arch/openrisc/kernel/traps.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2023-05-01 11:52:32 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2023-05-01 11:52:32 -0700
commitd75439d64a1e2b35e0f08906205b00279753cbed (patch)
treea1dbe1281ef228f7999cd21ca3380931eacd8dd5 /arch/openrisc/kernel/traps.c
parent3f2a1903af06672f416efd506f029066b9243cbd (diff)
parentc91b4a07655d5ba67962a08dfac8bd7f45ad049c (diff)
downloadlinux-d75439d64a1e2b35e0f08906205b00279753cbed.tar.gz
linux-d75439d64a1e2b35e0f08906205b00279753cbed.tar.bz2
linux-d75439d64a1e2b35e0f08906205b00279753cbed.zip
Merge tag 'for-linus' of https://github.com/openrisc/linux
Pull OpenRISC updates from Stafford Horne: "Two things for OpenRISC this cycle: - Small cleanup for device tree cpu iteration from Rob Herring - Add support for storing, restoring and accessing user space FPU state, to allow for libc to support the FPU on OpenRISC" * tag 'for-linus' of https://github.com/openrisc/linux: openrisc: Add floating point regset openrisc: Support floating point user api openrisc: Support storing and restoring fpu state openrisc: Properly store r31 to pt_regs on unhandled exceptions openrisc: Use common of_get_cpu_node() instead of open-coding
Diffstat (limited to 'arch/openrisc/kernel/traps.c')
-rw-r--r--arch/openrisc/kernel/traps.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/arch/openrisc/kernel/traps.c b/arch/openrisc/kernel/traps.c
index fd9a0f2b66c4..0aa6b07efda1 100644
--- a/arch/openrisc/kernel/traps.c
+++ b/arch/openrisc/kernel/traps.c
@@ -75,8 +75,9 @@ void show_registers(struct pt_regs *regs)
in_kernel = 0;
printk("CPU #: %d\n"
- " PC: %08lx SR: %08lx SP: %08lx\n",
- smp_processor_id(), regs->pc, regs->sr, regs->sp);
+ " PC: %08lx SR: %08lx SP: %08lx FPCSR: %08lx\n",
+ smp_processor_id(), regs->pc, regs->sr, regs->sp,
+ regs->fpcsr);
printk("GPR00: %08lx GPR01: %08lx GPR02: %08lx GPR03: %08lx\n",
0L, regs->gpr[1], regs->gpr[2], regs->gpr[3]);
printk("GPR04: %08lx GPR05: %08lx GPR06: %08lx GPR07: %08lx\n",
@@ -242,6 +243,28 @@ asmlinkage void unhandled_exception(struct pt_regs *regs, int ea, int vector)
die("Oops", regs, 9);
}
+asmlinkage void do_fpe_trap(struct pt_regs *regs, unsigned long address)
+{
+ int code = FPE_FLTUNK;
+ unsigned long fpcsr = regs->fpcsr;
+
+ if (fpcsr & SPR_FPCSR_IVF)
+ code = FPE_FLTINV;
+ else if (fpcsr & SPR_FPCSR_OVF)
+ code = FPE_FLTOVF;
+ else if (fpcsr & SPR_FPCSR_UNF)
+ code = FPE_FLTUND;
+ else if (fpcsr & SPR_FPCSR_DZF)
+ code = FPE_FLTDIV;
+ else if (fpcsr & SPR_FPCSR_IXF)
+ code = FPE_FLTRES;
+
+ /* Clear all flags */
+ regs->fpcsr &= ~SPR_FPCSR_ALLF;
+
+ force_sig_fault(SIGFPE, code, (void __user *)regs->pc);
+}
+
asmlinkage void do_trap(struct pt_regs *regs, unsigned long address)
{
force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->pc);