Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 14 May 2014 04:57:55 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r266005 - in stable/10/sys: conf dev/uart powerpc/aim powerpc/booke powerpc/fpu powerpc/include powerpc/powerpc
Message-ID:  <201405140457.s4E4vt5T011373@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ian
Date: Wed May 14 04:57:55 2014
New Revision: 266005
URL: http://svnweb.freebsd.org/changeset/base/266005

Log:
  MFC r258259, r258798, r259010
  
    Unify handling of illegal instruction faults between AIM and Book-E.
  
    Make uart_cpu_powerpc work on both FDT and OFW systems.
  
    Fix debug printfs in FPU_EMU to compile on powerpc64 and enable it for
    powerpc64.

Modified:
  stable/10/sys/conf/files.powerpc
  stable/10/sys/dev/uart/uart_cpu_powerpc.c
  stable/10/sys/powerpc/aim/trap.c
  stable/10/sys/powerpc/booke/trap.c
  stable/10/sys/powerpc/fpu/fpu_emu.c
  stable/10/sys/powerpc/include/trap.h
  stable/10/sys/powerpc/powerpc/exec_machdep.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/conf/files.powerpc
==============================================================================
--- stable/10/sys/conf/files.powerpc	Wed May 14 04:42:38 2014	(r266004)
+++ stable/10/sys/conf/files.powerpc	Wed May 14 04:57:55 2014	(r266005)
@@ -65,8 +65,7 @@ dev/syscons/scterm-teken.c	optional	sc
 dev/syscons/scvtb.c		optional	sc
 dev/tsec/if_tsec.c		optional	tsec
 dev/tsec/if_tsec_fdt.c		optional	tsec fdt
-dev/uart/uart_cpu_fdt.c		optional	uart fdt
-dev/uart/uart_cpu_powerpc.c	optional	uart aim
+dev/uart/uart_cpu_powerpc.c	optional	uart
 dev/usb/controller/ehci_fsl.c	optional	ehci mpc85xx
 dev/vt/hw/ofwfb/ofwfb.c		optional	vt aim
 kern/kern_clocksource.c		standard
@@ -111,15 +110,15 @@ powerpc/booke/trap.c		optional	booke
 powerpc/cpufreq/dfs.c		optional	cpufreq
 powerpc/cpufreq/pcr.c		optional	cpufreq aim
 powerpc/cpufreq/pmufreq.c	optional	cpufreq aim pmu
-powerpc/fpu/fpu_add.c		optional	fpu_emu powerpc
-powerpc/fpu/fpu_compare.c	optional	fpu_emu powerpc
-powerpc/fpu/fpu_div.c		optional	fpu_emu powerpc
-powerpc/fpu/fpu_emu.c		optional	fpu_emu powerpc
-powerpc/fpu/fpu_explode.c	optional	fpu_emu powerpc
-powerpc/fpu/fpu_implode.c	optional	fpu_emu powerpc
-powerpc/fpu/fpu_mul.c		optional	fpu_emu powerpc
-powerpc/fpu/fpu_sqrt.c		optional	fpu_emu powerpc
-powerpc/fpu/fpu_subr.c		optional	fpu_emu powerpc
+powerpc/fpu/fpu_add.c		optional	fpu_emu
+powerpc/fpu/fpu_compare.c	optional	fpu_emu
+powerpc/fpu/fpu_div.c		optional	fpu_emu
+powerpc/fpu/fpu_emu.c		optional	fpu_emu
+powerpc/fpu/fpu_explode.c	optional	fpu_emu
+powerpc/fpu/fpu_implode.c	optional	fpu_emu
+powerpc/fpu/fpu_mul.c		optional	fpu_emu
+powerpc/fpu/fpu_sqrt.c		optional	fpu_emu
+powerpc/fpu/fpu_subr.c		optional	fpu_emu
 powerpc/mambo/mambocall.S	optional	mambo
 powerpc/mambo/mambo.c		optional	mambo
 powerpc/mambo/mambo_console.c	optional	mambo

Modified: stable/10/sys/dev/uart/uart_cpu_powerpc.c
==============================================================================
--- stable/10/sys/dev/uart/uart_cpu_powerpc.c	Wed May 14 04:42:38 2014	(r266004)
+++ stable/10/sys/dev/uart/uart_cpu_powerpc.c	Wed May 14 04:57:55 2014	(r266005)
@@ -61,42 +61,96 @@ ofw_get_uart_console(phandle_t opts, pha
 	input = OF_finddevice(buf);
 	if (input == -1)
 		return (ENXIO);
-	if (OF_getprop(opts, outputdev, buf, sizeof(buf)) == -1)
-		return (ENXIO);
-	if (OF_finddevice(buf) != input)
-		return (ENXIO);
+
+	if (outputdev != NULL) {
+		if (OF_getprop(opts, outputdev, buf, sizeof(buf)) == -1)
+			return (ENXIO);
+		if (OF_finddevice(buf) != input)
+			return (ENXIO);
+	}
 
 	*result = input;
 	return (0);
 }
 
