Subversion Repositories HelenOS-historic

Rev

Rev 1074 | Rev 1196 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1074 Rev 1077
Line 35... Line 35...
35
#include <interrupt.h>
35
#include <interrupt.h>
36
#include <arch/asm.h>
36
#include <arch/asm.h>
37
#include <arch/cpu.h>
37
#include <arch/cpu.h>
38
#include <debug.h>
38
#include <debug.h>
39
#include <func.h>
39
#include <func.h>
-
 
40
#include <smp/ipi.h>
40
 
41
 
41
typedef struct  {
42
typedef struct  {
42
    __address address;      /**< Breakpoint address */
43
    __address address;      /**< Breakpoint address */
43
    int flags;              /**< Flags regarding breakpoint */
44
    int flags;              /**< Flags regarding breakpoint */
44
    int counter;            /**< How many times the exception occured */
45
    int counter;            /**< How many times the exception occured */
Line 53... Line 54...
53
    .description = "Print breakpoint table.",
54
    .description = "Print breakpoint table.",
54
    .func = cmd_print_breakpoints,
55
    .func = cmd_print_breakpoints,
55
    .argc = 0,
56
    .argc = 0,
56
};
57
};
57
 
58
 
-
 
59
#ifndef CONFIG_DEBUG_AS_WATCHPOINT
-
 
60
 
58
static int cmd_del_breakpoint(cmd_arg_t *argv);
61
static int cmd_del_breakpoint(cmd_arg_t *argv);
59
static cmd_arg_t del_argv = {
62
static cmd_arg_t del_argv = {
60
    .type = ARG_TYPE_INT
63
    .type = ARG_TYPE_INT
61
};
64
};
62
static cmd_info_t delbkpt_info = {
65
static cmd_info_t delbkpt_info = {
Line 88... Line 91...
88
    .func = cmd_add_breakpoint,
91
    .func = cmd_add_breakpoint,
89
    .argc = 1,
92
    .argc = 1,
90
    .argv = &addw_argv
93
    .argv = &addw_argv
91
};
94
};
92
 
95
 
-
 
96
#endif
93
 
97
 
94
/** Print table of active breakpoints */
98
/** Print table of active breakpoints */
95
int cmd_print_breakpoints(cmd_arg_t *argv)
99
int cmd_print_breakpoints(cmd_arg_t *argv)
96
{
100
{
97
    int i;
101
    int i;
Line 107... Line 111...
107
            printf("\n");
111
            printf("\n");
108
        }
112
        }
109
    return 1;
113
    return 1;
110
}
114
}
111
 
115
 
-
 
116
/* Setup DR register according to table */
-
 
117
static void setup_dr(int curidx)
-
 
118
{
-
 
119
    __native dr7;
-
 
120
    bpinfo_t *cur = &breakpoints[curidx];
-
 
121
    int flags = breakpoints[curidx].flags;
-
 
122
 
-
 
123
    /* Disable breakpoint in DR7 */
-
 
124
    dr7 = read_dr7();
-
 
125
    dr7 &= ~(0x2 << (curidx*2));
-
 
126
 
-
 
127
    if (cur->address) { /* Setup DR register */
-
 
128
        /* Set breakpoint to debug registers */
-
 
129
        switch (curidx) {
-
 
130
        case 0:
-
 
131
            write_dr0(cur->address);
-
 
132
            break;
-
 
133
        case 1:
-
 
134
            write_dr1(cur->address);
-
 
135
            break;
-
 
136
        case 2:
-
 
137
            write_dr2(cur->address);
-
 
138
            break;
-
 
139
        case 3:
-
 
140
            write_dr3(cur->address);
-
 
141
            break;
-
 
142
        }
-
 
143
        /* Set type to requested breakpoint & length*/
-
 
144
        dr7 &= ~ (0x3 << (16 + 4*curidx));
-
 
145
        dr7 &= ~ (0x3 << (18 + 4*curidx));
-
 
146
        if ((flags & BKPOINT_INSTR)) {
-
 
147
            ;
-
 
148
        } else {
-
 
149
            if (sizeof(int) == 4)
-
 
150
                dr7 |= ((__native) 0x3) << (18 + 4*curidx);
-
 
151
            else /* 8 */
-
 
152
                dr7 |= ((__native) 0x2) << (18 + 4*curidx);
-
 
153
           
-
 
154
            if ((flags & BKPOINT_WRITE))
-
 
155
                dr7 |= ((__native) 0x1) << (16 + 4*curidx);
-
 
156
            else if ((flags & BKPOINT_READ_WRITE))
-
 
157
                dr7 |= ((__native) 0x3) << (16 + 4*curidx);
-
 
158
        }
-
 
159
 
-
 
160
        /* Enable global breakpoint */
-
 
161
        dr7 |= 0x2 << (curidx*2);
-
 
162
 
-
 
163
        write_dr7(dr7);
-
 
164
       
-
 
165
    }
-
 
166
}
-
 
