Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/powerpc For booke and ibm4xx, switch to software-ba...



details:   https://anonhg.NetBSD.org/src/rev/0b4b487cd828
branches:  trunk
changeset: 953328:0b4b487cd828
user:      rin <rin%NetBSD.org@localhost>
date:      Sat Mar 06 08:08:19 2021 +0000

description:
For booke and ibm4xx, switch to software-based single-stepping for PT_STEP
ptrace(2) command from broken hardware-based implementation.

As described in proposal on port-powerpc@,

http://mail-index.netbsd.org/port-powerpc/2021/02/26/msg003597.html

hardware debug facilities of booke and 4xx use critical interrupts, that
are difficult to handle for this purpose; they are not automatically masked
when entering kernel mode via system call trap or hardware interrupt.
See my proposal above for more details.

Now, hardware debug facilities are exclusively usable by kernel itself.
They are much more functional than PSL_SE MSR bit of oea, and should be
useful to, e.g., support byte-granular watchpoint for DDB in the future.

diffstat:

 sys/arch/powerpc/booke/trap.c              |   40 ++++++-
 sys/arch/powerpc/ibm4xx/ibm4xx_machdep.c   |    6 +-
 sys/arch/powerpc/ibm4xx/trap.c             |   52 ++++------
 sys/arch/powerpc/include/proc.h            |   12 ++-
 sys/arch/powerpc/include/psl.h             |   13 +--
 sys/arch/powerpc/include/ptrace.h          |    6 +-
 sys/arch/powerpc/powerpc/locore_subr.S     |    7 +-
 sys/arch/powerpc/powerpc/powerpc_machdep.c |    9 +-
 sys/arch/powerpc/powerpc/process_machdep.c |  136 ++++++++++++++++++++++++++++-
 9 files changed, 218 insertions(+), 63 deletions(-)

diffs (truncated from 561 to 300 lines):

diff -r ce47089184a2 -r 0b4b487cd828 sys/arch/powerpc/booke/trap.c
--- a/sys/arch/powerpc/booke/trap.c     Sat Mar 06 07:29:05 2021 +0000
+++ b/sys/arch/powerpc/booke/trap.c     Sat Mar 06 08:08:19 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: trap.c,v 1.36 2021/01/06 08:04:57 rin Exp $    */
+/*     $NetBSD: trap.c,v 1.37 2021/03/06 08:08:19 rin Exp $    */
 /*-
  * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.36 2021/01/06 08:04:57 rin Exp $");
+__KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.37 2021/03/06 08:08:19 rin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_altivec.h"
@@ -47,6 +47,7 @@
 #include <sys/kauth.h>
 #include <sys/lwp.h>
 #include <sys/proc.h>
+#include <sys/ptrace.h>
 #include <sys/ras.h>
 #include <sys/siginfo.h>
 #include <sys/systm.h>
@@ -461,11 +462,31 @@
 
        ci->ci_ev_pgm.ev_count++;
 
+       KSI_INIT_TRAP(ksi);
+
        if (tf->tf_esr & ESR_PTR) {
-               struct proc *p = curlwp->l_proc;
-               if (p->p_raslist != NULL
-                   && ras_lookup(p, (void *)tf->tf_srr0) != (void *) -1) {
-                       tf->tf_srr0 += 4;
+               struct lwp * const l = curlwp;
+               struct proc * const p = curlwp->l_proc;
+               vaddr_t va = (vaddr_t)tf->tf_srr0;
+               int error;
+
+               /*
+                * Restore original instruction and clear BP.
+                */
+               if (p->p_md.md_ss_addr[0] == va ||
+                   p->p_md.md_ss_addr[1] == va) {
+                       error = ppc_sstep(l, 0);
+                       if (error != 0) {
+                               vm_signal(error, EXC_PGM /* XXX */, va, ksi);
+                               return error;
+                       }
+                       ksi->ksi_code = TRAP_TRACE;
+               } else
+                       ksi->ksi_code = TRAP_BRKPT;
+
+               if (p->p_raslist != NULL &&
+                   ras_lookup(p, (void *)va) != (void *)-1) {
+                       tf->tf_srr0 += (ksi->ksi_code == TRAP_TRACE) ? 0 : 4;
                        return 0;
                }
        }
@@ -494,7 +515,6 @@
                }
        }
 
-       KSI_INIT_TRAP(ksi);
        ksi->ksi_signo = SIGILL;
        ksi->ksi_trap = EXC_PGM;
        if (tf->tf_esr & ESR_PIL) {
@@ -503,7 +523,6 @@
                ksi->ksi_code = ILL_PRVOPC;
        } else if (tf->tf_esr & ESR_PTR) {
                ksi->ksi_signo = SIGTRAP;
-               ksi->ksi_code = TRAP_BRKPT;
        } else {
                ksi->ksi_code = 0;
        }
