Subversion Repositories HelenOS

Rev

Rev 3424 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3424 Rev 4377
Line 35... Line 35...
35
#include <arch/debugger.h>
35
#include <arch/debugger.h>
36
#include <arch/barrier.h>
36
#include <arch/barrier.h>
37
#include <memstr.h>
37
#include <memstr.h>
38
#include <console/kconsole.h>
38
#include <console/kconsole.h>
39
#include <console/cmd.h>
39
#include <console/cmd.h>
40
#include <symtab.h>
-
 
41
#include <print.h>
40
#include <print.h>
42
#include <panic.h>
41
#include <panic.h>
43
#include <arch.h>
42
#include <arch.h>
44
#include <arch/cp0.h>
43
#include <arch/cp0.h>
45
#include <func.h>
44
#include <func.h>
-
 
45
#include <symtab.h>
46
 
46
 
47
bpinfo_t breakpoints[BKPOINTS_MAX];
47
bpinfo_t breakpoints[BKPOINTS_MAX];
48
SPINLOCK_INITIALIZE(bkpoint_lock);
48
SPINLOCK_INITIALIZE(bkpoint_lock);
49
 
49
 
-
 
50
#ifdef CONFIG_KCONSOLE
-
 
51
 
50
static int cmd_print_breakpoints(cmd_arg_t *argv);
52
static int cmd_print_breakpoints(cmd_arg_t *argv);
51
static cmd_info_t bkpts_info = {
53
static cmd_info_t bkpts_info = {
52
    .name = "bkpts",
54
    .name = "bkpts",
53
    .description = "Print breakpoint table.",
55
    .description = "Print breakpoint table.",
54
    .func = cmd_print_breakpoints,
56
    .func = cmd_print_breakpoints,
Line 121... Line 123...
121
    {0xfc000000, 0x0c000000}, /* JAL */
123
    {0xfc000000, 0x0c000000}, /* JAL */
122
    {0xfc1f07ff, 0x00000009}, /* JALR */
124
    {0xfc1f07ff, 0x00000009}, /* JALR */
123
    {0, 0} /* EndOfTable */
125
    {0, 0} /* EndOfTable */
124
};
126
};
125
 
127
 
-
 
128
 
126
/** Test, if the given instruction is a jump or branch instruction
129
/** Test, if the given instruction is a jump or branch instruction
127
 *
130
 *
128
 * @param instr Instruction code
131
 * @param instr Instruction code
129
 * @return true - it is jump instruction, false otherwise
132
 * @return true - it is jump instruction, false otherwise
-
 
133
 *
130
 */
134
 */