167
   
112
/** Enable hardware breakpoint
168
/** Enable hardware breakpoint
113
 *
169
 *
114
 *
170
 *
115
 * @param where Address of HW breakpoint
171
 * @param where Address of HW breakpoint
116
 * @param flags Type of breakpoint (EXECUTE, WRITE)
172
 * @param flags Type of breakpoint (EXECUTE, WRITE)
117
 * @return Debug slot on success, -1 - no available HW breakpoint
173
 * @return Debug slot on success, -1 - no available HW breakpoint
118
 */
174
 */
119
int breakpoint_add(void * where, int flags)
175
int breakpoint_add(void * where, int flags, int curidx)
120
{
176
{
121
    bpinfo_t *cur = NULL;
-
 
122
    int curidx;
-
 
123
    ipl_t ipl;
177
    ipl_t ipl;
124
    int i;
178
    int i;
125
    __native dr7;
179
    bpinfo_t *cur;
126
 
180
 
127
    ASSERT( flags & (BKPOINT_INSTR | BKPOINT_WRITE | BKPOINT_READ_WRITE));
181
    ASSERT( flags & (BKPOINT_INSTR | BKPOINT_WRITE | BKPOINT_READ_WRITE));
128
 
182
 
129
    ipl = interrupts_disable();
183
    ipl = interrupts_disable();
130
    spinlock_lock(&bkpoint_lock);
184
    spinlock_lock(&bkpoint_lock);
131
   
185
   
-
 
186
    if (curidx == -1) {
132
    /* Find free space in slots */
187
        /* Find free space in slots */
133
    for (i=0; i<BKPOINTS_MAX; i++)
188
        for (i=0; i<BKPOINTS_MAX; i++)
134
        if (!breakpoints[i].address) {
189
            if (!breakpoints[i].address) {
135
            cur = &breakpoints[i];
-
 
136
            curidx = i;
190
                curidx = i;
137
            break;
191
                break;
-
 
192
            }
-
 
193
        if (curidx == -1) {
-
 
194
            /* Too many breakpoints */
-
 
195
            spinlock_unlock(&bkpoint_lock);
-
 
196
            interrupts_restore(ipl);
-
 
197
            return -1;
138
        }
198
        }
139
    if (!cur) {
-
 
140
        /* Too many breakpoints */
-
 
141
        spinlock_unlock(&bkpoint_lock);
-
 
142
        interrupts_restore(ipl);
-
 
143
        return -1;
-
 
144
    }
199
    }
-
 
200
    cur = &breakpoints[curidx];
-
 
201
 
145
    cur->address = (__address) where;
202
    cur->address = (__address) where;
146
    cur->flags = flags;
203
    cur->flags = flags;
147
    cur->counter = 0;
204
    cur->counter = 0;
148
 
205
 
149
    /* Set breakpoint to debug registers */
-
 
150
    switch (curidx) {
206
    setup_dr(curidx);
151
    case 0:
-
 
152
        write_dr0(cur->address);
-
 
153
        break;
-
 
154
    case 1:
-
 
155
        write_dr1(cur->address);
-
 
156
        break;
-
 
157
    case 2:
-
 
158
        write_dr2(cur->address);
-
 
159
        break;
-
 
160
    case 3:
-
 
161
        write_dr3(cur->address);
-
 
162
        break;
-
 
163
    }
-
 
164
    dr7 = read_dr7();
-
 
165
    /* Set type to requested breakpoint & length*/
-
 
166
    dr7 &= ~ (0x3 << (16 + 4*curidx));
-
 
167
    dr7 &= ~ (0x3 << (18 + 4*curidx));
-
 
168
    if ((flags & BKPOINT_INSTR)) {
-
 
169
        printf("Instr breakpoint\n");
-
 
170
        ;
-
 
171
    } else {
-
 
172
        if (sizeof(int) == 4)
-
 
173
            dr7 |= 0x3 << (18 + 4*curidx);
-
 
174
        else /* 8 */
-
 
175
            dr7 |= 0x2 << (18 + 4*curidx);
-
 
176
           
-
 
177
        if ((flags & BKPOINT_WRITE))
-
 
178
            dr7 |= 0x1 << (16 + 4*curidx);
-
 
179
        else if ((flags & BKPOINT_READ_WRITE))
-
 
180
            dr7 |= 0x3 << (16 + 4*curidx);
-
 
181
    }
-
 
182
 
-
 
183
    /* Enable global breakpoint */
-
 
184
    dr7 |= 0x2 << (curidx*2);
-
 
185
 
-
 
186
    write_dr7(dr7);
-
 
187
 
207
 
188
    spinlock_unlock(&bkpoint_lock);
208
    spinlock_unlock(&bkpoint_lock);
189
    interrupts_restore(ipl);
209
    interrupts_restore(ipl);
190
 
210
 
-
 
211
    /* Send IPI */
-
 
212
#ifdef CONFIG_SMP
-
 
213
//  ipi_broadcast(VECTOR_DEBUG_IPI);    
-
 
214
#endif  
-
 
215
 
191
    return curidx;
216
    return curidx;
192
}
217
}
193
 