@@ -511,6 +530,7 @@
        return rv;
 }
 
+#if 0
 static int
 debug_exception(struct trapframe *tf, ksiginfo_t *ksi)
 {
@@ -545,6 +565,7 @@
        ksi->ksi_code = TRAP_TRACE;
        return rv;
 }
+#endif
 
 static int
 ali_exception(struct trapframe *tf, ksiginfo_t *ksi)
@@ -752,6 +773,7 @@
        switch (trap_code) {
        case T_CRITIAL_INPUT:
        case T_EXTERNAL_INPUT:
+       case T_DEBUG:
        case T_DECREMENTER:
        case T_FIXED_INTERVAL:
        case T_WATCHDOG:
@@ -791,6 +813,7 @@
        case T_INSTRUCTION_TLB_ERROR:
                rv = itlb_exception(tf, &ksi);
                break;
+#if 0
        case T_DEBUG:
 #ifdef DDB
                if (!usertrap && ddb_exception(tf))
@@ -798,6 +821,7 @@
 #endif
                rv = debug_exception(tf, &ksi);
                break;
+#endif
        case T_EMBEDDED_FP_DATA:
                rv = embedded_fp_data_exception(tf, &ksi);
                break;
diff -r ce47089184a2 -r 0b4b487cd828 sys/arch/powerpc/ibm4xx/ibm4xx_machdep.c
--- a/sys/arch/powerpc/ibm4xx/ibm4xx_machdep.c  Sat Mar 06 07:29:05 2021 +0000
+++ b/sys/arch/powerpc/ibm4xx/ibm4xx_machdep.c  Sat Mar 06 08:08:19 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ibm4xx_machdep.c,v 1.34 2021/01/18 02:43:27 rin Exp $  */
+/*     $NetBSD: ibm4xx_machdep.c,v 1.35 2021/03/06 08:08:19 rin Exp $  */
 /*     Original: ibm40x_machdep.c,v 1.3 2005/01/17 17:19:36 shige Exp $ */
 
 /*
@@ -68,7 +68,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ibm4xx_machdep.c,v 1.34 2021/01/18 02:43:27 rin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ibm4xx_machdep.c,v 1.35 2021/03/06 08:08:19 rin Exp $");
 
 #include "ksyms.h"
 
@@ -148,6 +148,8 @@
                        errata51handler, (uintptr_t)&errata51size },
 #if defined(DDB)
        { EXC_PGM,      ddblow,         (uintptr_t)&ddbsize },
+#else
+       { EXC_PGM,      accesstrap,     (uintptr_t)&accesssize },
 #endif
 };
 
diff -r ce47089184a2 -r 0b4b487cd828 sys/arch/powerpc/ibm4xx/trap.c
--- a/sys/arch/powerpc/ibm4xx/trap.c    Sat Mar 06 07:29:05 2021 +0000
+++ b/sys/arch/powerpc/ibm4xx/trap.c    Sat Mar 06 08:08:19 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: trap.c,v 1.85 2020/07/15 09:10:14 rin Exp $    */
+/*     $NetBSD: trap.c,v 1.86 2021/03/06 08:08:19 rin Exp $    */
 
 /*
  * Copyright 2001 Wasabi Systems, Inc.
@@ -69,7 +69,7 @@
 #define        __UFETCHSTORE_PRIVATE
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.85 2020/07/15 09:10:14 rin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.86 2021/03/06 08:08:19 rin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -81,6 +81,7 @@
 #include <sys/cpu.h>
 #include <sys/kauth.h>
 #include <sys/proc.h>
+#include <sys/ptrace.h>
 #include <sys/reboot.h>
 #include <sys/syscall.h>
 #include <sys/systm.h>
@@ -157,20 +158,10 @@
 
        switch (type) {
        case EXC_DEBUG|EXC_USER:
-               {
-                       int srr2, srr3;
+               /* We don't use hardware breakpoints for userland. */
+               goto brain_damage;
 
-                       __asm volatile("mfspr %0,0x3f0" :
-                           "=r" (rv), "=r" (srr2), "=r" (srr3) :);
-                       printf("debug reg is %x srr2 %x srr3 %x\n", rv, srr2,
-                           srr3);
-                       /* XXX fall through or break here?! */
-               }
-               /*
-                * DEBUG intr -- probably single-step.
-                */
        case EXC_TRC|EXC_USER:
-               tf->tf_srr1 &= ~PSL_SE;
                KSI_INIT_TRAP(&ksi);
                ksi.ksi_signo = SIGTRAP;
                ksi.ksi_trap = EXC_TRC;
