Module Name:    src
Committed By:   matt
Date:           Thu Feb 17 13:53:33 UTC 2011

Modified Files:
        src/sys/arch/powerpc/booke: booke_machdep.c copyin.c trap.c
        src/sys/arch/powerpc/include: userret.h
        src/sys/arch/powerpc/include/booke: cpuvar.h

Log Message:
add begging of single step support.  Since BookE doesn't support PSL_SE, if
userret find PSL_SE set in SRR1, it will call booke_sstep to setup the
debug registers.


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/powerpc/booke/booke_machdep.c
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/powerpc/booke/copyin.c
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/powerpc/booke/trap.c
cvs rdiff -u -r1.17 -r1.18 src/sys/arch/powerpc/include/userret.h
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/powerpc/include/booke/cpuvar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/powerpc/booke/booke_machdep.c
diff -u src/sys/arch/powerpc/booke/booke_machdep.c:1.3 src/sys/arch/powerpc/booke/booke_machdep.c:1.4
--- src/sys/arch/powerpc/booke/booke_machdep.c:1.3	Wed Feb 16 18:44:54 2011
+++ src/sys/arch/powerpc/booke/booke_machdep.c	Thu Feb 17 13:53:32 2011
@@ -50,7 +50,9 @@
 
 #include <uvm/uvm_extern.h>
 
