Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/powerpc add begging of single step support. Since ...
details: https://anonhg.NetBSD.org/src/rev/969149a623ee
branches: trunk
changeset: 762198:969149a623ee
user: matt <matt%NetBSD.org@localhost>
date: Thu Feb 17 13:53:32 2011 +0000
description:
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.
diffstat:
sys/arch/powerpc/booke/booke_machdep.c | 38 +++++++++++++++++++++++-
sys/arch/powerpc/booke/copyin.c | 24 +++++++++++++-
sys/arch/powerpc/booke/trap.c | 52 +++++++++++++++++++++++++++++++-
sys/arch/powerpc/include/booke/cpuvar.h | 7 +++-
sys/arch/powerpc/include/userret.h | 20 ++++++++++++-
5 files changed, 133 insertions(+), 8 deletions(-)
diffs (279 lines):
diff -r 11659d8a8f3c -r 969149a623ee sys/arch/powerpc/booke/booke_machdep.c
--- a/sys/arch/powerpc/booke/booke_machdep.c Thu Feb 17 12:52:33 2011 +0000
+++ b/sys/arch/powerpc/booke/booke_machdep.c Thu Feb 17 13:53:32 2011 +0000
@@ -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);
+}
diff -r 11659d8a8f3c -r 969149a623ee sys/arch/powerpc/booke/copyin.c
--- a/sys/arch/powerpc/booke/copyin.c Thu Feb 17 12:52:33 2011 +0000
+++ b/sys/arch/powerpc/booke/copyin.c Thu Feb 17 13:53:32 2011 +0000
@@ -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)
{
diff -r 11659d8a8f3c -r 969149a623ee sys/arch/powerpc/booke/trap.c
--- a/sys/arch/powerpc/booke/trap.c Thu Feb 17 12:52:33 2011 +0000
+++ b/sys/arch/powerpc/booke/trap.c Thu Feb 17 13:53:32 2011 +0000
@@ -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;
diff -r 11659d8a8f3c -r 969149a623ee sys/arch/powerpc/include/booke/cpuvar.h
--- a/sys/arch/powerpc/include/booke/cpuvar.h Thu Feb 17 12:52:33 2011 +0000
+++ b/sys/arch/powerpc/include/booke/cpuvar.h Thu Feb 17 13:53:32 2011 +0000
@@ -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;
diff -r 11659d8a8f3c -r 969149a623ee sys/arch/powerpc/include/userret.h
--- a/sys/arch/powerpc/include/userret.h Thu Feb 17 12:52:33 2011 +0000
+++ b/sys/arch/powerpc/include/userret.h Thu Feb 17 13:53:32 2011 +0000
@@ -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
Home |
Main Index |
Thread Index |
Old Index