@@ -317,13 +308,26 @@
                ksi.ksi_addr = (void *)tf->tf_srr0;
 
                if (tf->tf_esr & ESR_PTR) {
+                       vaddr_t va;
 sigtrap:
+                       va = (vaddr_t)tf->tf_srr0;
+                       /*
+                        * Restore original instruction and clear BP.
+                        */
+                       if (p->p_md.md_ss_addr[0] == va ||
+                           p->p_md.md_ss_addr[1] == va) {
+                               rv = ppc_sstep(l, 0);
+                               if (rv != 0)
+                                       goto vm_signal;
+                               ksi.ksi_code = TRAP_TRACE;
+                       } else
+                               ksi.ksi_code = TRAP_BRKPT;
                        if (p->p_raslist != NULL &&
-                           ras_lookup(p, (void *)tf->tf_srr0) != (void *) -1) {
-                               tf->tf_srr1 += 4;
+                           ras_lookup(p, (void *)va) != (void *)-1) {
+                               tf->tf_srr0 += (ksi.ksi_code == TRAP_TRACE) ?
+                                   0 : 4;
                                break;
                        }
-                       ksi.ksi_code = TRAP_BRKPT;
                        ksi.ksi_signo = SIGTRAP;
                } else if (tf->tf_esr & ESR_PPR) {
                        uint32_t opcode;
@@ -411,20 +415,6 @@
                        ctx_alloc(__UNVOLATILE(pm));
                }
                ctx = pm->pm_ctx;
-               if (srr1 & PSL_SE) {
-                       int dbreg, mask = 0x48000000;
-                               /*
-                                * Set the Internal Debug and
-                                * Instruction Completion bits of
-                                * the DBCR0 register.
-                                *
-                                * XXX this is also used by jtag debuggers...
-                                */
-                       __asm volatile("mfspr %0,0x3f2;"
-                           "or %0,%0,%1;"
-                           "mtspr 0x3f2,%0;" :
-                           "=&r" (dbreg) : "r" (mask));
-               }
        }
        else if (!ctx) {
                ctx = KERNEL_PID;
diff -r ce47089184a2 -r 0b4b487cd828 sys/arch/powerpc/include/proc.h
--- a/sys/arch/powerpc/include/proc.h   Sat Mar 06 07:29:05 2021 +0000
+++ b/sys/arch/powerpc/include/proc.h   Sat Mar 06 08:08:19 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: proc.h,v 1.13 2013/08/23 06:19:46 matt Exp $   */
+/*     $NetBSD: proc.h,v 1.14 2021/03/06 08:08:19 rin Exp $    */
 
 /*-
  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -34,6 +34,11 @@
 #ifndef _POWERPC_PROC_H_
 #define _POWERPC_PROC_H_
 
+#ifdef _KERNEL_OPT
+#include "opt_modular.h"
+#include "opt_ppcarch.h"
+#endif
+
 /*
  * Machine-dependent part of the lwp structure
  */
@@ -47,6 +52,11 @@
 
 struct mdproc {
        void (*md_syscall)(struct trapframe *);
+#if defined(PPC_BOOKE) || defined(PPC_IBM4XX) || \
+    defined(MODULAR) || defined(_MODULE)
+       vaddr_t md_ss_addr[2];
+       uint32_t md_ss_insn[2];
+#endif
 };
 
 #ifdef _KERNEL
diff -r ce47089184a2 -r 0b4b487cd828 sys/arch/powerpc/include/psl.h
--- a/sys/arch/powerpc/include/psl.h    Sat Mar 06 07:29:05 2021 +0000
+++ b/sys/arch/powerpc/include/psl.h    Sat Mar 06 08:08:19 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: psl.h,v 1.21 2020/07/06 09:34:17 rin Exp $     */
+/*     $NetBSD: psl.h,v 1.22 2021/03/06 08:08:19 rin Exp $     */
 
 /*
  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -111,7 +111,7 @@
 #define        PSL_USERMOD             cpu_pslusermod
 #define        PSL_USERMASK            cpu_pslusermask
 #elif defined(PPC_BOOKE)
-#define        PSL_USERSET             (PSL_EE | PSL_PR | PSL_IS | PSL_DS | PSL_ME | PSL_CE | PSL_DE)
+#define        PSL_USERSET             (PSL_EE | PSL_PR | PSL_IS | PSL_DS | PSL_ME | PSL_CE)
 #define        PSL_USERMASK            (PSL_SPV | PSL_CE | 0xFFFF)
 #define        PSL_USERMOD             (0)
 #else /* PPC_IBM4XX */
@@ -122,14 +122,7 @@
 #endif
 #define        PSL_USERMASK            0xFFFF
 #define        PSL_USERMOD             (0)



Home | Main Index | Thread Index | Old Index