218
 
194
#ifdef amd64
219
#ifdef amd64
195
# define getip(x)  ((x)->rip)
220
# define getip(x)  ((x)->rip)
Line 219... Line 244...
219
    atomic_set(&haltstate,1);
244
    atomic_set(&haltstate,1);
220
    kconsole("debug");
245
    kconsole("debug");
221
    atomic_set(&haltstate,0);
246
    atomic_set(&haltstate,0);
222
}
247
}
223
 
248
 
224
static void debug_exception(int n, istate_t *istate)
-
 
225
{
-
 
226
    __native dr6;
-
 
227
    int i;
-
 
228
   
-
 
229
    /* Set RF to restart the instruction  */
-
 
230
#ifdef amd64       
-
 
231
    istate->rflags |= RFLAGS_RF;
-
 
232
#else
-
 
233
    istate->eflags |= EFLAGS_RF;
-
 
234
#endif
-
 
235
 
-
 
236
    dr6 = read_dr6();
-
 
237
    for (i=0; i < BKPOINTS_MAX; i++) {
-
 
238
        if (dr6 & (1 << i)) {
-
 
239
            dr6 &= ~ (1 << i);
-
 
240
            write_dr6(dr6);
-
 
241
           
-
 
242
            handle_exception(i, istate);
-
 
243
        }
-
 
244
    }
-
 
245
}
-
 
246
 
-
 
247
void breakpoint_del(int slot)
249
void breakpoint_del(int slot)
248
{
250
{
249
    bpinfo_t *cur;
251
    bpinfo_t *cur;
250
    ipl_t ipl;
252
    ipl_t ipl;
251
    __native dr7;
-
 
252
 
253
 
253
    ipl = interrupts_disable();
254
    ipl = interrupts_disable();
254
    spinlock_lock(&bkpoint_lock);
255
    spinlock_lock(&bkpoint_lock);
255
 
256
 
256
    cur = &breakpoints[slot];
257
    cur = &breakpoints[slot];
Line 260... Line 261...
260
        return;
261
        return;
261
    }
262
    }
262
 
263
 
263
    cur->address = NULL;
264
    cur->address = NULL;
264
 
265
 
265
    /* Disable breakpoint in DR7 */
-
 
266
    dr7 = read_dr7();
-
 
267
    dr7 &= ~(0x2 << (slot*2));
-
 
268
    write_dr7(dr7);
266
    setup_dr(slot);
269
 
267
 
270
    spinlock_unlock(&bkpoint_lock);
268
    spinlock_unlock(&bkpoint_lock);
271
    interrupts_restore(ipl);
269
    interrupts_restore(ipl);
-
 
270
#ifdef CONFIG_SMP
-
 
271
//  ipi_broadcast(VECTOR_DEBUG_IPI);    
-
 
272
#endif
272
}
273
}
273
 
274
 
-
 
275
#ifndef CONFIG_DEBUG_AS_WATCHPOINT
-
 
276
 