+static int
+ofw_get_console_phandle_path(phandle_t node, phandle_t *result,
+    const char *prop)
+{
+	union {
+		char buf[64];
+		phandle_t ref;
+	} field;
+	phandle_t output;
+	ssize_t size;
+
+	size = OF_getproplen(node, prop);
+	if (size == -1)
+		return (ENXIO);
+	OF_getprop(node, prop, &field, sizeof(field));
+
+	/* This property might be a phandle or might be a path. Hooray. */
+
+	output = -1;
+	if (field.buf[size - 1] == 0)
+		output = OF_finddevice(field.buf);
+	if (output == -1 && size == 4)
+		output = OF_xref_phandle(field.ref);
+	
+	if (output != -1) {
+		*result = output;
+		return (0);
+	}
+
+	return (ENXIO);
+}
+
 int
 uart_cpu_getdev(int devtype, struct uart_devinfo *di)
 {
 	char buf[64];
 	struct uart_class *class;
-	phandle_t input, opts;
+	phandle_t input, opts, chosen;
 	int error;
 
 	class = &uart_z8530_class;
 	if (class == NULL)
 		return (ENXIO);
 
-	if ((opts = OF_finddevice("/options")) == -1)
-		return (ENXIO);
+	opts = OF_finddevice("/options");
+	chosen = OF_finddevice("/chosen");
 	switch (devtype) {
 	case UART_DEV_CONSOLE:
-		if (ofw_get_uart_console(opts, &input, "input-device",
-		    "output-device")) {
-			/*
-			 * At least some G5 Xserves require that we
-			 * probe input-device-1 as well
-			 */
-	
-			if (ofw_get_uart_console(opts, &input, "input-device-1",
-			    "output-device-1"))
-				return (ENXIO);
+		error = ENXIO;
+		if (chosen != -1 && error != 0)
+			error = ofw_get_uart_console(chosen, &input,
+			    "stdout-path", NULL);
+		if (chosen != -1 && error != 0)
+			error = ofw_get_uart_console(chosen, &input,
+			    "linux,stdout-path", NULL);
+		if (chosen != -1 && error != 0)
+			error = ofw_get_console_phandle_path(chosen, &input,
+			    "stdout");
+		if (chosen != -1 && error != 0)
+			error = ofw_get_uart_console(chosen, &input,
+			    "stdin-path", NULL);
+		if (chosen != -1 && error != 0)
+			error = ofw_get_console_phandle_path(chosen, &input,
+			    "stdin");
+		if (opts != -1 && error != 0)
+			error = ofw_get_uart_console(opts, &input,
+			    "input-device", "output-device");
+		if (opts != -1 && error != 0)
+			error = ofw_get_uart_console(opts, &input,
+			    "input-device-1", "output-device-1");
+		if (error != 0) {
+			input = OF_finddevice("serial0"); /* Last ditch */
+			if (input == -1)
+				error = (ENXIO);
 		}
+
+		if (error != 0)
+			return (error);
 		break;
 	case UART_DEV_DBGPORT:
 		if (!getenv_string("hw.uart.dbgport", buf, sizeof(buf)))
@@ -113,14 +167,14 @@ uart_cpu_getdev(int devtype, struct uart
 		return (ENXIO);
 	if (strcmp(buf, "serial") != 0)
 		return (ENXIO);
-	if (OF_getprop(input, "name", buf, sizeof(buf)) == -1)
+	if (OF_getprop(input, "compatible", buf, sizeof(buf)) == -1)
 		return (ENXIO);
 
-	if (strcmp(buf, "ch-a") == 0) {
+	if (strncmp(buf, "chrp,es", 7) == 0) {
 		class = &uart_z8530_class;
 		di->bas.regshft = 4;
 		di->bas.chan = 1;
-	} else if (strcmp(buf,"serial") == 0) {
+	} else if (strcmp(buf,"ns16550") == 0 || strcmp(buf,"ns8250") == 0) {
 		class = &uart_ns8250_class;
 		di->bas.regshft = 0;
 		di->bas.chan = 0;
@@ -139,9 +193,12 @@ uart_cpu_getdev(int devtype, struct uart
 	if (OF_getprop(input, "current-speed", &di->baudrate, 
 	    sizeof(di->baudrate)) == -1)
 		di->baudrate = 0;
+	OF_getprop(input, "reg-shift", &di->bas.regshft,
+	    sizeof(di->bas.regshft));
 
 	di->databits = 8;
 	di->stopbits = 1;
 	di->parity = UART_PARITY_NONE;
 	return (0);
 }
+

Modified: stable/10/sys/powerpc/aim/trap.c
==============================================================================
--- stable/10/sys/powerpc/aim/trap.c	Wed May 14 04:42:38 2014	(r266004)
+++ stable/10/sys/powerpc/aim/trap.c	Wed May 14 04:57:55 2014	(r266005)
@@ -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: stable/10/sys/powerpc/booke/trap.c
==============================================================================
--- stable/10/sys/powerpc/booke/trap.c	Wed May 14 04:42:38 2014	(r266004)
+++ stable/10/sys/powerpc/booke/trap.c	Wed May 14 04:57:55 2014	(r266005)
@@ -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: stable/10/sys/powerpc/fpu/fpu_emu.c
==============================================================================
--- stable/10/sys/powerpc/fpu/fpu_emu.c	Wed May 14 04:42:38 2014	(r266004)
+++ stable/10/sys/powerpc/fpu/fpu_emu.c	Wed May 14 04:57:55 2014	(r266005)
@@ -326,8 +326,10 @@ fpu_execute(struct trapframe *tf, struct
 				/* Store as integer */
 				ra = instr.i_x.i_ra;
 				rb = instr.i_x.i_rb;
-				DPRINTF(FPE_INSN, ("reg %d has %x reg %d has %x\n",
-					ra, tf->fixreg[ra], rb, tf->fixreg[rb]));
+				DPRINTF(FPE_INSN,
+					("reg %d has %jx reg %d has %jx\n",
+					ra, (uintmax_t)tf->fixreg[ra], rb,
+					(uintmax_t)tf->fixreg[rb]));
 
 				addr = tf->fixreg[rb];
 				if (ra != 0)
@@ -356,8 +358,9 @@ fpu_execute(struct trapframe *tf, struct
 			/* calculate EA of load/store */
 			ra = instr.i_x.i_ra;
 			rb = instr.i_x.i_rb;
-			DPRINTF(FPE_INSN, ("reg %d has %x reg %d has %x\n",
-				ra, tf->fixreg[ra], rb, tf->fixreg[rb]));
+			DPRINTF(FPE_INSN, ("reg %d has %jx reg %d has %jx\n",
+				ra, (uintmax_t)tf->fixreg[ra], rb,
+				(uintmax_t)tf->fixreg[rb]));
 			addr = tf->fixreg[rb];
 			if (ra != 0)
 				addr += tf->fixreg[ra];
@@ -373,8 +376,9 @@ fpu_execute(struct trapframe *tf, struct
 			/* calculate EA of load/store */
 			ra = instr.i_d.i_ra;
 			addr = instr.i_d.i_d;
-			DPRINTF(FPE_INSN, ("reg %d has %x displ %x\n",
-				ra, tf->fixreg[ra], addr));
+			DPRINTF(FPE_INSN, ("reg %d has %jx displ %jx\n",
+				ra, (uintmax_t)tf->fixreg[ra],
+				(uintmax_t)addr));
 			if (ra != 0)
 				addr += tf->fixreg[ra];
 			rt = instr.i_d.i_rt;
@@ -420,7 +424,7 @@ fpu_execute(struct trapframe *tf, struct
 		return (0);
 #ifdef notyet
 	} else if (instr.i_any.i_opcd == OPC_load_st_62) {
-		/* These are 64-bit extenstions */
+		/* These are 64-bit extensions */
 		return (NOTFPU);
 #endif
 	} else if (instr.i_any.i_opcd == OPC_sp_fp_59 ||
@@ -784,7 +788,8 @@ fpu_execute(struct trapframe *tf, struct
 		/* Move fpu condition codes to cr[1] */
 		tf->cr &= ~(0xf0000000>>bf);
 		tf->cr |= (cond>>bf);
-		DPRINTF(FPE_INSN, ("fpu_execute: cr[%d] (cr=%x) <= %x\n", bf/4, tf->cr, cond));
+		DPRINTF(FPE_INSN, ("fpu_execute: cr[%d] (cr=%jx) <= %x\n",
+			bf/4, (uintmax_t)tf->cr, cond));
 	}
 
 	((int *)&fs->fpscr)[1] = fsr;

Modified: stable/10/sys/powerpc/include/trap.h
==============================================================================
--- stable/10/sys/powerpc/include/trap.h	Wed May 14 04:42:38 2014	(r266004)
+++ stable/10/sys/powerpc/include/trap.h	Wed May 14 04:57:55 2014	(r266005)
@@ -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: stable/10/sys/powerpc/powerpc/exec_machdep.c
==============================================================================
--- stable/10/sys/powerpc/powerpc/exec_machdep.c	Wed May 14 04:42:38 2014	(r266004)
+++ stable/10/sys/powerpc/powerpc/exec_machdep.c	Wed May 14 04:57:55 2014	(r266005)
@@ -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);
+}
+



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