131
static bool is_jump(unative_t instr)
135
static bool is_jump(unative_t instr)
132
{
136
{
133
    int i;
137
    int i;
134
 
138
 
Line 156... Line 160...
156
 
160
 
157
    /* Check, that the breakpoints do not conflict */
161
    /* Check, that the breakpoints do not conflict */
158
    for (i = 0; i < BKPOINTS_MAX; i++) {
162
    for (i = 0; i < BKPOINTS_MAX; i++) {
159
        if (breakpoints[i].address == (uintptr_t)argv->intval) {
163
        if (breakpoints[i].address == (uintptr_t)argv->intval) {
160
            printf("Duplicate breakpoint %d.\n", i);
164
            printf("Duplicate breakpoint %d.\n", i);
161
            spinlock_unlock(&bkpoints_lock);
165
            spinlock_unlock(&bkpoint_lock);
162
            return 0;
166
            return 0;
163
        } else if (breakpoints[i].address == (uintptr_t)argv->intval +
167
        } else if (breakpoints[i].address == (uintptr_t)argv->intval +
164
            sizeof(unative_t) || breakpoints[i].address ==
168
            sizeof(unative_t) || breakpoints[i].address ==
165
            (uintptr_t)argv->intval - sizeof(unative_t)) {
169
            (uintptr_t)argv->intval - sizeof(unative_t)) {
166
            printf("Adjacent breakpoints not supported, conflict "
170
            printf("Adjacent breakpoints not supported, conflict "
167
                "with %d.\n", i);
171
                "with %d.\n", i);
168
            spinlock_unlock(&bkpoints_lock);
172
            spinlock_unlock(&bkpoint_lock);
169
            return 0;
173
            return 0;
170
        }
174
        }
171
           
175
       
172
    }
176
    }
173
 
177
 
174
    for (i = 0; i < BKPOINTS_MAX; i++)
178
    for (i = 0; i < BKPOINTS_MAX; i++)
175
        if (!breakpoints[i].address) {
179
        if (!breakpoints[i].address) {
176
            cur = &breakpoints[i];
180
            cur = &breakpoints[i];
Line 253... Line 257...
253
    printf("#  Count Address    INPROG ONESHOT FUNCCALL In symbol\n");
257
    printf("#  Count Address    INPROG ONESHOT FUNCCALL In symbol\n");
254
    printf("-- ----- ---------- ------ ------- -------- ---------\n");
258
    printf("-- ----- ---------- ------ ------- -------- ---------\n");
255
   
259
   
256
    for (i = 0; i < BKPOINTS_MAX; i++)
260
    for (i = 0; i < BKPOINTS_MAX; i++)
257
        if (breakpoints[i].address) {
261
        if (breakpoints[i].address) {
-
 
262
            symbol = symtab_fmt_name_lookup(
258
            symbol = get_symtab_entry(breakpoints[i].address);
263
                breakpoints[i].address);
259
           
264
 
260
            printf("%-2u %-5d %#10zx %-6s %-7s %-8s %s\n", i,
265
            printf("%-2u %-5d %#10zx %-6s %-7s %-8s %s\n", i,
261
                breakpoints[i].counter, breakpoints[i].address,
266
                breakpoints[i].counter, breakpoints[i].address,
262
                ((breakpoints[i].flags & BKPOINT_INPROG) ? "true" :
267
                ((breakpoints[i].flags & BKPOINT_INPROG) ? "true" :
263
                "false"), ((breakpoints[i].flags & BKPOINT_ONESHOT)
268
                "false"), ((breakpoints[i].flags & BKPOINT_ONESHOT)
264
                ? "true" : "false"), ((breakpoints[i].flags &
269
                ? "true" : "false"), ((breakpoints[i].flags &
265
                BKPOINT_FUNCCALL) ? "true" : "false"), symbol);
270
                BKPOINT_FUNCCALL) ? "true" : "false"), symbol);
266
        }
271
        }
267
    return 1;
272
    return 1;
268
}
273
}
269
 
274
 
-
 
275
#endif
-
 
276
 
270
/** Initialize debugger */
277
/** Initialize debugger */
271
void debugger_init()
278
void debugger_init()
272
{
279
{
273
    int i;
280
    int i;
274
 
281
 
275
    for (i = 0; i < BKPOINTS_MAX; i++)
282
    for (i = 0; i < BKPOINTS_MAX; i++)
276
        breakpoints[i].address = NULL;
283
        breakpoints[i].address = NULL;
277
   
284
 
-
 
285
#ifdef CONFIG_KCONSOLE
278
    cmd_initialize(&bkpts_info);
286
    cmd_initialize(&bkpts_info);
279
    if (!cmd_register(&bkpts_info))
287
    if (!cmd_register(&bkpts_info))
280
        panic("could not register command %s\n", bkpts_info.name);
288
        printf("Cannot register command %s\n", bkpts_info.name);
281
 
289
 
282
    cmd_initialize(&delbkpt_info);
290
    cmd_initialize(&delbkpt_info);
283
    if (!cmd_register(&delbkpt_info))
291
    if (!cmd_register(&delbkpt_info))
284
        panic("could not register command %s\n", delbkpt_info.name);
292
        printf("Cannot register command %s\n", delbkpt_info.name);
285
 
293
 
286
    cmd_initialize(&addbkpt_info);
294
    cmd_initialize(&addbkpt_info);
287
    if (!cmd_register(&addbkpt_info))
295
    if (!cmd_register(&addbkpt_info))
288
        panic("could not register command %s\n", addbkpt_info.name);
296
        printf("Cannot register command %s\n", addbkpt_info.name);
289
 
297
 
290
    cmd_initialize(&addbkpte_info);
298
    cmd_initialize(&addbkpte_info);
291
    if (!cmd_register(&addbkpte_info))
299
    if (!cmd_register(&addbkpte_info))
292
        panic("could not register command %s\n", addbkpte_info.name);
300
        printf("Cannot register command %s\n", addbkpte_info.name);
-
 
301
#endif
293
}
302
}
294
 
303
 
295
/** Handle breakpoint
304
/** Handle breakpoint
296
 *
305
 *
297
 * Find breakpoint in breakpoint table.
306
 * Find breakpoint in breakpoint table.
Line 306... Line 315...
306
    uintptr_t fireaddr = istate->epc;
315
    uintptr_t fireaddr = istate->epc;
307
    int i;
316
    int i;
308
 
317
 
309
    /* test branch delay slot */
318
    /* test branch delay slot */
310
    if (cp0_cause_read() & 0x80000000)
319
    if (cp0_cause_read() & 0x80000000)
311
        panic("Breakpoint in branch delay slot not supported.\n");
320
        panic("Breakpoint in branch delay slot not supported.");
312
 
321
 
313
    spinlock_lock(&bkpoint_lock);
322
    spinlock_lock(&bkpoint_lock);
314
    for (i = 0; i < BKPOINTS_MAX; i++) {
323
    for (i = 0; i < BKPOINTS_MAX; i++) {
315
        /* Normal breakpoint */
324
        /* Normal breakpoint */
316
        if (fireaddr == breakpoints[i].address &&
325
        if (fireaddr == breakpoints[i].address &&
Line 338... Line 347...
338
            return;
347
            return;
339
        }
348
        }
340
        if (cur->flags & BKPOINT_INPROG)
349
        if (cur->flags & BKPOINT_INPROG)
341
            printf("Warning: breakpoint recursion\n");
350
            printf("Warning: breakpoint recursion\n");
342
       
351
       
343
        if (!(cur->flags & BKPOINT_FUNCCALL))
352
        if (!(cur->flags & BKPOINT_FUNCCALL)) {
344
            printf("***Breakpoint %d: %p in %s.\n", i, fireaddr,
353
            printf("***Breakpoint %d: %p in %s.\n", i, fireaddr,
345
                get_symtab_entry(istate->epc));
354
                symtab_fmt_name_lookup(istate->epc));
-
 
355
        }
346
 
356
 
347
        /* Return first instruction back */
357
        /* Return first instruction back */
348
        ((uint32_t *)cur->address)[0] = cur->instruction;
358
        ((uint32_t *)cur->address)[0] = cur->instruction;
349
        smc_coherence(cur->address);
359
        smc_coherence(cur->address);
350
 
360
 
Line 353... Line 363...
353
            ((uint32_t *)cur->address)[1] = 0x0d;
363
            ((uint32_t *)cur->address)[1] = 0x0d;
354
            cur->flags |= BKPOINT_REINST;
364
            cur->flags |= BKPOINT_REINST;
355
        }
365
        }
356
        cur->flags |= BKPOINT_INPROG;
366
        cur->flags |= BKPOINT_INPROG;
357
    } else {
367
    } else {
358
        printf("***Breakpoint %p in %s.\n", fireaddr,
368
        printf("***Breakpoint %d: %p in %s.\n", i, fireaddr,
359
               get_symtab_entry(fireaddr));
369
            symtab_fmt_name_lookup(fireaddr));
-
 
370
 
360
        /* Move on to next instruction */
371
        /* Move on to next instruction */
361
        istate->epc += 4;
372
        istate->epc += 4;
362
    }
373
    }