274
/** Remove breakpoint from table */
277
/** Remove breakpoint from table */
275
int cmd_del_breakpoint(cmd_arg_t *argv)
278
int cmd_del_breakpoint(cmd_arg_t *argv)
276
{
279
{
277
    if (argv->intval < 0 || argv->intval > BKPOINTS_MAX) {
280
    if (argv->intval < 0 || argv->intval > BKPOINTS_MAX) {
278
        printf("Invalid breakpoint number.\n");
281
        printf("Invalid breakpoint number.\n");
Line 284... Line 287...
284
 
287
 
285
/** Add new breakpoint to table */
288
/** Add new breakpoint to table */
286
static int cmd_add_breakpoint(cmd_arg_t *argv)
289
static int cmd_add_breakpoint(cmd_arg_t *argv)
287
{
290
{
288
    int flags;
291
    int flags;
-
 
292
    int id;
289
 
293
 
290
    if (argv == &add_argv) {
294
    if (argv == &add_argv) {
291
        flags = BKPOINT_INSTR;
295
        flags = BKPOINT_INSTR;
292
    } else { /* addwatchp */
296
    } else { /* addwatchp */
293
        flags = BKPOINT_WRITE;
297
        flags = BKPOINT_WRITE;
294
    }
298
    }
295
    printf("Adding breakpoint on address: %p\n", argv->intval);
299
    printf("Adding breakpoint on address: %p\n", argv->intval);
296
    if (breakpoint_add((void *)argv->intval, flags))
300
    id = breakpoint_add((void *)argv->intval, flags, -1);
-
 
301
    if (id < 0)
297
        printf("Add breakpoint failed.\n");
302
        printf("Add breakpoint failed.\n");
-
 
303
    else
-
 
304
        printf("Added breakpoint %d.\n", id);
298
   
305
   
299
    return 1;
306
    return 1;
300
}
307
}
-
 
308
#endif
-
 
309
 
-
 
310
static void debug_exception(int n, istate_t *istate)
-
 
311
{
-
 
312
    __native dr6;
-
 
313
    int i;
-
 
314
   
-
 
315
    /* Set RF to restart the instruction  */
-
 
316
#ifdef amd64       
-
 
317
    istate->rflags |= RFLAGS_RF;
-
 
318
#else
-
 
319
    istate->eflags |= EFLAGS_RF;
-
 
320
#endif
-
 
321
 
-
 
322
    dr6 = read_dr6();
-
 
323
    for (i=0; i < BKPOINTS_MAX; i++) {
-
 
324
        if (dr6 & (1 << i)) {
-
 
325
            dr6 &= ~ (1 << i);
-
 
326
            write_dr6(dr6);
-
 
327
           
-
 
328
            handle_exception(i, istate);
-
 
329
        }
-
 
330
    }
-
 
331
}
-
 
332
 
-
 
333
#ifdef CONFIG_SMP
-
 
334
static void debug_ipi(int n, istate_t *istate)
-
 
335
{
-
 
336
    int i;
-
 
337
 
-
 
338
    spinlock_lock(&bkpoint_lock);
-
 
339
    for (i=0; i < BKPOINTS_MAX; i++)
-
 
340
        setup_dr(i);
-
 
341
    spinlock_unlock(&bkpoint_lock);
-
 
342
}
-
 
343
#endif
301
 
344
 
302
/** Initialize debugger */
345
/** Initialize debugger */
303
void debugger_init()
346
void debugger_init()
304
{
347
{
305
    int i;
348
    int i;
Line 309... Line 352...
309
   
352
   
310
    cmd_initialize(&bkpts_info);
353
    cmd_initialize(&bkpts_info);
311
    if (!cmd_register(&bkpts_info))
354
    if (!cmd_register(&bkpts_info))
312
        panic("could not register command %s\n", bkpts_info.name);
355
        panic("could not register command %s\n", bkpts_info.name);
313
 
356
 
-
 
357
#ifndef CONFIG_DEBUG_AS_WATCHPOINT
314
    cmd_initialize(&delbkpt_info);
358
    cmd_initialize(&delbkpt_info);
315
    if (!cmd_register(&delbkpt_info))
359
    if (!cmd_register(&delbkpt_info))
316
        panic("could not register command %s\n", delbkpt_info.name);
360
        panic("could not register command %s\n", delbkpt_info.name);
317
 
361
 
318
    cmd_initialize(&addbkpt_info);
362
    cmd_initialize(&addbkpt_info);
Line 320... Line 364...
320
        panic("could not register command %s\n", addbkpt_info.name);
364
        panic("could not register command %s\n", addbkpt_info.name);
321
 
365
 
322
    cmd_initialize(&addwatchp_info);
366
    cmd_initialize(&addwatchp_info);
323
    if (!cmd_register(&addwatchp_info))
367
    if (!cmd_register(&addwatchp_info))
324
        panic("could not register command %s\n", addwatchp_info.name);
368
        panic("could not register command %s\n", addwatchp_info.name);
-
 
369
#endif
325
   
370
   
326
    exc_register(VECTOR_DEBUG, "debugger",
371
    exc_register(VECTOR_DEBUG, "debugger",
327
             debug_exception);
372
             debug_exception);
-
 
373
#ifdef CONFIG_SMP
-
 
374
    exc_register(VECTOR_DEBUG_IPI, "debugger_smp",
-
 
375
             debug_ipi);
-
 
376
#endif
328
}
377
}