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