Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/mips32/src/debugger.c

    rda1bafb r556f9892  
    4646
    4747bpinfo_t breakpoints[BKPOINTS_MAX];
    48 IRQ_SPINLOCK_STATIC_INITIALIZE(bkpoint_lock);
     48SPINLOCK_INITIALIZE(bkpoint_lock);
    4949
    5050#ifdef CONFIG_KCONSOLE
    5151
    52 static int cmd_print_breakpoints(cmd_arg_t *);
    53 static int cmd_del_breakpoint(cmd_arg_t *);
    54 static int cmd_add_breakpoint(cmd_arg_t *);
    55 
     52static int cmd_print_breakpoints(cmd_arg_t *argv);
    5653static cmd_info_t bkpts_info = {
    5754        .name = "bkpts",
     
    6158};
    6259
     60static int cmd_del_breakpoint(cmd_arg_t *argv);
    6361static cmd_arg_t del_argv = {
    6462        .type = ARG_TYPE_INT
    6563};
    66 
    6764static cmd_info_t delbkpt_info = {
    6865        .name = "delbkpt",
    69         .description = "Delete breakpoint.",
     66        .description = "delbkpt <number> - Delete breakpoint.",
    7067        .func = cmd_del_breakpoint,
    7168        .argc = 1,
     
    7370};
    7471
     72static int cmd_add_breakpoint(cmd_arg_t *argv);
    7573static cmd_arg_t add_argv = {
    7674        .type = ARG_TYPE_INT
    7775};
    78 
    7976static cmd_info_t addbkpt_info = {
    8077        .name = "addbkpt",
    81         .description = "Add bkpoint (break on J/Branch insts unsupported).",
     78        .description = "addbkpt <&symbol> - new bkpoint. Break on J/Branch "
     79            "insts unsupported.",
    8280        .func = cmd_add_breakpoint,
    8381        .argc = 1,
     
    9189static cmd_info_t addbkpte_info = {
    9290        .name = "addbkpte",
    93         .description = "Add bkpoint with a trigger function.",
     91        .description = "addebkpte <&symbol> <&func> - new bkpoint. Call "
     92            "func(or Nothing if 0).",
    9493        .func = cmd_add_breakpoint,
    9594        .argc = 2,
     
    101100        uint32_t value;
    102101} jmpinstr[] = {
    103         {0xf3ff0000, 0x41000000},  /* BCzF */
    104         {0xf3ff0000, 0x41020000},  /* BCzFL */
    105         {0xf3ff0000, 0x41010000},  /* BCzT */
    106         {0xf3ff0000, 0x41030000},  /* BCzTL */
    107         {0xfc000000, 0x10000000},  /* BEQ */
    108         {0xfc000000, 0x50000000},  /* BEQL */
    109         {0xfc1f0000, 0x04010000},  /* BEQL */
    110         {0xfc1f0000, 0x04110000},  /* BGEZAL */
    111         {0xfc1f0000, 0x04130000},  /* BGEZALL */
    112         {0xfc1f0000, 0x04030000},  /* BGEZL */
    113         {0xfc1f0000, 0x1c000000},  /* BGTZ */
    114         {0xfc1f0000, 0x5c000000},  /* BGTZL */
    115         {0xfc1f0000, 0x18000000},  /* BLEZ */
    116         {0xfc1f0000, 0x58000000},  /* BLEZL */
    117         {0xfc1f0000, 0x04000000},  /* BLTZ */
    118         {0xfc1f0000, 0x04100000},  /* BLTZAL */
    119         {0xfc1f0000, 0x04120000},  /* BLTZALL */
    120         {0xfc1f0000, 0x04020000},  /* BLTZL */
    121         {0xfc000000, 0x14000000},  /* BNE */
    122         {0xfc000000, 0x54000000},  /* BNEL */
    123         {0xfc000000, 0x08000000},  /* J */
    124         {0xfc000000, 0x0c000000},  /* JAL */
    125         {0xfc1f07ff, 0x00000009},  /* JALR */
    126         {0, 0}                     /* end of table */
    127 };
     102        {0xf3ff0000, 0x41000000}, /* BCzF */
     103        {0xf3ff0000, 0x41020000}, /* BCzFL */
     104        {0xf3ff0000, 0x41010000}, /* BCzT */
     105        {0xf3ff0000, 0x41030000}, /* BCzTL */
     106        {0xfc000000, 0x10000000}, /* BEQ */
     107        {0xfc000000, 0x50000000}, /* BEQL */
     108        {0xfc1f0000, 0x04010000}, /* BEQL */
     109        {0xfc1f0000, 0x04110000}, /* BGEZAL */
     110        {0xfc1f0000, 0x04130000}, /* BGEZALL */
     111        {0xfc1f0000, 0x04030000}, /* BGEZL */
     112        {0xfc1f0000, 0x1c000000}, /* BGTZ */
     113        {0xfc1f0000, 0x5c000000}, /* BGTZL */
     114        {0xfc1f0000, 0x18000000}, /* BLEZ */
     115        {0xfc1f0000, 0x58000000}, /* BLEZL */
     116        {0xfc1f0000, 0x04000000}, /* BLTZ */
     117        {0xfc1f0000, 0x04100000}, /* BLTZAL */
     118        {0xfc1f0000, 0x04120000}, /* BLTZALL */
     119        {0xfc1f0000, 0x04020000}, /* BLTZL */
     120        {0xfc000000, 0x14000000}, /* BNE */
     121        {0xfc000000, 0x54000000}, /* BNEL */
     122        {0xfc000000, 0x08000000}, /* J */
     123        {0xfc000000, 0x0c000000}, /* JAL */
     124        {0xfc1f07ff, 0x00000009}, /* JALR */
     125        {0, 0} /* EndOfTable */
     126};
     127
    128128
    129129/** Test, if the given instruction is a jump or branch instruction
    130130 *
    131131 * @param instr Instruction code
    132  *
    133  * @return true if it is jump instruction, false otherwise
     132 * @return true - it is jump instruction, false otherwise
    134133 *
    135134 */
    136135static bool is_jump(unative_t instr)
    137136{
    138         unsigned int i;
    139        
     137        int i;
     138
    140139        for (i = 0; jmpinstr[i].andmask; i++) {
    141140                if ((instr & jmpinstr[i].andmask) == jmpinstr[i].value)
    142141                        return true;
    143142        }
    144        
     143
    145144        return false;
    146145}
    147146
    148 /** Add new breakpoint to table
    149  *
    150  */
     147/** Add new breakpoint to table */
    151148int cmd_add_breakpoint(cmd_arg_t *argv)
    152149{
     150        bpinfo_t *cur = NULL;
     151        ipl_t ipl;
     152        int i;
     153
    153154        if (argv->intval & 0x3) {
    154155                printf("Not aligned instruction, forgot to use &symbol?\n");
    155156                return 1;
    156157        }
    157        
    158         irq_spinlock_lock(&bkpoint_lock, true);
    159        
     158        ipl = interrupts_disable();
     159        spinlock_lock(&bkpoint_lock);
     160
    160161        /* Check, that the breakpoints do not conflict */
    161         unsigned int i;
    162162        for (i = 0; i < BKPOINTS_MAX; i++) {
    163                 if (breakpoints[i].address == (uintptr_t) argv->intval) {
     163                if (breakpoints[i].address == (uintptr_t)argv->intval) {
    164164                        printf("Duplicate breakpoint %d.\n", i);
    165                         irq_spinlock_unlock(&bkpoint_lock, true);
     165                        spinlock_unlock(&bkpoint_lock);
     166                        interrupts_restore(ipl);
    166167                        return 0;
    167                 } else if ((breakpoints[i].address == (uintptr_t) argv->intval +
    168                     sizeof(unative_t)) || (breakpoints[i].address ==
    169                     (uintptr_t) argv->intval - sizeof(unative_t))) {
     168                } else if (breakpoints[i].address == (uintptr_t)argv->intval +
     169                    sizeof(unative_t) || breakpoints[i].address ==
     170                    (uintptr_t)argv->intval - sizeof(unative_t)) {
    170171                        printf("Adjacent breakpoints not supported, conflict "
    171172                            "with %d.\n", i);
    172                         irq_spinlock_unlock(&bkpoint_lock, true);
     173                        spinlock_unlock(&bkpoint_lock);
     174                        interrupts_restore(ipl);
    173175                        return 0;
    174176                }
    175177               
    176178        }
    177        
    178         bpinfo_t *cur = NULL;
    179        
    180         for (i = 0; i < BKPOINTS_MAX; i++) {
     179
     180        for (i = 0; i < BKPOINTS_MAX; i++)
    181181                if (!breakpoints[i].address) {
    182182                        cur = &breakpoints[i];
    183183                        break;
    184184                }
    185         }
    186        
    187185        if (!cur) {
    188186                printf("Too many breakpoints.\n");
    189                 irq_spinlock_unlock(&bkpoint_lock, true);
     187                spinlock_unlock(&bkpoint_lock);
     188                interrupts_restore(ipl);
    190189                return 0;
    191190        }
    192        
    193         printf("Adding breakpoint on address %p\n", argv->intval);
    194        
    195191        cur->address = (uintptr_t) argv->intval;
    196         cur->instruction = ((unative_t *) cur->address)[0];
    197         cur->nextinstruction = ((unative_t *) cur->address)[1];
     192        printf("Adding breakpoint on address: %p\n", argv->intval);
     193        cur->instruction = ((unative_t *)cur->address)[0];
     194        cur->nextinstruction = ((unative_t *)cur->address)[1];
    198195        if (argv == &add_argv) {
    199196                cur->flags = 0;
    200         } else {  /* We are add extended */
     197        } else { /* We are add extended */
    201198                cur->flags = BKPOINT_FUNCCALL;
    202199                cur->bkfunc = (void (*)(void *, istate_t *)) argv[1].intval;
    203200        }
    204        
    205201        if (is_jump(cur->instruction))
    206202                cur->flags |= BKPOINT_ONESHOT;
    207        
    208203        cur->counter = 0;
    209        
     204
    210205        /* Set breakpoint */
    211         *((unative_t *) cur->address) = 0x0d;
     206        *((unative_t *)cur->address) = 0x0d;
    212207        smc_coherence(cur->address);
    213        
    214         irq_spinlock_unlock(&bkpoint_lock, true);
    215        
     208
     209        spinlock_unlock(&bkpoint_lock);
     210        interrupts_restore(ipl);
     211
    216212        return 1;
    217213}
    218214
    219 /** Remove breakpoint from table
    220  *
    221  */
     215/** Remove breakpoint from table */
    222216int cmd_del_breakpoint(cmd_arg_t *argv)
    223217{
     218        bpinfo_t *cur;
     219        ipl_t ipl;
     220
    224221        if (argv->intval > BKPOINTS_MAX) {
    225222                printf("Invalid breakpoint number.\n");
    226223                return 0;
    227224        }
    228        
    229         irq_spinlock_lock(&bkpoint_lock, true);
    230        
    231         bpinfo_t *cur = &breakpoints[argv->intval];
     225        ipl = interrupts_disable();
     226        spinlock_lock(&bkpoint_lock);
     227
     228        cur = &breakpoints[argv->intval];
    232229        if (!cur->address) {
    233230                printf("Breakpoint does not exist.\n");
    234                 irq_spinlock_unlock(&bkpoint_lock, true);
     231                spinlock_unlock(&bkpoint_lock);
     232                interrupts_restore(ipl);
    235233                return 0;
    236234        }
    237        
    238235        if ((cur->flags & BKPOINT_INPROG) && (cur->flags & BKPOINT_ONESHOT)) {
    239236                printf("Cannot remove one-shot breakpoint in-progress\n");
    240                 irq_spinlock_unlock(&bkpoint_lock, true);
     237                spinlock_unlock(&bkpoint_lock);
     238                interrupts_restore(ipl);
    241239                return 0;
    242240        }
    243        
    244         ((uint32_t *) cur->address)[0] = cur->instruction;
    245         smc_coherence(((uint32_t *) cur->address)[0]);
    246         ((uint32_t *) cur->address)[1] = cur->nextinstruction;
    247         smc_coherence(((uint32_t *) cur->address)[1]);
    248        
     241        ((uint32_t *)cur->address)[0] = cur->instruction;
     242        smc_coherence(((uint32_t *)cur->address)[0]);
     243        ((uint32_t *)cur->address)[1] = cur->nextinstruction;
     244        smc_coherence(((uint32_t *)cur->address)[1]);
     245
    249246        cur->address = NULL;
    250        
    251         irq_spinlock_unlock(&bkpoint_lock, true);
     247
     248        spinlock_unlock(&bkpoint_lock);
     249        interrupts_restore(ipl);
    252250        return 1;
    253251}
    254252
    255 /** Print table of active breakpoints
    256  *
    257  */
     253/** Print table of active breakpoints */
    258254int cmd_print_breakpoints(cmd_arg_t *argv)
    259255{
     
    280276}
    281277
    282 #endif /* CONFIG_KCONSOLE */
    283 
    284 /** Initialize debugger
    285  *
    286  */
     278#endif
     279
     280/** Initialize debugger */
    287281void debugger_init()
    288282{
    289         unsigned int i;
    290        
     283        int i;
     284
    291285        for (i = 0; i < BKPOINTS_MAX; i++)
    292286                breakpoints[i].address = NULL;
    293        
     287
    294288#ifdef CONFIG_KCONSOLE
    295289        cmd_initialize(&bkpts_info);
    296290        if (!cmd_register(&bkpts_info))
    297291                printf("Cannot register command %s\n", bkpts_info.name);
    298        
     292
    299293        cmd_initialize(&delbkpt_info);
    300294        if (!cmd_register(&delbkpt_info))
    301295                printf("Cannot register command %s\n", delbkpt_info.name);
    302        
     296
    303297        cmd_initialize(&addbkpt_info);
    304298        if (!cmd_register(&addbkpt_info))
    305299                printf("Cannot register command %s\n", addbkpt_info.name);
    306        
     300
    307301        cmd_initialize(&addbkpte_info);
    308302        if (!cmd_register(&addbkpte_info))
    309303                printf("Cannot register command %s\n", addbkpte_info.name);
    310 #endif /* CONFIG_KCONSOLE */
     304#endif
    311305}
    312306
    313307/** Handle breakpoint
    314308 *
    315  * Find breakpoint in breakpoint table.
     309 * Find breakpoint in breakpoint table. 
    316310 * If found, call kconsole, set break on next instruction and reexecute.
    317311 * If we are on "next instruction", set it back on the first and reexecute.
    318312 * If breakpoint not found in breakpoint table, call kconsole and start
    319313 * next instruction.
    320  *
    321314 */
    322315void debugger_bpoint(istate_t *istate)
    323316{
     317        bpinfo_t *cur = NULL;
     318        uintptr_t fireaddr = istate->epc;
     319        int i;
     320
    324321        /* test branch delay slot */
    325322        if (cp0_cause_read() & 0x80000000)
    326323                panic("Breakpoint in branch delay slot not supported.");
    327        
    328         irq_spinlock_lock(&bkpoint_lock, false);
    329        
    330         bpinfo_t *cur = NULL;
    331         uintptr_t fireaddr = istate->epc;
    332         unsigned int i;
    333        
     324
     325        spinlock_lock(&bkpoint_lock);
    334326        for (i = 0; i < BKPOINTS_MAX; i++) {
    335327                /* Normal breakpoint */
    336                 if ((fireaddr == breakpoints[i].address) &&
    337                     (!(breakpoints[i].flags & BKPOINT_REINST))) {
     328                if (fireaddr == breakpoints[i].address &&
     329                    !(breakpoints[i].flags & BKPOINT_REINST)) {
    338330                        cur = &breakpoints[i];
    339331                        break;
    340332                }
    341                
    342333                /* Reinst only breakpoint */
    343334                if ((breakpoints[i].flags & BKPOINT_REINST) &&
     
    347338                }
    348339        }
    349        
    350340        if (cur) {
    351341                if (cur->flags & BKPOINT_REINST) {
    352342                        /* Set breakpoint on first instruction */
    353                         ((uint32_t *) cur->address)[0] = 0x0d;
     343                        ((uint32_t *)cur->address)[0] = 0x0d;
    354344                        smc_coherence(((uint32_t *)cur->address)[0]);
    355                        
    356345                        /* Return back the second */
    357                         ((uint32_t *) cur->address)[1] = cur->nextinstruction;
    358                         smc_coherence(((uint32_t *) cur->address)[1]);
    359                        
     346                        ((uint32_t *)cur->address)[1] = cur->nextinstruction;
     347                        smc_coherence(((uint32_t *)cur->address)[1]);
    360348                        cur->flags &= ~BKPOINT_REINST;
    361                         irq_spinlock_unlock(&bkpoint_lock, false);
     349                        spinlock_unlock(&bkpoint_lock);
    362350                        return;
    363                 }
    364                
     351                }
    365352                if (cur->flags & BKPOINT_INPROG)
    366353                        printf("Warning: breakpoint recursion\n");
    367354               
    368355                if (!(cur->flags & BKPOINT_FUNCCALL)) {
    369                         printf("***Breakpoint %u: %p in %s.\n", i, fireaddr,
    370                             symtab_fmt_name_lookup(fireaddr));
    371                 }
    372                
     356                        printf("***Breakpoint %d: %p in %s.\n", i, fireaddr,
     357                            symtab_fmt_name_lookup(istate->epc));
     358                }
     359
    373360                /* Return first instruction back */
    374361                ((uint32_t *)cur->address)[0] = cur->instruction;
     
    384371                printf("***Breakpoint %d: %p in %s.\n", i, fireaddr,
    385372                    symtab_fmt_name_lookup(fireaddr));
    386                
     373
    387374                /* Move on to next instruction */
    388375                istate->epc += 4;
    389376        }
    390        
    391377        if (cur)
    392378                cur->counter++;
    393        
    394379        if (cur && (cur->flags & BKPOINT_FUNCCALL)) {
    395380                /* Allow zero bkfunc, just for counting */
     
    398383        } else {
    399384#ifdef CONFIG_KCONSOLE
    400                 /*
    401                  * This disables all other processors - we are not SMP,
     385                /* This disables all other processors - we are not SMP,
    402386                 * actually this gets us to cpu_halt, if scheduler() is run
    403387                 * - we generally do not want scheduler to be run from debug,
    404388                 *   so this is a good idea
    405                  */
     389                 */     
    406390                atomic_set(&haltstate, 1);
    407                 irq_spinlock_unlock(&bkpoint_lock, false);
     391                spinlock_unlock(&bkpoint_lock);
    408392               
    409393                kconsole("debug", "Debug console ready.\n", false);
    410394               
    411                 irq_spinlock_lock(&bkpoint_lock, false);
     395                spinlock_lock(&bkpoint_lock);
    412396                atomic_set(&haltstate, 0);
    413397#endif
    414398        }
    415        
    416         if ((cur) && (cur->address == fireaddr)
    417             && ((cur->flags & BKPOINT_INPROG))) {
     399        if (cur && cur->address == fireaddr && (cur->flags & BKPOINT_INPROG)) {
    418400                /* Remove one-shot breakpoint */
    419401                if ((cur->flags & BKPOINT_ONESHOT))
    420402                        cur->address = NULL;
    421                
    422403                /* Remove in-progress flag */
    423404                cur->flags &= ~BKPOINT_INPROG;
    424         }
    425        
    426         irq_spinlock_unlock(&bkpoint_lock, false);
     405        }
     406        spinlock_unlock(&bkpoint_lock);
    427407}
    428408
Note: See TracChangeset for help on using the changeset viewer.