arm64: Enable the floating-point exception traps

To enable it user-space needs to call feenableexcept().

FPE_FLTIDO has been added as the IDF bit can't be mapped to any existing
FPE code.

Reviewed by:		andrew@
Differential revision:	https://reviews.freebsd.org/D35247
MFC after:		2 weeks
This commit is contained in:
Dmitry Chagin 2022-05-19 19:53:56 +03:00
parent 2cd662064a
commit 6e2caba7a1
3 changed files with 40 additions and 1 deletions

View File

@ -411,6 +411,29 @@ print_registers(struct trapframe *frame)
printf("spsr: %8x\n", frame->tf_spsr);
}
#ifdef VFP
static void
fpe_trap(struct thread *td, void *addr, uint32_t exception)
{
int code;
code = FPE_FLTIDO;
if ((exception & ISS_FP_TFV) != 0) {
if ((exception & ISS_FP_IOF) != 0)
code = FPE_FLTINV;
else if ((exception & ISS_FP_DZF) != 0)
code = FPE_FLTDIV;
else if ((exception & ISS_FP_OFF) != 0)
code = FPE_FLTOVF;
else if ((exception & ISS_FP_UFF) != 0)
code = FPE_FLTUND;
else if ((exception & ISS_FP_IXF) != 0)
code = FPE_FLTRES;
}
call_trapsignal(td, SIGFPE, code, addr, exception);
}
#endif
void
do_el1h_sync(struct thread *td, struct trapframe *frame)
{
@ -556,11 +579,18 @@ do_el0_sync(struct thread *td, struct trapframe *frame)
switch (exception) {
case EXCP_FP_SIMD:
case EXCP_TRAP_FP:
#ifdef VFP
vfp_restore_state();
#else
panic("VFP exception in userland");
#endif
break;
case EXCP_TRAP_FP:
#ifdef VFP
fpe_trap(td, (void *)frame->tf_elr, esr);
userret(td, frame);
#else
panic("VFP exception in userland");
#endif
break;
case EXCP_SVC32:

View File

@ -265,6 +265,14 @@
/* ESR_ELx */
#define ESR_ELx_ISS_MASK 0x01ffffff
#define ISS_FP_TFV_SHIFT 23
#define ISS_FP_TFV (0x01 << ISS_FP_TFV_SHIFT)
#define ISS_FP_IOF 0x01
#define ISS_FP_DZF 0x02
#define ISS_FP_OFF 0x04
#define ISS_FP_UFF 0x08
#define ISS_FP_IXF 0x10
#define ISS_FP_IDF 0x80
#define ISS_INSN_FnV (0x01 << 10)
#define ISS_INSN_EA (0x01 << 9)
#define ISS_INSN_S1PTW (0x01 << 7)

View File

@ -339,6 +339,7 @@ struct siginfo32 {
#define FPE_FLTRES 6 /* Floating point inexact result. */
#define FPE_FLTINV 7 /* Invalid floating point operation. */
#define FPE_FLTSUB 8 /* Subscript out of range. */
#define FPE_FLTIDO 9 /* Input denormal operation */
/* codes for SIGTRAP */
#define TRAP_BRKPT 1 /* Process breakpoint. */