Changeset View
Changeset View
Standalone View
Standalone View
sys/arm64/arm64/debug_monitor.c
Show First 20 Lines • Show All 183 Lines • ▼ Show 20 Lines | |||||
#if defined(DDB) || defined(GDB) | #if defined(DDB) || defined(GDB) | ||||
void | void | ||||
kdb_cpu_set_singlestep(void) | kdb_cpu_set_singlestep(void) | ||||
{ | { | ||||
KASSERT((READ_SPECIALREG(daif) & PSR_D) == PSR_D, | KASSERT((READ_SPECIALREG(daif) & PSR_D) == PSR_D, | ||||
("%s: debug exceptions are not masked", __func__)); | ("%s: debug exceptions are not masked", __func__)); | ||||
kdb_frame->tf_spsr |= DBG_SPSR_SS; | kdb_frame->tf_spsr |= PSR_SS; | ||||
WRITE_SPECIALREG(mdscr_el1, READ_SPECIALREG(mdscr_el1) | | WRITE_SPECIALREG(mdscr_el1, READ_SPECIALREG(mdscr_el1) | | ||||
DBG_MDSCR_SS | DBG_MDSCR_KDE); | MDSCR_SS | MDSCR_KDE); | ||||
/* | /* | ||||
* Disable breakpoints and watchpoints, e.g. stepping | * Disable breakpoints and watchpoints, e.g. stepping | ||||
* over watched instruction will trigger break exception instead of | * over watched instruction will trigger break exception instead of | ||||
* single-step exception and locks CPU on that instruction for ever. | * single-step exception and locks CPU on that instruction for ever. | ||||
*/ | */ | ||||
if ((kernel_monitor.dbg_flags & DBGMON_ENABLED) != 0) { | if ((kernel_monitor.dbg_flags & DBGMON_ENABLED) != 0) { | ||||
WRITE_SPECIALREG(mdscr_el1, | WRITE_SPECIALREG(mdscr_el1, | ||||
READ_SPECIALREG(mdscr_el1) & ~DBG_MDSCR_MDE); | READ_SPECIALREG(mdscr_el1) & ~MDSCR_MDE); | ||||
} | } | ||||
} | } | ||||
void | void | ||||
kdb_cpu_clear_singlestep(void) | kdb_cpu_clear_singlestep(void) | ||||
{ | { | ||||
KASSERT((READ_SPECIALREG(daif) & PSR_D) == PSR_D, | KASSERT((READ_SPECIALREG(daif) & PSR_D) == PSR_D, | ||||
("%s: debug exceptions are not masked", __func__)); | ("%s: debug exceptions are not masked", __func__)); | ||||
WRITE_SPECIALREG(mdscr_el1, READ_SPECIALREG(mdscr_el1) & | WRITE_SPECIALREG(mdscr_el1, READ_SPECIALREG(mdscr_el1) & | ||||
~(DBG_MDSCR_SS | DBG_MDSCR_KDE)); | ~(MDSCR_SS | MDSCR_KDE)); | ||||
/* Restore breakpoints and watchpoints */ | /* Restore breakpoints and watchpoints */ | ||||
if ((kernel_monitor.dbg_flags & DBGMON_ENABLED) != 0) { | if ((kernel_monitor.dbg_flags & DBGMON_ENABLED) != 0) { | ||||
WRITE_SPECIALREG(mdscr_el1, | WRITE_SPECIALREG(mdscr_el1, | ||||
READ_SPECIALREG(mdscr_el1) | DBG_MDSCR_MDE); | READ_SPECIALREG(mdscr_el1) | MDSCR_MDE); | ||||
if ((kernel_monitor.dbg_flags & DBGMON_KERNEL) != 0) { | if ((kernel_monitor.dbg_flags & DBGMON_KERNEL) != 0) { | ||||
WRITE_SPECIALREG(mdscr_el1, | WRITE_SPECIALREG(mdscr_el1, | ||||
READ_SPECIALREG(mdscr_el1) | DBG_MDSCR_KDE); | READ_SPECIALREG(mdscr_el1) | MDSCR_KDE); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
int | int | ||||
kdb_cpu_set_watchpoint(vm_offset_t addr, vm_size_t size, int access) | kdb_cpu_set_watchpoint(vm_offset_t addr, vm_size_t size, int access) | ||||
{ | { | ||||
enum dbg_access_t dbg_access; | enum dbg_access_t dbg_access; | ||||
▲ Show 20 Lines • Show All 244 Lines • ▼ Show 20 Lines | dbg_register_sync(struct debug_monitor_state *monitor) | ||||
uint64_t mdscr; | uint64_t mdscr; | ||||
int i; | int i; | ||||
if (monitor == NULL) | if (monitor == NULL) | ||||
monitor = &kernel_monitor; | monitor = &kernel_monitor; | ||||
mdscr = READ_SPECIALREG(mdscr_el1); | mdscr = READ_SPECIALREG(mdscr_el1); | ||||
if ((monitor->dbg_flags & DBGMON_ENABLED) == 0) { | if ((monitor->dbg_flags & DBGMON_ENABLED) == 0) { | ||||
mdscr &= ~(DBG_MDSCR_MDE | DBG_MDSCR_KDE); | mdscr &= ~(MDSCR_MDE | MDSCR_KDE); | ||||
} else { | } else { | ||||
for (i = 0; i < dbg_breakpoint_num; i++) { | for (i = 0; i < dbg_breakpoint_num; i++) { | ||||
dbg_wb_write_reg(DBG_REG_BASE_BCR, i, | dbg_wb_write_reg(DBG_REG_BASE_BCR, i, | ||||
monitor->dbg_bcr[i]); | monitor->dbg_bcr[i]); | ||||
dbg_wb_write_reg(DBG_REG_BASE_BVR, i, | dbg_wb_write_reg(DBG_REG_BASE_BVR, i, | ||||
monitor->dbg_bvr[i]); | monitor->dbg_bvr[i]); | ||||
} | } | ||||
for (i = 0; i < dbg_watchpoint_num; i++) { | for (i = 0; i < dbg_watchpoint_num; i++) { | ||||
dbg_wb_write_reg(DBG_REG_BASE_WCR, i, | dbg_wb_write_reg(DBG_REG_BASE_WCR, i, | ||||
monitor->dbg_wcr[i]); | monitor->dbg_wcr[i]); | ||||
dbg_wb_write_reg(DBG_REG_BASE_WVR, i, | dbg_wb_write_reg(DBG_REG_BASE_WVR, i, | ||||
monitor->dbg_wvr[i]); | monitor->dbg_wvr[i]); | ||||
} | } | ||||
mdscr |= DBG_MDSCR_MDE; | mdscr |= MDSCR_MDE; | ||||
if ((monitor->dbg_flags & DBGMON_KERNEL) == DBGMON_KERNEL) | if ((monitor->dbg_flags & DBGMON_KERNEL) == DBGMON_KERNEL) | ||||
mdscr |= DBG_MDSCR_KDE; | mdscr |= MDSCR_KDE; | ||||
} | } | ||||
WRITE_SPECIALREG(mdscr_el1, mdscr); | WRITE_SPECIALREG(mdscr_el1, mdscr); | ||||
isb(); | isb(); | ||||
} | } | ||||
void | void | ||||
dbg_monitor_init(void) | dbg_monitor_init(void) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | for (i = 0; i < dbg_watchpoint_num; i++) { | ||||
dbg_wb_write_reg(DBG_REG_BASE_WVR, i, 0); | dbg_wb_write_reg(DBG_REG_BASE_WVR, i, 0); | ||||
} | } | ||||
for (i = 0; i < dbg_breakpoint_num; ++i) { | for (i = 0; i < dbg_breakpoint_num; ++i) { | ||||
dbg_wb_write_reg(DBG_REG_BASE_BCR, i, 0); | dbg_wb_write_reg(DBG_REG_BASE_BCR, i, 0); | ||||
dbg_wb_write_reg(DBG_REG_BASE_BVR, i, 0); | dbg_wb_write_reg(DBG_REG_BASE_BVR, i, 0); | ||||
} | } | ||||
WRITE_SPECIALREG(mdscr_el1, | WRITE_SPECIALREG(mdscr_el1, | ||||
READ_SPECIALREG(mdscr_el1) & | READ_SPECIALREG(mdscr_el1) & ~(MDSCR_MDE | MDSCR_KDE)); | ||||
~(DBG_MDSCR_MDE | DBG_MDSCR_KDE)); | |||||
isb(); | isb(); | ||||
} | } | ||||
} | } | ||||
void | void | ||||
dbg_monitor_exit(struct thread *thread, struct trapframe *frame) | dbg_monitor_exit(struct thread *thread, struct trapframe *frame) | ||||
{ | { | ||||
int i; | int i; | ||||
Show All 16 Lines | for (i = 0; i < dbg_watchpoint_num; i++) { | ||||
dbg_wb_write_reg(DBG_REG_BASE_WVR, i, 0); | dbg_wb_write_reg(DBG_REG_BASE_WVR, i, 0); | ||||
} | } | ||||
for (i = 0; i < dbg_breakpoint_num; ++i) { | for (i = 0; i < dbg_breakpoint_num; ++i) { | ||||
dbg_wb_write_reg(DBG_REG_BASE_BCR, i, 0); | dbg_wb_write_reg(DBG_REG_BASE_BCR, i, 0); | ||||
dbg_wb_write_reg(DBG_REG_BASE_BVR, i, 0); | dbg_wb_write_reg(DBG_REG_BASE_BVR, i, 0); | ||||
} | } | ||||
WRITE_SPECIALREG(mdscr_el1, | WRITE_SPECIALREG(mdscr_el1, | ||||
READ_SPECIALREG(mdscr_el1) & | READ_SPECIALREG(mdscr_el1) & ~(MDSCR_MDE | MDSCR_KDE)); | ||||
~(DBG_MDSCR_MDE | DBG_MDSCR_KDE)); | |||||
isb(); | isb(); | ||||
} | } | ||||
} | } |