summaryrefslogtreecommitdiffstats
path: root/sys/i386/i386
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2015-11-12 23:49:47 +0000
committerjhb <jhb@FreeBSD.org>2015-11-12 23:49:47 +0000
commitd10f13372071e4697871503bf0a1ed4b584c55d1 (patch)
tree4ea959ce96c95014e08f9f467e8f86cf8d527e1f /sys/i386/i386
parent2285630285e9d969da6a43fe0dbb58bb71fff2f6 (diff)
downloadFreeBSD-src-d10f13372071e4697871503bf0a1ed4b584c55d1.zip
FreeBSD-src-d10f13372071e4697871503bf0a1ed4b584c55d1.tar.gz
MFC 285783:
Various changes to the registers displayed in DDB for x86. - Fix segment registers to only display the low 16 bits. - Remove unused handlers and entries for the debug registers. - Display xcr0 (if valid) in 'show sysregs'. - Add '0x' prefix to MSR values to match other values in 'show sysregs'. - MFamd64: Display various MSRs in 'show sysregs'. - Add a 'show dbregs' to display the value of debug registers. - Dynamically size the column width for register values to properly align columns on 64-bit platforms. - Display %gs for i386 in 'show registers'.
Diffstat (limited to 'sys/i386/i386')
-rw-r--r--sys/i386/i386/db_trace.c80
-rw-r--r--sys/i386/i386/machdep.c23
2 files changed, 58 insertions, 45 deletions
diff --git a/sys/i386/i386/db_trace.c b/sys/i386/i386/db_trace.c
index 644925d..8c7bbc5 100644
--- a/sys/i386/i386/db_trace.c
+++ b/sys/i386/i386/db_trace.c
@@ -48,16 +48,10 @@ __FBSDID("$FreeBSD$");
#include <ddb/db_sym.h>
#include <ddb/db_variables.h>
-static db_varfcn_t db_dr0;
-static db_varfcn_t db_dr1;
-static db_varfcn_t db_dr2;
-static db_varfcn_t db_dr3;
-static db_varfcn_t db_dr4;
-static db_varfcn_t db_dr5;
-static db_varfcn_t db_dr6;
-static db_varfcn_t db_dr7;
static db_varfcn_t db_esp;
static db_varfcn_t db_frame;
+static db_varfcn_t db_frame_seg;
+static db_varfcn_t db_gs;
static db_varfcn_t db_ss;
/*
@@ -65,10 +59,11 @@ static db_varfcn_t db_ss;
*/
#define DB_OFFSET(x) (db_expr_t *)offsetof(struct trapframe, x)
struct db_variable db_regs[] = {
- { "cs", DB_OFFSET(tf_cs), db_frame },
- { "ds", DB_OFFSET(tf_ds), db_frame },
- { "es", DB_OFFSET(tf_es), db_frame },
- { "fs", DB_OFFSET(tf_fs), db_frame },
+ { "cs", DB_OFFSET(tf_cs), db_frame_seg },
+ { "ds", DB_OFFSET(tf_ds), db_frame_seg },
+ { "es", DB_OFFSET(tf_es), db_frame_seg },
+ { "fs", DB_OFFSET(tf_fs), db_frame_seg },
+ { "gs", NULL, db_gs },
{ "ss", NULL, db_ss },
{ "eax", DB_OFFSET(tf_eax), db_frame },
{ "ecx", DB_OFFSET(tf_ecx), db_frame },
@@ -80,40 +75,8 @@ struct db_variable db_regs[] = {
{ "edi", DB_OFFSET(tf_edi), db_frame },
{ "eip", DB_OFFSET(tf_eip), db_frame },
{ "efl", DB_OFFSET(tf_eflags), db_frame },
-#define DB_N_SHOW_REGS 15 /* Don't show registers after here. */
- { "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 + DB_N_SHOW_REGS;
-
-#define DB_DRX_FUNC(reg) \
-static 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 (1); \
-}
-
-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)
+struct db_variable *db_eregs = db_regs + nitems(db_regs);
static __inline int
get_esp(struct trapframe *tf)
@@ -139,6 +102,22 @@ db_frame(struct db_variable *vp, db_expr_t *valuep, int op)
}
static int
+db_frame_seg(struct db_variable *vp, db_expr_t *valuep, int op)
+{
+ uint16_t *reg;
+
+ if (kdb_frame == NULL)
+ return (0);
+
+ reg = (uint16_t *)((uintptr_t)kdb_frame + (db_expr_t)vp->valuep);
+ if (op == DB_VAR_GET)
+ *valuep = *reg;
+ else
+ *reg = *valuep;
+ return (1);
+}
+
+static int
db_esp(struct db_variable *vp, db_expr_t *valuep, int op)
{
@@ -153,6 +132,17 @@ db_esp(struct db_variable *vp, db_expr_t *valuep, int op)
}
static int
+db_gs(struct db_variable *vp, db_expr_t *valuep, int op)
+{
+
+ if (op == DB_VAR_GET)
+ *valuep = rgs();
+ else
+ load_gs(*valuep);
+ return (1);
+}
+
+static int
db_ss(struct db_variable *vp, db_expr_t *valuep, int op)
{
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index ab543fe..f7fb369 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -2043,6 +2043,29 @@ DB_SHOW_COMMAND(sysregs, db_show_sysregs)
db_printf("cr2\t0x%08x\n", rcr2());
db_printf("cr3\t0x%08x\n", rcr3());
db_printf("cr4\t0x%08x\n", rcr4());
+ if (rcr4() & CR4_XSAVE)
+ db_printf("xcr0\t0x%016llx\n", rxcr(0));
+ if (amd_feature & (AMDID_NX | AMDID_LM))
+ db_printf("EFER\t0x%016llx\n", rdmsr(MSR_EFER));
+ if (cpu_feature2 & (CPUID2_VMX | CPUID2_SMX))
+ db_printf("FEATURES_CTL\t0x%016llx\n",
+ rdmsr(MSR_IA32_FEATURE_CONTROL));
+ if ((cpu_vendor_id == CPU_VENDOR_INTEL ||
+ cpu_vendor_id == CPU_VENDOR_AMD) && CPUID_TO_FAMILY(cpu_id) >= 6)
+ db_printf("DEBUG_CTL\t0x%016llx\n", rdmsr(MSR_DEBUGCTLMSR));
+ if (cpu_feature & CPUID_PAT)
+ db_printf("PAT\t0x%016llx\n", rdmsr(MSR_PAT));
+}
+
+DB_SHOW_COMMAND(dbregs, db_show_dbregs)
+{
+
+ db_printf("dr0\t0x%08x\n", rdr0());
+ db_printf("dr1\t0x%08x\n", rdr1());
+ db_printf("dr2\t0x%08x\n", rdr2());
+ db_printf("dr3\t0x%08x\n", rdr3());
+ db_printf("dr6\t0x%08x\n", rdr6());
+ db_printf("dr7\t0x%08x\n", rdr7());
}
#endif
OpenPOWER on IntegriCloud