coverity appeasement
[minix.git] / kernel / arch / i386 / breakpoints.c
blob0965d9e5b5ed759c8149fd96c3a3962945e88a50
1 #include "kernel/kernel.h"
2 #include "arch_proto.h"
4 #include "debugreg.h"
6 int breakpoint_set(phys_bytes linaddr, int bp, const int flags)
8 unsigned long dr7, dr7flags;
10 if (bp >= BREAKPOINT_COUNT)
11 return EINVAL;
13 /* convert flags */
14 dr7flags = 0;
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 */
35 dr7 = st_dr7();
36 dr7 &= ~(DR7_L(bp) | DR7_G(bp) | DR7_RW_MASK(bp) | DR7_LN_MASK(bp));
37 ld_dr7(dr7);
39 /* need to set new breakpoint? */
40 if ((flags & BREAKPOINT_FLAG_MODE_MASK) == BREAKPOINT_FLAG_MODE_OFF)
41 return 0;
43 /* set breakpoint address */
44 switch (bp) {
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__);
52 /* set new flags */
53 dr7 |= dr7flags;
54 ld_dr7(dr7);
55 return 0;