summaryrefslogtreecommitdiffstats
path: root/sys/amd64
diff options
context:
space:
mode:
authorbsd <bsd@FreeBSD.org>2001-06-28 02:08:13 +0000
committerbsd <bsd@FreeBSD.org>2001-06-28 02:08:13 +0000
commit47d3082050d220c6f4d161234ff7a3c4bc03b629 (patch)
tree5be0ec8cce68f03e921e4e1d2e96c1d0d9b6b38d /sys/amd64
parent057bf882e3678d2a8cb0feeaf6c89af57e5074e9 (diff)
downloadFreeBSD-src-47d3082050d220c6f4d161234ff7a3c4bc03b629.zip
FreeBSD-src-47d3082050d220c6f4d161234ff7a3c4bc03b629.tar.gz
Provide access to the IA32 hardware debug registers from the ddb
kernel debugger. Proper use of these registers allows setting hardware watchpoints for use in kernel debugging. MFC after: 2 weeks
Diffstat (limited to 'sys/amd64')
-rw-r--r--sys/amd64/amd64/db_trace.c71
-rw-r--r--sys/amd64/amd64/support.S6
-rw-r--r--sys/amd64/amd64/support.s6
-rw-r--r--sys/amd64/include/cpufunc.h65
4 files changed, 120 insertions, 28 deletions
diff --git a/sys/amd64/amd64/db_trace.c b/sys/amd64/amd64/db_trace.c
index 64db559..a861d16 100644
--- a/sys/amd64/amd64/db_trace.c
+++ b/sys/amd64/amd64/db_trace.c
@@ -44,28 +44,45 @@
#include <ddb/db_sym.h>
#include <ddb/db_variables.h>
+db_varfcn_t db_dr0;
+db_varfcn_t db_dr1;
+db_varfcn_t db_dr2;
+db_varfcn_t db_dr3;
+db_varfcn_t db_dr4;
+db_varfcn_t db_dr5;
+db_varfcn_t db_dr6;
+db_varfcn_t db_dr7;
+
/*
* Machine register set.
*/
struct db_variable db_regs[] = {
- { "cs", &ddb_regs.tf_cs, FCN_NULL },
- { "ds", &ddb_regs.tf_ds, FCN_NULL },
- { "es", &ddb_regs.tf_es, FCN_NULL },
- { "fs", &ddb_regs.tf_fs, FCN_NULL },
+ { "cs", &ddb_regs.tf_cs, FCN_NULL },
+ { "ds", &ddb_regs.tf_ds, FCN_NULL },
+ { "es", &ddb_regs.tf_es, FCN_NULL },
+ { "fs", &ddb_regs.tf_fs, FCN_NULL },
#if 0
- { "gs", &ddb_regs.tf_gs, FCN_NULL },
+ { "gs", &ddb_regs.tf_gs, FCN_NULL },
#endif
- { "ss", &ddb_regs.tf_ss, FCN_NULL },
- { "eax", &ddb_regs.tf_eax, FCN_NULL },
- { "ecx", &ddb_regs.tf_ecx, FCN_NULL },
- { "edx", &ddb_regs.tf_edx, FCN_NULL },
- { "ebx", &ddb_regs.tf_ebx, FCN_NULL },
- { "esp", &ddb_regs.tf_esp, FCN_NULL },
- { "ebp", &ddb_regs.tf_ebp, FCN_NULL },
- { "esi", &ddb_regs.tf_esi, FCN_NULL },
- { "edi", &ddb_regs.tf_edi, FCN_NULL },
- { "eip", &ddb_regs.tf_eip, FCN_NULL },
+ { "ss", &ddb_regs.tf_ss, FCN_NULL },
+ { "eax", &ddb_regs.tf_eax, FCN_NULL },
+ { "ecx", &ddb_regs.tf_ecx, FCN_NULL },
+ { "edx", &ddb_regs.tf_edx, FCN_NULL },
+ { "ebx", &ddb_regs.tf_ebx, FCN_NULL },
+ { "esp", &ddb_regs.tf_esp, FCN_NULL },
+ { "ebp", &ddb_regs.tf_ebp, FCN_NULL },
+ { "esi", &ddb_regs.tf_esi, FCN_NULL },
+ { "edi", &ddb_regs.tf_edi, FCN_NULL },
+ { "eip", &ddb_regs.tf_eip, FCN_NULL },
{ "efl", &ddb_regs.tf_eflags, FCN_NULL },
+ { "dr0", NULL, db_dr0 },
+ { "dr1", NULL, db_dr1 },
+ { "dr2", NULL, db_dr2 },
+ { "dr3", NULL, db_dr3 },
+ { "dr4", NULL, db_dr4 },
+ { "dr5", NULL, db_dr5 },
+ { "dr6", NULL, db_dr6 },
+ { "dr7", NULL, db_dr7 },
};
struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
@@ -409,3 +426,27 @@ db_stack_trace_cmd(addr, have_addr, count, modif)
}
}
}
+
+#define DB_DRX_FUNC(reg) \
+int \
+db_ ## reg (vp, valuep, op) \
+ struct db_variable *vp; \
+ db_expr_t * valuep; \
+ int op; \
+{ \
+ if (op == DB_VAR_GET) \
+ *valuep = r ## reg (); \
+ else \
+ load_ ## reg (*valuep); \
+ \
+ return(0); \
+}
+
+DB_DRX_FUNC(dr0)
+DB_DRX_FUNC(dr1)
+DB_DRX_FUNC(dr2)
+DB_DRX_FUNC(dr3)
+DB_DRX_FUNC(dr4)
+DB_DRX_FUNC(dr5)
+DB_DRX_FUNC(dr6)
+DB_DRX_FUNC(dr7)
diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S
index 70cc144..3218774 100644
--- a/sys/amd64/amd64/support.S
+++ b/sys/amd64/amd64/support.S
@@ -1627,12 +1627,6 @@ ENTRY(load_cr4)
movl %eax,%cr4
ret
-/* void load_dr6(u_int dr6) */
-ENTRY(load_dr6)
- movl 4(%esp),%eax
- movl %eax,%dr6
- ret
-
/* void reset_dbregs() */
ENTRY(reset_dbregs)
movl $0,%eax
diff --git a/sys/amd64/amd64/support.s b/sys/amd64/amd64/support.s
index 70cc144..3218774 100644
--- a/sys/amd64/amd64/support.s
+++ b/sys/amd64/amd64/support.s
@@ -1627,12 +1627,6 @@ ENTRY(load_cr4)
movl %eax,%cr4
ret
-/* void load_dr6(u_int dr6) */
-ENTRY(load_dr6)
- movl 4(%esp),%eax
- movl %eax,%dr6
- ret
-
/* void reset_dbregs() */
ENTRY(reset_dbregs)
movl $0,%eax
diff --git a/sys/amd64/include/cpufunc.h b/sys/amd64/include/cpufunc.h
index 40f5bb7..4a9300a 100644
--- a/sys/amd64/include/cpufunc.h
+++ b/sys/amd64/include/cpufunc.h
@@ -443,6 +443,12 @@ rdr0(void)
return (data);
}
+static __inline void
+load_dr0(u_int sel)
+{
+ __asm __volatile("movl %0,%%dr0" : : "r" (sel));
+}
+
static __inline u_int
rdr1(void)
{
@@ -451,6 +457,12 @@ rdr1(void)
return (data);
}
+static __inline void
+load_dr1(u_int sel)
+{
+ __asm __volatile("movl %0,%%dr1" : : "r" (sel));
+}
+
static __inline u_int
rdr2(void)
{
@@ -459,6 +471,12 @@ rdr2(void)
return (data);
}
+static __inline void
+load_dr2(u_int sel)
+{
+ __asm __volatile("movl %0,%%dr2" : : "r" (sel));
+}
+
static __inline u_int
rdr3(void)
{
@@ -467,6 +485,40 @@ rdr3(void)
return (data);
}
+static __inline void
+load_dr3(u_int sel)
+{
+ __asm __volatile("movl %0,%%dr3" : : "r" (sel));
+}
+
+static __inline u_int
+rdr4(void)
+{
+ u_int data;
+ __asm __volatile("movl %%dr4,%0" : "=r" (data));
+ return (data);
+}
+
+static __inline void
+load_dr4(u_int sel)
+{
+ __asm __volatile("movl %0,%%dr4" : : "r" (sel));
+}
+
+static __inline u_int
+rdr5(void)
+{
+ u_int data;
+ __asm __volatile("movl %%dr5,%0" : "=r" (data));
+ return (data);
+}
+
+static __inline void
+load_dr5(u_int sel)
+{
+ __asm __volatile("movl %0,%%dr5" : : "r" (sel));
+}
+
static __inline u_int
rdr6(void)
{
@@ -475,6 +527,12 @@ rdr6(void)
return (data);
}
+static __inline void
+load_dr6(u_int sel)
+{
+ __asm __volatile("movl %0,%%dr6" : : "r" (sel));
+}
+
static __inline u_int
rdr7(void)
{
@@ -483,6 +541,12 @@ rdr7(void)
return (data);
}
+static __inline void
+load_dr7(u_int sel)
+{
+ __asm __volatile("movl %0,%%dr7" : : "r" (sel));
+}
+
static __inline critical_t
critical_enter(void)
{
@@ -545,7 +609,6 @@ void ltr __P((u_short sel));
u_int rcr0 __P((void));
u_int rcr3 __P((void));
u_int rcr4 __P((void));
-void load_dr6 __P((u_int dr6));
void reset_dbregs __P((void));
__END_DECLS
OpenPOWER on IntegriCloud