svn commit: r258259 - in head/sys/powerpc: aim booke include powerpc

Nathan Whitehorn nwhitehorn at FreeBSD.org
Sun Nov 17 15:12:05 UTC 2013


Author: nwhitehorn
Date: Sun Nov 17 15:12:03 2013
New Revision: 258259
URL: http://svnweb.freebsd.org/changeset/base/258259

Log:
  Unify handling of illegal instruction faults between AIM and Book-E. This
  allows FPU emulation on AIM as well as providing support for the mfpvr
  and lwsync instructions from userland on e500 cores. lwsync, in particular,
  is required for many C++ programs to work correctly.
  
  MFC after:	1 week

Modified:
  head/sys/powerpc/aim/trap.c
  head/sys/powerpc/booke/trap.c
  head/sys/powerpc/include/trap.h
  head/sys/powerpc/powerpc/exec_machdep.c

Modified: head/sys/powerpc/aim/trap.c
==============================================================================
--- head/sys/powerpc/aim/trap.c	Sun Nov 17 15:09:39 2013	(r258258)
+++ head/sys/powerpc/aim/trap.c	Sun Nov 17 15:12:03 2013	(r258259)
@@ -80,7 +80,6 @@ static void	printtrap(u_int vector, stru
 		    int user);
 static int	trap_pfault(struct trapframe *frame, int user);
 static int	fix_unaligned(struct thread *td, struct trapframe *frame);
-static int	ppc_instr_emulate(struct trapframe *frame);
 static int	handle_onfault(struct trapframe *frame);
 static void	syscall(struct trapframe *frame);
 
@@ -292,10 +291,9 @@ trap(struct trapframe *frame)
 				}
 #endif
  				sig = SIGTRAP;
-			} else if (ppc_instr_emulate(frame) == 0)
-				frame->srr0 += 4;
-			else
-				sig = SIGILL;
+			} else {
+				sig = ppc_instr_emulate(frame, td->td_pcb);
+			}
 			break;
 
 		default:
@@ -800,20 +798,3 @@ fix_unaligned(struct thread *td, struct 
 	return -1;
 }
 
-static int
-ppc_instr_emulate(struct trapframe *frame)
-{
-	uint32_t instr;
-	int reg;
-
-	instr = fuword32((void *)frame->srr0);
-
-	if ((instr & 0xfc1fffff) == 0x7c1f42a6) {	/* mfpvr */
-		reg = (instr & ~0xfc1fffff) >> 21;
-		frame->fixreg[reg] = mfpvr();
-		return (0);
-	}
-
-	return (-1);
-}
-

Modified: head/sys/powerpc/booke/trap.c
==============================================================================
--- head/sys/powerpc/booke/trap.c	Sun Nov 17 15:09:39 2013	(r258258)
+++ head/sys/powerpc/booke/trap.c	Sun Nov 17 15:12:03 2013	(r258259)
@@ -71,10 +71,6 @@ __FBSDID("$FreeBSD$");
 #include <machine/trap.h>
 #include <machine/spr.h>
 
-#ifdef FPU_EMU
-#include <powerpc/fpu/fpu_extern.h>
-#endif
-
 #define	FAULTBUF_LR	0
 #define	FAULTBUF_R1	1
 #define	FAULTBUF_R2	2
@@ -193,18 +189,7 @@ trap(struct trapframe *frame)
 			break;
 
 		case EXC_PGM:	/* Program exception */
-#ifdef FPU_EMU
-			if (!(td->td_pcb->pcb_flags & PCB_FPREGS)) {
-				bzero(&td->td_pcb->pcb_fpu,
-				    sizeof(td->td_pcb->pcb_fpu));
-				td->td_pcb->pcb_flags |= PCB_FPREGS;
-			}
-			sig = fpu_emulate(frame,
-			    (struct fpreg *)&td->td_pcb->pcb_fpu);
-#else
-			/* XXX SIGILL for non-trap instructions. */
-			sig = SIGTRAP;
-#endif
+			sig = ppc_instr_emulate(frame, td->td_pcb);
 			break;
 
 		default:

Modified: head/sys/powerpc/include/trap.h
==============================================================================
--- head/sys/powerpc/include/trap.h	Sun Nov 17 15:09:39 2013	(r258258)
+++ head/sys/powerpc/include/trap.h	Sun Nov 17 15:12:03 2013	(r258259)
@@ -122,7 +122,9 @@
 
 #ifndef LOCORE
 struct	trapframe;
+struct	pcb;
 void    trap(struct trapframe *);
+int	ppc_instr_emulate(struct trapframe *, struct pcb *);
 #endif
 
 #endif	/* _POWERPC_TRAP_H_ */

Modified: head/sys/powerpc/powerpc/exec_machdep.c
==============================================================================
--- head/sys/powerpc/powerpc/exec_machdep.c	Sun Nov 17 15:09:39 2013	(r258258)
+++ head/sys/powerpc/powerpc/exec_machdep.c	Sun Nov 17 15:12:03 2013	(r258259)
@@ -58,6 +58,7 @@
 __FBSDID("$FreeBSD$");
 
 #include "opt_compat.h"
+#include "opt_fpu_emu.h"
 
 #include <sys/param.h>
 #include <sys/proc.h>
@@ -92,6 +93,10 @@ __FBSDID("$FreeBSD$");
 #include <machine/trap.h>
 #include <machine/vmparam.h>
 
+#ifdef FPU_EMU
+#include <powerpc/fpu/fpu_extern.h>
+#endif
+
 #ifdef COMPAT_FREEBSD32
 #include <compat/freebsd32/freebsd32_signal.h>
 #include <compat/freebsd32/freebsd32_util.h>
@@ -1038,3 +1043,36 @@ cpu_set_upcall_kse(struct thread *td, vo
 	td->td_retval[1] = 0;
 }
 
+int
+ppc_instr_emulate(struct trapframe *frame, struct pcb *pcb)
+{
+	uint32_t instr;
+	int reg, sig;
+
+	instr = fuword32((void *)frame->srr0);
+	sig = SIGILL;
+
+	if ((instr & 0xfc1fffff) == 0x7c1f42a6) {	/* mfpvr */
+		reg = (instr & ~0xfc1fffff) >> 21;
+		frame->fixreg[reg] = mfpvr();
+		frame->srr0 += 4;
+		return (0);
+	}
+
+	if ((instr & 0xfc000ffe) == 0x7c0004ac) {	/* various sync */
+		powerpc_sync(); /* Do a heavy-weight sync */
+		frame->srr0 += 4;
+		return (0);
+	}
+
+#ifdef FPU_EMU
+	if (!(pcb->pcb_flags & PCB_FPREGS)) {
+		bzero(&pcb->pcb_fpu, sizeof(pcb->pcb_fpu));
+		pcb->pcb_flags |= PCB_FPREGS;
+	}
+	sig = fpu_emulate(frame, (struct fpreg *)&pcb->pcb_fpu);
+#endif
+
+	return (sig);
+}
+


More information about the svn-src-all mailing list