-#include <powerpc/altivec.h>
+#include <powerpc/spr.h>
+#include <powerpc/booke/spr.h>
+#include <powerpc/booke/cpuvar.h>
 
 /*
  * Global variables used here and there
@@ -442,3 +444,37 @@
 	struct cpu_softc * const cpu = curcpu()->ci_softc;
 	bus_space_write_1(cpu->cpu_bst, cpu->cpu_bsh, a, v);
 }
+
+void
+booke_sstep(struct trapframe *tf)
+{
+	KASSERT(tf->tf_srr1 & PSL_DE);
+	const uint32_t insn = ufetch_32((const void *)tf->tf_srr0);
+	register_t dbcr0 = DBCR0_IAC1 | DBCR0_IDM;
+	register_t dbcr1 = DBCR1_IAC1US_USER | DBCR1_IAC1ER_DS1;
+	if ((insn >> 28) == 4) {
+		uint32_t iac2 = 0;
+		if ((insn >> 26) == 0x12) {
+			const int32_t off = (((int32_t)insn << 6) >> 6) & ~3;
+			iac2 = ((insn & 2) ? 0 : tf->tf_srr0) + off;
+			dbcr0 |= DBCR0_IAC2;
+		} else if ((insn >> 26) == 0x10) {
+			const int16_t off = insn & ~3;
+			iac2 = ((insn & 2) ? 0 : tf->tf_srr0) + off;
+			dbcr0 |= DBCR0_IAC2;
+		} else if ((insn & 0xfc00ffde) == 0x4c000420) {
+			iac2 = tf->tf_ctr;
+			dbcr0 |= DBCR0_IAC2;
+		} else if ((insn & 0xfc00ffde) == 0x4c000020) {
+			iac2 = tf->tf_lr;
+			dbcr0 |= DBCR0_IAC2;
+		}
+		if (dbcr0 & DBCR0_IAC2) {
+			dbcr1 |= DBCR1_IAC2US_USER | DBCR1_IAC2ER_DS1;
+			mtspr(SPR_IAC2, iac2);
+		}
+	}
+	mtspr(SPR_IAC1, tf->tf_srr0 + 4);
+	mtspr(SPR_DBCR1, dbcr1);
+	mtspr(SPR_DBCR0, dbcr0);
+}

Index: src/sys/arch/powerpc/booke/copyin.c
diff -u src/sys/arch/powerpc/booke/copyin.c:1.2 src/sys/arch/powerpc/booke/copyin.c:1.3
--- src/sys/arch/powerpc/booke/copyin.c:1.2	Tue Jan 18 01:02:52 2011
+++ src/sys/arch/powerpc/booke/copyin.c	Thu Feb 17 13:53:32 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: copyin.c,v 1.2 2011/01/18 01:02:52 matt Exp $	*/
+/*	$NetBSD: copyin.c,v 1.3 2011/02/17 13:53:32 matt Exp $	*/
 
 /*-
  * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
@@ -36,13 +36,15 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: copyin.c,v 1.2 2011/01/18 01:02:52 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: copyin.c,v 1.3 2011/02/17 13:53:32 matt Exp $");
 
 #include <sys/param.h>
 #include <sys/lwp.h>
 
 #include <machine/pcb.h>
 
+#include <powerpc/booke/cpuvar.h>
+
 static inline uint8_t
 copyin_byte(const uint8_t * const usaddr8, register_t ds_msr)
 {
@@ -195,6 +197,24 @@
 	}
 }
 
+uint32_t
+ufetch_32(const void *vusaddr)
+{
+	struct pcb * const pcb = lwp_getpcb(curlwp);
+	struct faultbuf env;
+
+	if (setfault(&env) != 0) {
+		pcb->pcb_onfault = NULL;
+		return -1;
+	}
+
+	uint32_t rv = copyin_word(vusaddr, mfmsr() | PSL_DS);
+
+	pcb->pcb_onfault = NULL;
+
+	return rv;
+}
+
 int
 copyin(const void *vusaddr, void *vkdaddr, size_t len)
 {

Index: src/sys/arch/powerpc/booke/trap.c
diff -u src/sys/arch/powerpc/booke/trap.c:1.4 src/sys/arch/powerpc/booke/trap.c:1.5
--- src/sys/arch/powerpc/booke/trap.c:1.4	Tue Feb  8 01:38:48 2011
+++ src/sys/arch/powerpc/booke/trap.c	Thu Feb 17 13:53:32 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: trap.c,v 1.4 2011/02/08 01:38:48 matt Exp $	*/
+/*	$NetBSD: trap.c,v 1.5 2011/02/17 13:53:32 matt Exp $	*/
 /*-
  * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -39,7 +39,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.4 2011/02/08 01:38:48 matt Exp $");
+__KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.5 2011/02/17 13:53:32 matt Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -64,6 +64,7 @@
 
 #include <powerpc/spr.h>
 #include <powerpc/booke/spr.h>
+#include <powerpc/booke/cpuvar.h>
 
 #include <powerpc/db_machdep.h>
 #include <ddb/db_interface.h>
@@ -450,7 +451,9 @@
 			tf->tf_srr0 += 4;
 			return 0;
 		}
-	} else if (tf->tf_esr & (ESR_PIL|ESR_PPR)) {
+	}
+
+	if (tf->tf_esr & (ESR_PIL|ESR_PPR)) {
 		if (emulate_opcode(tf, ksi)) {
 			tf->tf_srr0 += 4;
 			return 0;
@@ -475,6 +478,41 @@
 }
 
 static int
+debug_exception(struct trapframe *tf, ksiginfo_t *ksi)
+{
+	struct cpu_info * const ci = curcpu();
+	int rv = EPERM;
+
+	if (!usertrap_p(tf))
+		return rv;
+
+	ci->ci_ev_debug.ev_count++;
+
+	/*
+	 * Ack the interrupt.
+	 */
+	mtspr(SPR_DBSR, tf->tf_esr);
+	KASSERT(tf->tf_esr & (DBSR_IAC1|DBSR_IAC2));
+	KASSERT((tf->tf_srr1 & PSL_SE) == 0);
+
+	/*
+	 * Disable debug events
+	 */
+	mtspr(SPR_DBCR1, 0);
+	mtspr(SPR_DBCR0, 0);
+
+	/*
+	 * Tell the debugger ...
+	 */
+	KSI_INIT_TRAP(ksi);
+	ksi->ksi_signo = SIGTRAP;
+	ksi->ksi_trap = EXC_TRC;
+	ksi->ksi_addr = (void *)tf->tf_srr0;
+	ksi->ksi_code = TRAP_TRACE;
+	return rv;
+}
+
+static int
 ali_exception(struct trapframe *tf, ksiginfo_t *ksi)
 {
 	struct cpu_info * const ci = curcpu();
@@ -578,6 +616,7 @@
 	}
 	return false;
 #else
