svn commit: r345831 - in head/sys/powerpc: include powerpc
Justin Hibbits
jhibbits at FreeBSD.org
Wed Apr 3 04:01:10 UTC 2019
Author: jhibbits
Date: Wed Apr 3 04:01:08 2019
New Revision: 345831
URL: https://svnweb.freebsd.org/changeset/base/345831
Log:
powerpc: Allow emulating optional FPU instructions on CPUs with an FPU
The e5500 has an FPU, but lacks the optional fsqrt instruction. This
instruction gets emulated in the kernel, but the emulation uses stale data,
from the last switch out, and does not return the result of the operation
immediately. Fix both of these conditions by saving and restoring the FPRs
around the emulation point.
MFC after: 1 week
MFC with: r345829
Modified:
head/sys/powerpc/include/trap.h
head/sys/powerpc/powerpc/exec_machdep.c
head/sys/powerpc/powerpc/trap.c
Modified: head/sys/powerpc/include/trap.h
==============================================================================
--- head/sys/powerpc/include/trap.h Wed Apr 3 03:57:37 2019 (r345830)
+++ head/sys/powerpc/include/trap.h Wed Apr 3 04:01:08 2019 (r345831)
@@ -152,10 +152,10 @@
#ifndef LOCORE
struct trapframe;
-struct pcb;
+struct thread;
extern int (*hmi_handler)(struct trapframe *);
void trap(struct trapframe *);
-int ppc_instr_emulate(struct trapframe *, struct pcb *);
+int ppc_instr_emulate(struct trapframe *, struct thread *);
#endif
#endif /* _POWERPC_TRAP_H_ */
Modified: head/sys/powerpc/powerpc/exec_machdep.c
==============================================================================
--- head/sys/powerpc/powerpc/exec_machdep.c Wed Apr 3 03:57:37 2019 (r345830)
+++ head/sys/powerpc/powerpc/exec_machdep.c Wed Apr 3 04:01:08 2019 (r345831)
@@ -1081,8 +1081,9 @@ emulate_mtspr(int spr, int reg, struct trapframe *fram
#define XFX 0xFC0007FF
int
-ppc_instr_emulate(struct trapframe *frame, struct pcb *pcb)
+ppc_instr_emulate(struct trapframe *frame, struct thread *td)
{
+ struct pcb *pcb;
uint32_t instr;
int reg, sig;
int rs, spr;
@@ -1109,12 +1110,16 @@ ppc_instr_emulate(struct trapframe *frame, struct pcb
return (0);
}
+ pcb = td->td_pcb;
#ifdef FPU_EMU
if (!(pcb->pcb_flags & PCB_FPREGS)) {
bzero(&pcb->pcb_fpu, sizeof(pcb->pcb_fpu));
pcb->pcb_flags |= PCB_FPREGS;
- }
+ } else if (pcb->pcb_flags & PCB_FPU)
+ save_fpu(td);
sig = fpu_emulate(frame, &pcb->pcb_fpu);
+ if ((sig == 0 || sig == SIGFPE) && pcb->pcb_flags & PCB_FPU)
+ enable_fpu(td);
#endif
if (sig == SIGILL) {
if (pcb->pcb_lastill != frame->srr0) {
Modified: head/sys/powerpc/powerpc/trap.c
==============================================================================
--- head/sys/powerpc/powerpc/trap.c Wed Apr 3 03:57:37 2019 (r345830)
+++ head/sys/powerpc/powerpc/trap.c Wed Apr 3 04:01:08 2019 (r345831)
@@ -363,7 +363,7 @@ trap(struct trapframe *frame)
sig = SIGTRAP;
ucode = TRAP_BRKPT;
} else {
- sig = ppc_instr_emulate(frame, td->td_pcb);
+ sig = ppc_instr_emulate(frame, td);
if (sig == SIGILL) {
if (frame->srr1 & EXC_PGM_PRIV)
ucode = ILL_PRVOPC;
More information about the svn-src-all
mailing list