From 86cc722477a3e462b1f0ac4442fec7e79596745d Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Wed, 2 Mar 2005 00:05:02 +0000 Subject: [PATCH] * DR3 is used for holding the pointer to the current struct thread*, so we only have 3 debug registers available for break-/watchpoints. * Added definitions for debug status register DR6. Reordered DR7 defs to ascending order. Added definitions for the EFLAGS flags we need. * Added arch_thread_debug_info structure and related definitions. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@11525 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/arch/x86/arch_user_debugger.h | 88 ++++++++++++++----- 1 file changed, 68 insertions(+), 20 deletions(-) diff --git a/headers/private/kernel/arch/x86/arch_user_debugger.h b/headers/private/kernel/arch/x86/arch_user_debugger.h index eb2d077317..6bf00f45e2 100644 --- a/headers/private/kernel/arch/x86/arch_user_debugger.h +++ b/headers/private/kernel/arch/x86/arch_user_debugger.h @@ -6,8 +6,23 @@ #define _KERNEL_ARCH_X86_USER_DEBUGGER_H // number of breakpoints the CPU supports +// Actually it supports 4, but DR3 is used to hold the struct thread*. enum { - X86_BREAKPOINT_COUNT = 4, + X86_BREAKPOINT_COUNT = 3, +}; + +// debug status register DR6 +enum { + X86_DR6_B0 = 0, // breakpoint condition detected + X86_DR6_B1 = 1, // + X86_DR6_B2 = 2, // + X86_DR6_B3 = 3, // + X86_DR6_BD = 13, // debug register access detected + X86_DR6_BS = 14, // single step + X86_DR6_BT = 15, // task switch + + X86_DR6_BREAKPOINT_MASK = (1 << X86_DR6_B0) | (1 << X86_DR6_B1) + | (1 << X86_DR6_B2) | (1 << X86_DR6_B3), }; // debug control register DR7 layout: @@ -18,32 +33,38 @@ enum { // 0 0 GD 0 0 1 GE LE G3 L3 G2 L2 G1 L1 G0 L0 // enum { - X86_DR7_LEN3_LSB = 30, // breakpoints len and type - X86_DR7_RW3_LSB = 28, // - X86_DR7_LEN2_LSB = 26, // - X86_DR7_RW2_LSB = 24, // - X86_DR7_LEN1_LSB = 22, // - X86_DR7_RW1_LSB = 20, // - X86_DR7_LEN0_LSB = 18, // - X86_DR7_RW0_LSB = 16, // - X86_DR7_GD = 13, // general detect enable: disallows debug + X86_DR7_L0 = 0, // local/global breakpoints enable + X86_DR7_G0 = 1, // + X86_DR7_L1 = 2, // + X86_DR7_G1 = 3, // + X86_DR7_L2 = 4, // + X86_DR7_G2 = 5, // + X86_DR7_L3 = 6, // + X86_DR7_G3 = 7, // + X86_DR7_LE = 8, // local/global exact breakpoint + X86_DR7_GE = 9, // + X86_DR7_GD = 13, // general detect enable: disallows debug // register access - X86_DR7_GE = 9, // global/local exact breakpoint - X86_DR7_LE = 8, // - X86_DR7_G3 = 7, // global/local breakpoints enable - X86_DR7_L3 = 6, // - X86_DR7_G2 = 5, // - X86_DR7_L2 = 4, // - X86_DR7_G1 = 3, // - X86_DR7_L1 = 2, // - X86_DR7_G0 = 1, // - X86_DR7_L0 = 0, // + X86_DR7_RW0_LSB = 16, // breakpoints type and len + X86_DR7_LEN0_LSB = 18, // + X86_DR7_RW1_LSB = 20, // + X86_DR7_LEN1_LSB = 22, // + X86_DR7_RW2_LSB = 24, // + X86_DR7_LEN2_LSB = 26, // + X86_DR7_RW3_LSB = 28, // + X86_DR7_LEN3_LSB = 30, // X86_BREAKPOINTS_DISABLED_DR7 = (1 << 10) | (1 << X86_DR7_GE) | (1 << X86_DR7_LE), // all breakpoints disabled }; +// the EFLAGS flags we need +enum { + X86_EFLAGS_TF = 8, // trap flag (single stepping) + X86_EFLAGS_RF = 16, // resume flag (skips instruction breakpoint) +}; + // x86 breakpoint types enum { X86_INSTRUCTION_BREAKPOINT = 0x0, @@ -59,6 +80,11 @@ enum { X86_BREAKPOINT_LENGTH_4 = 0x3, }; +// thread debug flags +enum { + X86_THREAD_DEBUG_DR7_SET = 0x01, +}; + struct arch_breakpoint { void *address; // NULL, if deactivated uint32 type; // one of the architecture types above @@ -71,4 +97,26 @@ struct arch_team_debug_info { uint32 dr7; // debug control register DR7 }; +struct arch_thread_debug_info { + uint32 flags; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +struct iframe; +struct thread; + +extern void i386_init_user_debug_at_kernel_exit(struct iframe *frame); +extern void i386_exit_user_debug_at_kernel_entry(); +extern void i386_reinit_user_debug_after_context_switch(struct thread *thread); + +extern int i386_handle_debug_exception(struct iframe *frame); +extern int i386_handle_breakpoint_exception(struct iframe *frame); + +#ifdef __cplusplus +} +#endif + #endif // _KERNEL_ARCH_X86_USER_DEBUGGER_H