Index: sys/arm64/arm64/machdep.c =================================================================== --- sys/arm64/arm64/machdep.c +++ sys/arm64/arm64/machdep.c @@ -321,8 +321,8 @@ fill_dbregs(struct thread *td, struct dbreg *regs) { struct debug_monitor_state *monitor; - int count, i; - uint8_t debug_ver, nbkpts; + int i; + uint8_t debug_ver, nbkpts, nwtpts; memset(regs, 0, sizeof(*regs)); @@ -330,24 +330,31 @@ &debug_ver); extract_user_id_field(ID_AA64DFR0_EL1, ID_AA64DFR0_BRPs_SHIFT, &nbkpts); + extract_user_id_field(ID_AA64DFR0_EL1, ID_AA64DFR0_WRPs_SHIFT, + &nwtpts); /* * The BRPs field contains the number of breakpoints - 1. Armv8-A * allows the hardware to provide 2-16 breakpoints so this won't - * overflow an 8 bit value. + * overflow an 8 bit value. The same applies to the WRPs field. */ - count = nbkpts + 1; + nbkpts++; + nwtpts++; regs->db_info = debug_ver; - regs->db_info <<= 8; - regs->db_info |= count; + regs->db_info |= (nbkpts << 8); + regs->db_info |= (nwtpts << 16); monitor = &td->td_pcb->pcb_dbg_regs; if ((monitor->dbg_flags & DBGMON_ENABLED) != 0) { - for (i = 0; i < count; i++) { + for (i = 0; i < nbkpts; i++) { regs->db_regs[i].dbr_addr = monitor->dbg_bvr[i]; regs->db_regs[i].dbr_ctrl = monitor->dbg_bcr[i]; } + for (i = 0; i < nwtpts; i++) { + regs->db_watchregs[i].dbw_addr = monitor->dbg_wvr[i]; + regs->db_watchregs[i].dbw_ctrl = monitor->dbg_wcr[i]; + } } return (0); @@ -370,6 +377,12 @@ if ((monitor->dbg_bcr[i] & 1) != 0) monitor->dbg_enable_count++; } + for (i = 0; i < DBG_WRP_MAX; i++) { + monitor->dbg_wvr[i] = regs->db_watchregs[i].dbw_addr; + monitor->dbg_wcr[i] = regs->db_watchregs[i].dbw_ctrl; + if ((monitor->dbg_wcr[i] & 1) != 0) + monitor->dbg_enable_count++; + } if (monitor->dbg_enable_count > 0) monitor->dbg_flags |= DBGMON_ENABLED; Index: sys/arm64/include/reg.h =================================================================== --- sys/arm64/include/reg.h +++ sys/arm64/include/reg.h @@ -60,6 +60,13 @@ }; struct dbreg { + /* + * db_info: + * bits 0:7 - value of debug_ver + * bits 8:15 - number of breakpoint registers + * bits 16:23 - number of watchpoint registers + * bits 24:31 - reserved + */ uint32_t db_info; uint32_t db_pad; @@ -68,6 +75,11 @@ uint32_t dbr_ctrl; uint32_t dbr_pad; } db_regs[16]; + struct { + uint64_t dbw_addr; + uint32_t dbw_ctrl; + uint32_t dbw_pad; + } db_watchregs[16]; }; struct dbreg32 {