? o Index: aarch64/cpuswitch.S =================================================================== RCS file: /cvsroot/src/sys/arch/aarch64/aarch64/cpuswitch.S,v retrieving revision 1.7 diff -u -u -r1.7 cpuswitch.S --- aarch64/cpuswitch.S 7 Dec 2018 18:27:03 -0000 1.7 +++ aarch64/cpuswitch.S 8 Dec 2018 23:12:23 -0000 @@ -39,6 +39,24 @@ RCSID("$NetBSD: cpuswitch.S,v 1.7 2018/12/07 18:27:03 ryo Exp $") +.macro clear_step_flag pcbflags, tmp + tbz \pcbflags, #PCB_SINGLE_STEP_SHIFT, 999f + mrs \tmp, mdscr_el1 + bic \tmp, \tmp, #1 + msr mdscr_el1, \tmp + isb +999: +.endm + +.macro set_step_flag pcbflags, tmp + tbz \pcbflags, #PCB_SINGLE_STEP_SHIFT, 999f + mrs \tmp, mdscr_el1 + orr \tmp, \tmp, #1 + msr mdscr_el1, \tmp + isb +999: +.endm + /* * At IPL_SCHED: * x0 = oldlwp (maybe be NULL) @@ -49,6 +67,11 @@ ENTRY_NP(cpu_switchto) cbz x0, .Lrestore_lwp + /* If we were single stepping, disable it */ + ldr x4, [x0, #L_PCB] + ldr w5, [x4, #PCB_FLAGS] + clear_step_flag w5, x6 + /* * Store the callee saved register on the stack. */ @@ -90,6 +113,12 @@ str x1, [x3, #CI_CURLWP] /* switch curlwp to new lwp */ ENABLE_INTERRUPT + + /* If we are single stepping, enable it */ + ldr x4, [x1, #L_PCB] + ldr w5, [x4, #PCB_FLAGS] + set_step_flag w5, x6 + /* * Restore callee save registers. */ @@ -133,6 +162,12 @@ mrs x3, tpidr_el1 /* x3 := curcpu() */ DISABLE_INTERRUPT ldr x19, [x3, #CI_CURLWP] /* x19 := curcpu()->ci_curlwp */ + + /* If we were single stepping, disable it */ + ldr x4, [x19, #L_PCB] + ldr w5, [x4, #PCB_FLAGS] + clear_step_flag w5, x6 + mov x4, sp mrs x5, cpacr_el1 #if L_MD_KTF + 8 == L_MD_CPACR @@ -155,6 +190,12 @@ sub sp, x4, #TF_SIZE /* new sp := softlwp->l_md_utf - 1 */ mov x5, #CPACR_FPEN_NONE msr cpacr_el1, x5 /* cpacr_el1 = CPACR_FPEN_NONE */ + + /* If we are single stepping, enable it */ + ldr x4, [x0, #L_PCB] + ldr w5, [x4, #PCB_FLAGS] + set_step_flag w5, x6 + ENABLE_INTERRUPT /* softint_dispatch(pinned_lwp, ipl) */ Index: aarch64/genassym.cf =================================================================== RCS file: /cvsroot/src/sys/arch/aarch64/aarch64/genassym.cf,v retrieving revision 1.9 diff -u -u -r1.9 genassym.cf --- aarch64/genassym.cf 20 Nov 2018 01:59:51 -0000 1.9 +++ aarch64/genassym.cf 8 Dec 2018 23:12:23 -0000 @@ -51,6 +51,7 @@ include include include +include if defined(_KERNEL_OPT) include "opt_multiprocessor.h" @@ -182,6 +183,9 @@ define L_MD_CPACR offsetof(struct lwp, l_md.md_cpacr) define L_MD_ONFAULT offsetof(struct lwp, l_md.md_onfault) +define PCB_SINGLE_STEP_SHIFT PCB_SINGLE_STEP_SHIFT +define PCB_FLAGS offsetof(struct pcb, pcb_flags) + define FB_X19 FB_X19 define FB_X20 FB_X20 define FB_X21 FB_X21 Index: aarch64/process_machdep.c =================================================================== RCS file: /cvsroot/src/sys/arch/aarch64/aarch64/process_machdep.c,v retrieving revision 1.3 diff -u -u -r1.3 process_machdep.c --- aarch64/process_machdep.c 17 Jul 2018 00:36:30 -0000 1.3 +++ aarch64/process_machdep.c 8 Dec 2018 23:12:23 -0000 @@ -43,6 +43,12 @@ #include #include +static __inline struct trapframe * +process_frame(struct lwp *l) +{ + return l->l_md.md_utf; +} + int process_read_regs(struct lwp *l, struct reg *regs) { @@ -89,6 +95,23 @@ } int +process_sstep(struct lwp *l, int sstep) +{ + struct trapframe *tf = process_frame(l); + struct pcb *pcb = lwp_getpcb(l); + +printf("single step %s %d\n", l->l_proc->p_comm, sstep); + if (sstep) { + tf->tf_spsr |= SPSR_SS; + pcb->pcb_flags |= PCB_SINGLE_STEP; + } else { + tf->tf_spsr &= ~SPSR_SS; + pcb->pcb_flags &= ~PCB_SINGLE_STEP; + } + return 0; +} + +int process_set_pc(struct lwp *l, void *addr) { Index: aarch64/trap.c =================================================================== RCS file: /cvsroot/src/sys/arch/aarch64/aarch64/trap.c,v retrieving revision 1.12 diff -u -u -r1.12 trap.c --- aarch64/trap.c 7 Dec 2018 18:46:27 -0000 1.12 +++ aarch64/trap.c 8 Dec 2018 23:12:23 -0000 @@ -267,10 +267,15 @@ case ESR_EC_BRKPNT_EL0: case ESR_EC_SW_STEP_EL0: case ESR_EC_WTCHPNT_EL0: + { + struct pcb *pcb = lwp_getpcb(l); +printf("EL0 %s %p %x\n", l->l_proc->p_comm, (void *)tf->tf_pc, pcb->pcb_flags); + pcb->pcb_flags &= ~PCB_SINGLE_STEP; + tf->tf_spsr &= ~SPSR_SS; do_trapsignal(l, SIGTRAP, TRAP_BRKPT, (void *)tf->tf_pc, esr); userret(l); break; - + } default: case ESR_EC_UNKNOWN: #ifdef DDB Index: include/pcb.h =================================================================== RCS file: /cvsroot/src/sys/arch/aarch64/include/pcb.h,v retrieving revision 1.1 diff -u -u -r1.1 pcb.h --- include/pcb.h 10 Aug 2014 05:47:38 -0000 1.1 +++ include/pcb.h 8 Dec 2018 23:12:23 -0000 @@ -38,6 +38,9 @@ struct pcb { struct fpreg pcb_fpregs; + int pcb_flags; +#define PCB_SINGLE_STEP_SHIFT 0 +#define PCB_SINGLE_STEP (1 << PCB_SINGLE_STEP_SHIFT) }; struct md_coredump { Index: include/ptrace.h =================================================================== RCS file: /cvsroot/src/sys/arch/aarch64/include/ptrace.h,v retrieving revision 1.7 diff -u -u -r1.7 ptrace.h --- include/ptrace.h 21 Jul 2018 18:58:05 -0000 1.7 +++ include/ptrace.h 8 Dec 2018 23:12:23 -0000 @@ -42,12 +42,18 @@ #define PT_SETREGS (PT_FIRSTMACH + 1) #define PT_GETFPREGS (PT_FIRSTMACH + 2) #define PT_SETFPREGS (PT_FIRSTMACH + 3) +#define PT_STEP (PT_FIRSTMACH + 4) +#define PT_SETSTEP (PT_FIRSTMACH + 5) +#define PT_CLEARSTEP (PT_FIRSTMACH + 6) #define PT_MACHDEP_STRINGS \ "PT_GETREGS", \ "PT_SETREGS", \ "PT_GETFPREGS", \ - "PT_SETFPREGS", + "PT_SETFPREGS", \ + "PT_STEP", \ + "PT_SETSTEP", \ + "PT_CLEARSTEP", #include