Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 3 Apr 2019 04:01:08 +0000 (UTC)
From:      Justin Hibbits <jhibbits@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r345831 - in head/sys/powerpc: include powerpc
Message-ID:  <201904030401.x33418h0036251@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201904030401.x33418h0036251>