Page MenuHomeFreeBSD

D44355.id136927.diff
No OneTemporary

D44355.id136927.diff

diff --git a/sys/arm64/arm64/db_trace.c b/sys/arm64/arm64/db_trace.c
--- a/sys/arm64/arm64/db_trace.c
+++ b/sys/arm64/arm64/db_trace.c
@@ -47,6 +47,13 @@
#define FRAME_SERROR 3
#define FRAME_UNHANDLED 4
+void
+db_md_list_breakpoints(void)
+{
+
+ dbg_show_breakpoint();
+}
+
void
db_md_list_watchpoints(void)
{
diff --git a/sys/arm64/arm64/debug_monitor.c b/sys/arm64/arm64/debug_monitor.c
--- a/sys/arm64/arm64/debug_monitor.c
+++ b/sys/arm64/arm64/debug_monitor.c
@@ -44,7 +44,9 @@
#include <machine/pcb.h>
#ifdef DDB
+#include <vm/vm.h>
#include <ddb/ddb.h>
+#include <ddb/db_break.h>
#include <ddb/db_sym.h>
#endif
@@ -59,6 +61,10 @@
.dbg_flags = DBGMON_KERNEL
};
+static int dbg_setup_breakpoint(struct debug_monitor_state *monitor,
+ vm_offset_t addr);
+static int dbg_remove_breakpoint(struct debug_monitor_state *monitor,
+ vm_offset_t addr);
static int dbg_setup_watchpoint(struct debug_monitor_state *, vm_offset_t,
vm_size_t, enum dbg_access_t);
static int dbg_remove_watchpoint(struct debug_monitor_state *, vm_offset_t,
@@ -185,6 +191,18 @@
}
#if defined(DDB) || defined(GDB)
+int
+kdb_cpu_set_breakpoint(vm_offset_t addr)
+{
+ return (dbg_setup_breakpoint(NULL, addr));
+}
+
+int
+kdb_cpu_clr_breakpoint(vm_offset_t addr)
+{
+ return (dbg_remove_breakpoint(NULL, addr));
+}
+
void
kdb_cpu_set_singlestep(void)
{
@@ -272,6 +290,33 @@
#endif /* DDB || GDB */
#ifdef DDB
+void
+dbg_show_breakpoint(void)
+{
+ db_breakpoint_t bkpt;
+ uint32_t bcr;
+ uint64_t addr;
+ int i;
+
+ db_printf("\nhardware breakpoints:\n");
+ db_printf(" break status count address symbol\n");
+ db_printf(" ----- -------- ----- ------------------ ------------------\n");
+ for (i = 0; i < dbg_breakpoint_num; i++) {
+ bcr = dbg_wb_read_reg(DBG_REG_BASE_BCR, i);
+ if ((bcr & DBG_WB_CTRL_E) != 0) {
+ addr = dbg_wb_read_reg(DBG_REG_BASE_BVR, i);
+ bkpt = db_find_breakpoint_here(addr);
+ db_printf(" %-5d %-8s %-5d 0x%16lx ",
+ i, "enabled", bkpt == NULL ? -1 : bkpt->count,
+ addr);
+ db_printsym((db_addr_t)addr, DB_STGY_ANY);
+ db_printf("\n");
+ } else {
+ db_printf(" %-5d disabled\n", i);
+ }
+ }
+}
+
static const char *
dbg_watchtype_str(uint32_t type)
{
@@ -394,6 +439,60 @@
return (-1);
}
+static int
+dbg_setup_breakpoint(struct debug_monitor_state *monitor, vm_offset_t addr)
+{
+ uint64_t bcr_priv;
+ u_int i;
+
+ if (monitor == NULL)
+ monitor = &kernel_monitor;
+
+ i = dbg_find_free_slot(monitor, DBG_TYPE_BREAKPOINT);
+ if (i == -1) {
+ printf("Can not find slot for breakpoint, max %d"
+ " breakpoints supported\n", dbg_breakpoint_num);
+ return (EBUSY);
+ }
+
+ if ((monitor->dbg_flags & DBGMON_KERNEL) == 0)
+ bcr_priv = DBG_WB_CTRL_EL0;
+ else
+ bcr_priv = DBG_WB_CTRL_EL1;
+
+ monitor->dbg_bvr[i] = addr;
+ monitor->dbg_bcr[i] = (0xf << 5) | bcr_priv | DBG_WB_CTRL_E;
+ monitor->dbg_enable_count++;
+ monitor->dbg_flags |= DBGMON_ENABLED;
+ dbg_register_sync(monitor);
+
+ return (0);
+}
+
+static int
+dbg_remove_breakpoint(struct debug_monitor_state *monitor, vm_offset_t addr)
+{
+ u_int i;
+
+ if (monitor == NULL)
+ monitor = &kernel_monitor;
+
+ i = dbg_find_slot(monitor, DBG_TYPE_BREAKPOINT, addr);
+ if (i == -1) {
+ printf("Can not find breakpoint for address 0%lx\n", addr);
+ return (i);
+ }
+
+ monitor->dbg_bvr[i] = 0;
+ monitor->dbg_bcr[i] = 0;
+ monitor->dbg_enable_count--;
+ if (monitor->dbg_enable_count == 0)
+ monitor->dbg_flags &= ~DBGMON_ENABLED;
+ dbg_register_sync(monitor);
+
+ return (0);
+}
+
static int
dbg_setup_watchpoint(struct debug_monitor_state *monitor, vm_offset_t addr,
vm_size_t size, enum dbg_access_t access)
diff --git a/sys/arm64/arm64/gdb_machdep.c b/sys/arm64/arm64/gdb_machdep.c
--- a/sys/arm64/arm64/gdb_machdep.c
+++ b/sys/arm64/arm64/gdb_machdep.c
@@ -121,9 +121,16 @@
gdb_cpu_stop_reason(int type, int code __unused)
{
- if (type == EXCP_WATCHPT_EL1) {
+ switch (type) {
+ case EXCP_WATCHPT_EL1:
gdb_tx_str("watch:");
gdb_tx_varhex((uintmax_t)READ_SPECIALREG(far_el1));
gdb_tx_char(';');
+ break;
+ case EXCP_BRKPT_EL1:
+ gdb_tx_str("hwbreak:;");
+ break;
+ default:
+ break;
}
}
diff --git a/sys/arm64/include/db_machdep.h b/sys/arm64/include/db_machdep.h
--- a/sys/arm64/include/db_machdep.h
+++ b/sys/arm64/include/db_machdep.h
@@ -40,6 +40,9 @@
#define T_SINGLESTEP (EXCP_SOFTSTP_EL1)
#define T_WATCHPOINT (EXCP_WATCHPT_EL1)
+#define HAS_HW_BREAKPOINT
+#define NHBREAKPOINTS 16
+
typedef vm_offset_t db_addr_t;
typedef long db_expr_t;
diff --git a/sys/arm64/include/debug_monitor.h b/sys/arm64/include/debug_monitor.h
--- a/sys/arm64/include/debug_monitor.h
+++ b/sys/arm64/include/debug_monitor.h
@@ -56,6 +56,7 @@
void dbg_register_sync(struct debug_monitor_state *);
#ifdef DDB
+void dbg_show_breakpoint(void);
void dbg_show_watchpoint(void);
#endif
diff --git a/sys/arm64/include/kdb.h b/sys/arm64/include/kdb.h
--- a/sys/arm64/include/kdb.h
+++ b/sys/arm64/include/kdb.h
@@ -37,6 +37,8 @@
void kdb_cpu_clear_singlestep(void);
void kdb_cpu_set_singlestep(void);
+int kdb_cpu_set_breakpoint(vm_offset_t addr);
+int kdb_cpu_clr_breakpoint(vm_offset_t addr);
int kdb_cpu_set_watchpoint(vm_offset_t addr, size_t size, int access);
int kdb_cpu_clr_watchpoint(vm_offset_t addr, size_t size);

File Metadata

Mime Type
text/plain
Expires
Tue, Nov 19, 4:24 PM (11 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14705130
Default Alt Text
D44355.id136927.diff (5 KB)

Event Timeline