1 #include "kernel/kernel.h"
2 #include "arch_proto.h"
6 int breakpoint_set(phys_bytes linaddr
, int bp
, const int flags
)
8 unsigned long dr7
, dr7flags
;
10 if (bp
>= BREAKPOINT_COUNT
)
15 switch (flags
& BREAKPOINT_FLAG_RW_MASK
) {
16 case BREAKPOINT_FLAG_RW_EXEC
: dr7flags
|= DR7_RW_EXEC(bp
); break;
17 case BREAKPOINT_FLAG_RW_WRITE
: dr7flags
|= DR7_RW_WRITE(bp
); break;
18 case BREAKPOINT_FLAG_RW_RW
: dr7flags
|= DR7_RW_RW(bp
); break;
19 default: return EINVAL
;
21 switch (flags
& BREAKPOINT_FLAG_LEN_MASK
) {
22 case BREAKPOINT_FLAG_LEN_1
: dr7flags
|= DR7_LN_1(bp
); break;
23 case BREAKPOINT_FLAG_LEN_2
: dr7flags
|= DR7_LN_2(bp
); break;
24 case BREAKPOINT_FLAG_LEN_4
: dr7flags
|= DR7_LN_4(bp
); break;
25 default: return EINVAL
;
27 switch (flags
& BREAKPOINT_FLAG_MODE_MASK
) {
28 case BREAKPOINT_FLAG_MODE_OFF
: break;
29 case BREAKPOINT_FLAG_MODE_LOCAL
: dr7flags
|= DR7_L(bp
); break;
30 case BREAKPOINT_FLAG_MODE_GLOBAL
: dr7flags
|= DR7_G(bp
); break;
31 default: return EINVAL
;
34 /* disable breakpoint before setting address */
36 dr7
&= ~(DR7_L(bp
) | DR7_G(bp
) | DR7_RW_MASK(bp
) | DR7_LN_MASK(bp
));
39 /* need to set new breakpoint? */
40 if ((flags
& BREAKPOINT_FLAG_MODE_MASK
) == BREAKPOINT_FLAG_MODE_OFF
)
43 /* set breakpoint address */
45 case 0: ld_dr0(linaddr
); break;
46 case 1: ld_dr1(linaddr
); break;
47 case 2: ld_dr2(linaddr
); break;
48 case 3: ld_dr3(linaddr
); break;
49 default: panic("%s:%d: invalid breakpoint index", __FILE__
, __LINE__
);