diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-05-01 11:52:32 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-05-01 11:52:32 -0700 |
| commit | d75439d64a1e2b35e0f08906205b00279753cbed (patch) | |
| tree | a1dbe1281ef228f7999cd21ca3380931eacd8dd5 /arch/openrisc/kernel/traps.c | |
| parent | 3f2a1903af06672f416efd506f029066b9243cbd (diff) | |
| parent | c91b4a07655d5ba67962a08dfac8bd7f45ad049c (diff) | |
| download | linux-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.c | 27 |
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); |