+#if 0
 	struct cpu_info * const ci = curcpu();
 	struct cpu_softc * const cpu = ci->ci_softc;
 	printf("CPL stack:");
@@ -588,6 +627,7 @@
 	}
 	printf(" %u\n", ci->ci_cpl);
 	dump_trapframe(tf);
+#endif
 	if (kdb_trap(tf->tf_exc, tf)) {
 		tf->tf_srr0 += 4;
 		return true;
@@ -713,6 +753,12 @@
 		rv = itlb_exception(tf, &ksi);
 		break;
 	case T_DEBUG:
+#ifdef DDB
+		if (!usertrap && ddb_exception(tf))
+			return;
+#endif
+		rv = debug_exception(tf, &ksi);
+		break;
 	case T_EMBEDDED_FP_DATA:
 		rv = embedded_fp_data_exception(tf, &ksi);
 		break;

Index: src/sys/arch/powerpc/include/userret.h
diff -u src/sys/arch/powerpc/include/userret.h:1.17 src/sys/arch/powerpc/include/userret.h:1.18
--- src/sys/arch/powerpc/include/userret.h:1.17	Tue Jan 18 01:02:54 2011
+++ src/sys/arch/powerpc/include/userret.h	Thu Feb 17 13:53:32 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: userret.h,v 1.17 2011/01/18 01:02:54 matt Exp $	*/
+/*	$NetBSD: userret.h,v 1.18 2011/02/17 13:53:32 matt Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -31,12 +31,18 @@
  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include "opt_ppcarch.h"
 #include "opt_altivec.h"
 
 #include <sys/userret.h>
 
 #include <powerpc/fpu.h>
 
+#ifdef PPC_BOOKE
+#include <powerpc/spr.h>
+#include <powerpc/booke/spr.h>
+#endif
+
 /*
  * Define the code needed before returning to user mode, for
  * trap and syscall.
@@ -89,6 +95,18 @@
 		__asm volatile("dssall;sync");
 	}
 #endif
+#ifdef PPC_BOOKE
+	/*
+	 * BookE doesn't PSL_SE but it does have a debug instruction completion
+	 * exception but it needs PSL_DE to fire.  Since we don't want it to
+	 * happen in the kernel, we must disable PSL_DE and let it get
+	 * restored by rfi/rfci.
+	 */
+	if (__predict_false(tf->tf_srr1 & PSL_SE)) {
+		extern void booke_sstep(struct trapframe *); /* ugly */
+		booke_sstep(tf);
+	}
+#endif
 #ifdef PPC_HAVE_SPE
 	/*
 	 * We need to manually restore PSL_SPV each time we return

Index: src/sys/arch/powerpc/include/booke/cpuvar.h
diff -u src/sys/arch/powerpc/include/booke/cpuvar.h:1.4 src/sys/arch/powerpc/include/booke/cpuvar.h:1.5
--- src/sys/arch/powerpc/include/booke/cpuvar.h:1.4	Wed Feb 16 18:41:48 2011
+++ src/sys/arch/powerpc/include/booke/cpuvar.h	Thu Feb 17 13:53:32 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpuvar.h,v 1.4 2011/02/16 18:41:48 matt Exp $	*/
+/*	$NetBSD: cpuvar.h,v 1.5 2011/02/17 13:53:32 matt Exp $	*/
 /*-
  * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -157,6 +157,11 @@
 	return old_msr;
 }
 
+uint32_t ufetch_32(const void *);
+
+struct trapframe;
+void	booke_sstep(struct trapframe *);
+
 void	booke_fixup_stubs(void);
 void	booke_cpu_startup(const char *);	/* model name */
 struct powerpc_bus_dma_tag booke_bus_dma_tag;

Reply via email to