363
    if (cur)
374
    if (cur)
364
        cur->counter++;
375
        cur->counter++;
365
    if (cur && (cur->flags & BKPOINT_FUNCCALL)) {
376
    if (cur && (cur->flags & BKPOINT_FUNCCALL)) {
366
        /* Allow zero bkfunc, just for counting */
377
        /* Allow zero bkfunc, just for counting */
367
        if (cur->bkfunc)
378
        if (cur->bkfunc)
368
            cur->bkfunc(cur, istate);
379
            cur->bkfunc(cur, istate);
369
    } else {
380
    } else {
370
        printf("***Type 'exit' to exit kconsole.\n");
381
#ifdef CONFIG_KCONSOLE
371
        /* This disables all other processors - we are not SMP,
382
        /* This disables all other processors - we are not SMP,
372
         * actually this gets us to cpu_halt, if scheduler() is run
383
         * actually this gets us to cpu_halt, if scheduler() is run
373
         * - we generally do not want scheduler to be run from debug,
384
         * - we generally do not want scheduler to be run from debug,
374
         *   so this is a good idea
385
         *   so this is a good idea
375
         */
386
         */
376
        atomic_set(&haltstate,1);
387
        atomic_set(&haltstate, 1);
377
        spinlock_unlock(&bkpoint_lock);
388
        spinlock_unlock(&bkpoint_lock);
378
 
389
       
379
        kconsole("debug");
390
        kconsole("debug", "Debug console ready.\n", false);
380
 
391
       
381
        spinlock_lock(&bkpoint_lock);
392
        spinlock_lock(&bkpoint_lock);
382
        atomic_set(&haltstate,0);
393
        atomic_set(&haltstate, 0);
-
 
394
#endif
383
    }
395
    }
384
    if (cur && cur->address == fireaddr && (cur->flags & BKPOINT_INPROG)) {
396
    if (cur && cur->address == fireaddr && (cur->flags & BKPOINT_INPROG)) {
385
        /* Remove one-shot breakpoint */
397
        /* Remove one-shot breakpoint */
386
        if ((cur->flags & BKPOINT_ONESHOT))
398
        if ((cur->flags & BKPOINT_ONESHOT))
387
            cur->address = NULL;
399
            cur->address = NULL;