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