1 /* 2 * Copyright 2005, Ingo Weinhold, bonefish@users.sf.net. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef _KERNEL_ARCH_X86_USER_DEBUGGER_H 6 #define _KERNEL_ARCH_X86_USER_DEBUGGER_H 7 8 #define ARCH_INIT_USER_DEBUG i386_init_user_debug 9 10 // number of breakpoints the CPU supports 11 // Actually it supports 4, but DR3 is used to hold the struct thread*. 12 enum { 13 X86_BREAKPOINT_COUNT = 3, 14 }; 15 16 // debug status register DR6 17 enum { 18 X86_DR6_B0 = 0, // breakpoint condition detected 19 X86_DR6_B1 = 1, // 20 X86_DR6_B2 = 2, // 21 X86_DR6_B3 = 3, // 22 X86_DR6_BD = 13, // debug register access detected 23 X86_DR6_BS = 14, // single step 24 X86_DR6_BT = 15, // task switch 25 26 X86_DR6_BREAKPOINT_MASK = (1 << X86_DR6_B0) | (1 << X86_DR6_B1) 27 | (1 << X86_DR6_B2) | (1 << X86_DR6_B3), 28 }; 29 30 // debug control register DR7 layout: 31 // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 32 // LEN3 R/W3 LEN2 R/W2 LEN1 R/W1 LEN0 R/W0 33 // 34 // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 35 // 0 0 GD 0 0 1 GE LE G3 L3 G2 L2 G1 L1 G0 L0 36 // 37 enum { 38 X86_DR7_L0 = 0, // local/global breakpoints enable 39 X86_DR7_G0 = 1, // 40 X86_DR7_L1 = 2, // 41 X86_DR7_G1 = 3, // 42 X86_DR7_L2 = 4, // 43 X86_DR7_G2 = 5, // 44 X86_DR7_L3 = 6, // 45 X86_DR7_G3 = 7, // 46 X86_DR7_LE = 8, // local/global exact breakpoint 47 X86_DR7_GE = 9, // 48 X86_DR7_GD = 13, // general detect enable: disallows debug 49 // register access 50 X86_DR7_RW0_LSB = 16, // breakpoints type and len 51 X86_DR7_LEN0_LSB = 18, // 52 X86_DR7_RW1_LSB = 20, // 53 X86_DR7_LEN1_LSB = 22, // 54 X86_DR7_RW2_LSB = 24, // 55 X86_DR7_LEN2_LSB = 26, // 56 X86_DR7_RW3_LSB = 28, // 57 X86_DR7_LEN3_LSB = 30, // 58 59 X86_BREAKPOINTS_DISABLED_DR7 60 = (1 << 10) | (1 << X86_DR7_GE) | (1 << X86_DR7_LE), 61 // all breakpoints disabled 62 }; 63 64 // the EFLAGS flags we need 65 enum { 66 X86_EFLAGS_CF = 0, // carry flag 67 X86_EFLAGS_PF = 2, // parity flag 68 X86_EFLAGS_AF = 4, // auxiliary carry flag (adjust flag) 69 X86_EFLAGS_ZF = 6, // zero flag 70 X86_EFLAGS_SF = 7, // sign flag 71 X86_EFLAGS_TF = 8, // trap flag (single stepping) 72 X86_EFLAGS_DF = 10, // direction flag 73 X86_EFLAGS_OF = 11, // overflow flag 74 X86_EFLAGS_RF = 16, // resume flag (skips instruction breakpoint) 75 76 X86_EFLAGS_USER_SETTABLE_FLAGS 77 = (1 << X86_EFLAGS_CF) | (1 << X86_EFLAGS_PF) | (1 << X86_EFLAGS_AF) 78 | (1 << X86_EFLAGS_ZF) | (1 << X86_EFLAGS_SF) | (1 << X86_EFLAGS_DF) 79 | (1 << X86_EFLAGS_OF), 80 }; 81 82 // x86 breakpoint types 83 enum { 84 X86_INSTRUCTION_BREAKPOINT = 0x0, 85 X86_DATA_WRITE_BREAKPOINT = 0x1, 86 X86_IO_READ_WRITE_BREAKPOINT = 0x2, // >= 586 87 X86_DATA_READ_WRITE_BREAKPOINT = 0x3, 88 }; 89 90 // x86 breakpoint lengths 91 enum { 92 X86_BREAKPOINT_LENGTH_1 = 0x0, 93 X86_BREAKPOINT_LENGTH_2 = 0x1, 94 X86_BREAKPOINT_LENGTH_4 = 0x3, 95 }; 96 97 // thread debug flags 98 enum { 99 X86_THREAD_DEBUG_DR7_SET = 0x01, 100 }; 101 102 struct arch_breakpoint { 103 void *address; // NULL, if deactivated 104 uint32 type; // one of the architecture types above 105 uint32 length; // one of the length values above 106 }; 107 108 struct arch_team_debug_info { 109 struct arch_breakpoint breakpoints[X86_BREAKPOINT_COUNT]; 110 111 uint32 dr7; // debug control register DR7 112 }; 113 114 struct arch_thread_debug_info { 115 uint32 flags; 116 }; 117 118 #ifdef __cplusplus 119 extern "C" { 120 #endif 121 122 struct iframe; 123 struct thread; 124 125 extern void i386_init_user_debug_at_kernel_exit(struct iframe *frame); 126 extern void i386_exit_user_debug_at_kernel_entry(); 127 extern void i386_reinit_user_debug_after_context_switch(struct thread *thread); 128 129 extern int i386_handle_debug_exception(struct iframe *frame); 130 extern int i386_handle_breakpoint_exception(struct iframe *frame); 131 132 extern void i386_init_user_debug(); 133 134 #ifdef __cplusplus 135 } 136 #endif 137 138 #endif // _KERNEL_ARCH_X86_USER_DEBUGGER_H 139