1#ifndef _ASM_X86_DEBUGREG_H
2#define _ASM_X86_DEBUGREG_H
3
4
5
6
7#define DR_FIRSTADDR 0
8#define DR_LASTADDR 3
9
10#define DR_STATUS 6
11#define DR_CONTROL 7
12
13
14
15
16
17
18#define DR6_RESERVED (0xFFFF0FF0)
19
20#define DR_TRAP0 (0x1)
21#define DR_TRAP1 (0x2)
22#define DR_TRAP2 (0x4)
23#define DR_TRAP3 (0x8)
24#define DR_TRAP_BITS (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)
25
26#define DR_STEP (0x4000)
27#define DR_SWITCH (0x8000)
28
29
30
31
32
33
34
35#define DR_CONTROL_SHIFT 16
36#define DR_CONTROL_SIZE 4
37
38#define DR_RW_EXECUTE (0x0)
39#define DR_RW_WRITE (0x1)
40#define DR_RW_READ (0x3)
41
42#define DR_LEN_1 (0x0)
43#define DR_LEN_2 (0x4)
44#define DR_LEN_4 (0xC)
45#define DR_LEN_8 (0x8)
46
47
48
49
50
51
52
53
54#define DR_LOCAL_ENABLE_SHIFT 0
55#define DR_GLOBAL_ENABLE_SHIFT 1
56#define DR_LOCAL_ENABLE (0x1)
57#define DR_GLOBAL_ENABLE (0x2)
58#define DR_ENABLE_SIZE 2
59
60#define DR_LOCAL_ENABLE_MASK (0x55)
61#define DR_GLOBAL_ENABLE_MASK (0xAA)
62
63
64
65
66
67#ifdef __i386__
68#define DR_CONTROL_RESERVED (0xFC00)
69#else
70#define DR_CONTROL_RESERVED (0xFFFFFFFF0000FC00UL)
71#endif
72
73#define DR_LOCAL_SLOWDOWN (0x100)
74#define DR_GLOBAL_SLOWDOWN (0x200)
75
76
77
78
79#ifdef __KERNEL__
80
81#include <linux/bug.h>
82
83DECLARE_PER_CPU(unsigned long, cpu_dr7);
84
85#ifndef CONFIG_PARAVIRT
86
87
88
89#define get_debugreg(var, register) \
90 (var) = native_get_debugreg(register)
91#define set_debugreg(value, register) \
92 native_set_debugreg(register, value)
93#endif
94
95static inline unsigned long native_get_debugreg(int regno)
96{
97 unsigned long val = 0;
98
99 switch (regno) {
100 case 0:
101 asm("mov %%db0, %0" :"=r" (val));
102 break;
103 case 1:
104 asm("mov %%db1, %0" :"=r" (val));
105 break;
106 case 2:
107 asm("mov %%db2, %0" :"=r" (val));
108 break;
109 case 3:
110 asm("mov %%db3, %0" :"=r" (val));
111 break;
112 case 6:
113 asm("mov %%db6, %0" :"=r" (val));
114 break;
115 case 7:
116 asm("mov %%db7, %0" :"=r" (val));
117 break;
118 default:
119 BUG();
120 }
121 return val;
122}
123
124static inline void native_set_debugreg(int regno, unsigned long value)
125{
126 switch (regno) {
127 case 0:
128 asm("mov %0, %%db0" ::"r" (value));
129 break;
130 case 1:
131 asm("mov %0, %%db1" ::"r" (value));
132 break;
133 case 2:
134 asm("mov %0, %%db2" ::"r" (value));
135 break;
136 case 3:
137 asm("mov %0, %%db3" ::"r" (value));
138 break;
139 case 6:
140 asm("mov %0, %%db6" ::"r" (value));
141 break;
142 case 7:
143 asm("mov %0, %%db7" ::"r" (value));
144 break;
145 default:
146 BUG();
147 }
148}
149
150static inline void hw_breakpoint_disable(void)
151{
152
153 set_debugreg(0UL, 7);
154
155
156 set_debugreg(0UL, 0);
157 set_debugreg(0UL, 1);
158 set_debugreg(0UL, 2);
159 set_debugreg(0UL, 3);
160}
161
162static inline int hw_breakpoint_active(void)
163{
164 return __this_cpu_read(cpu_dr7) & DR_GLOBAL_ENABLE_MASK;
165}
166
167extern void aout_dump_debugregs(struct user *dump);
168
169extern void hw_breakpoint_restore(void);
170
171#ifdef CONFIG_X86_64
172DECLARE_PER_CPU(int, debug_stack_usage);
173static inline void debug_stack_usage_inc(void)
174{
175 __get_cpu_var(debug_stack_usage)++;
176}
177static inline void debug_stack_usage_dec(void)
178{
179 __get_cpu_var(debug_stack_usage)--;
180}
181int is_debug_stack(unsigned long addr);
182void debug_stack_set_zero(void);
183void debug_stack_reset(void);
184#else
185static inline int is_debug_stack(unsigned long addr) { return 0; }
186static inline void debug_stack_set_zero(void) { }
187static inline void debug_stack_reset(void) { }
188static inline void debug_stack_usage_inc(void) { }
189static inline void debug_stack_usage_dec(void) { }
190#endif
191
192
193#endif
194
195#endif
196