Ignore:
File:
1 edited

Legend:

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

    r556f9892 r63bdde6  
    4646
    4747bpinfo_t breakpoints[BKPOINTS_MAX];
    48 SPINLOCK_INITIALIZE(bkpoint_lock);
     48IRQ_SPINLOCK_STATIC_INITIALIZE(bkpoint_lock);
    4949
    5050#ifdef CONFIG_KCONSOLE
    5151
    52 static int cmd_print_breakpoints(cmd_arg_t *argv);
     52static int cmd_print_breakpoints(cmd_arg_t *);
     53static int cmd_del_breakpoint(cmd_arg_t *);
     54static int cmd_add_breakpoint(cmd_arg_t *);
     55
    5356static cmd_info_t bkpts_info = {
    5457        .name = "bkpts",
     
    5861};
    5962
    60 static int cmd_del_breakpoint(cmd_arg_t *argv);
    6163static cmd_arg_t del_argv = {
    6264        .type = ARG_TYPE_INT
    6365};
     66
    6467static cmd_info_t delbkpt_info = {
    6568        .name = "delbkpt",
    66         .description = "delbkpt <number> - Delete breakpoint.",
     69        .description = "Delete breakpoint.",
    6770        .func = cmd_del_breakpoint,
    6871        .argc = 1,
     
    7073};
    7174
    72 static int cmd_add_breakpoint(cmd_arg_t *argv);
    7375static cmd_arg_t add_argv = {
    7476        .type = ARG_TYPE_INT
    7577};
     78
    7679static cmd_info_t addbkpt_info = {
    7780        .name = "addbkpt",
    78         .description = "addbkpt <&symbol> - new bkpoint. Break on J/Branch "
    79             "insts unsupported.",
     81        .description = "Add bkpoint (break on J/Branch insts unsupported).",
    8082        .func = cmd_add_breakpoint,
    8183        .argc = 1,
     
    8991static cmd_info_t addbkpte_info = {
    9092        .name = "addbkpte",
    91         .description = "addebkpte <&symbol> <&func> - new bkpoint. Call "
    92             "func(or Nothing if 0).",
     93        .description = "Add bkpoint with a trigger function.",
    9394        .func = cmd_add_breakpoint,
    9495        .argc = 2,
     
    100101        uint32_t value;
    101102} jmpinstr[] = {
    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 
     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};
    128128
    129129/** Test, if the given instruction is a jump or branch instruction
    130130 *
    131131 * @param instr Instruction code
    132  * @return true - it is jump instruction, false otherwise
    133  *
    134  */
    135 static bool is_jump(unative_t instr)
    136 {
    137         int i;
    138 
     132 *
     133 * @return true if it is jump instruction, false otherwise
     134 *
     135 */
     136bool is_jump(unative_t instr)
     137{
     138        unsigned int i;
     139       
    139140        for (i = 0; jmpinstr[i].andmask; i++) {
    140141                if ((instr & jmpinstr[i].andmask) == jmpinstr[i].value)
    141142                        return true;
    142143        }
    143 
     144       
    144145        return false;
    145146}
    146147
    147 /** Add new breakpoint to table */
     148/** Add new breakpoint to table
     149 *
     150 */
    148151int cmd_add_breakpoint(cmd_arg_t *argv)
    149152{
    150         bpinfo_t *cur = NULL;
    151         ipl_t ipl;
    152         int i;
    153 
    154153        if (argv->intval & 0x3) {
    155154                printf("Not aligned instruction, forgot to use &symbol?\n");
    156155                return 1;
    157156        }
    158         ipl = interrupts_disable();
    159         spinlock_lock(&bkpoint_lock);
    160 
     157       
     158        irq_spinlock_lock(&bkpoint_lock, true);
     159       
    161160        /* 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                         spinlock_unlock(&bkpoint_lock);
    166                         interrupts_restore(ipl);
     165                        irq_spinlock_unlock(&bkpoint_lock, true);
    167166                        return 0;
    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)) {
     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))) {
    171170                        printf("Adjacent breakpoints not supported, conflict "
    172171                            "with %d.\n", i);
    173                         spinlock_unlock(&bkpoint_lock);
    174                         interrupts_restore(ipl);
     172                        irq_spinlock_unlock(&bkpoint_lock, true);
    175173                        return 0;
    176174                }
    177175               
    178176        }
    179 
    180         for (i = 0; i < BKPOINTS_MAX; i++)
     177       
     178        bpinfo_t *cur = NULL;
     179       
     180        for (i = 0; i < BKPOINTS_MAX; i++) {
    181181                if (!breakpoints[i].address) {
    182182                        cur = &breakpoints[i];
    183183                        break;
    184184                }
     185        }
     186       
    185187        if (!cur) {
    186188                printf("Too many breakpoints.\n");
    187                 spinlock_unlock(&bkpoint_lock);
    188                 interrupts_restore(ipl);
     189                irq_spinlock_unlock(&bkpoint_lock, true);
    189190                return 0;
    190191        }
     192       
     193        printf("Adding breakpoint on address %p\n", argv->intval);
     194       
    191195        cur->address = (uintptr_t) argv->intval;
    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];
     196        cur->instruction = ((unative_t *) cur->address)[0];
     197        cur->nextinstruction = ((unative_t *) cur->address)[1];
    195198        if (argv == &add_argv) {
    196199                cur->flags = 0;
    197         } else { /* We are add extended */
     200        } else {  /* We are add extended */
    198201                cur->flags = BKPOINT_FUNCCALL;
    199202                cur->bkfunc = (void (*)(void *, istate_t *)) argv[1].intval;
    200203        }
     204       
    201205        if (is_jump(cur->instruction))
    202206                cur->flags |= BKPOINT_ONESHOT;
     207       
    203208        cur->counter = 0;
    204 
     209       
    205210        /* Set breakpoint */
    206         *((unative_t *)cur->address) = 0x0d;
     211        *((unative_t *) cur->address) = 0x0d;
    207212        smc_coherence(cur->address);
    208 
    209         spinlock_unlock(&bkpoint_lock);
    210         interrupts_restore(ipl);
    211 
     213       
     214        irq_spinlock_unlock(&bkpoint_lock, true);
     215       
    212216        return 1;
    213217}
    214218
    215 /** Remove breakpoint from table */
     219/** Remove breakpoint from table
     220 *
     221 */
    216222int cmd_del_breakpoint(cmd_arg_t *argv)
    217223{
    218         bpinfo_t *cur;
    219         ipl_t ipl;
    220 
    221224        if (argv->intval > BKPOINTS_MAX) {
    222225                printf("Invalid breakpoint number.\n");
    223226                return 0;
    224227        }
    225         ipl = interrupts_disable();
    226         spinlock_lock(&bkpoint_lock);
    227 
    228         cur = &breakpoints[argv->intval];
     228       
     229        irq_spinlock_lock(&bkpoint_lock, true);
     230       
     231        bpinfo_t *cur = &breakpoints[argv->intval];
    229232        if (!cur->address) {
    230233                printf("Breakpoint does not exist.\n");
    231                 spinlock_unlock(&bkpoint_lock);
    232                 interrupts_restore(ipl);
     234                irq_spinlock_unlock(&bkpoint_lock, true);
    233235                return 0;
    234236        }
     237       
    235238        if ((cur->flags & BKPOINT_INPROG) && (cur->flags & BKPOINT_ONESHOT)) {
    236239                printf("Cannot remove one-shot breakpoint in-progress\n");
    237                 spinlock_unlock(&bkpoint_lock);
    238                 interrupts_restore(ipl);
     240                irq_spinlock_unlock(&bkpoint_lock, true);
    239241                return 0;
    240242        }
    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 
     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       
    246249        cur->address = NULL;
    247 
    248         spinlock_unlock(&bkpoint_lock);
    249         interrupts_restore(ipl);
     250       
     251        irq_spinlock_unlock(&bkpoint_lock, true);
    250252        return 1;
    251253}
    252254
    253 /** Print table of active breakpoints */
     255/** Print table of active breakpoints
     256 *
     257 */
    254258int cmd_print_breakpoints(cmd_arg_t *argv)
    255259{
    256260        unsigned int i;
    257261       
    258         printf("#  Count Address    INPROG ONESHOT FUNCCALL In symbol\n");
    259         printf("-- ----- ---------- ------ ------- -------- ---------\n");
     262        printf("[nr] [count] [address ] [inprog] [oneshot] [funccall] [in symbol\n");
    260263       
    261264        for (i = 0; i < BKPOINTS_MAX; i++) {
     
    264267                            breakpoints[i].address);
    265268                       
    266                         printf("%-2u %-5d %#10zx %-6s %-7s %-8s %s\n", i,
     269                        printf("%-4u %7" PRIs " %p %-8s %-9s %-10s %s\n", i,
    267270                            breakpoints[i].counter, breakpoints[i].address,
    268271                            ((breakpoints[i].flags & BKPOINT_INPROG) ? "true" :
     
    276279}
    277280
    278 #endif
    279 
    280 /** Initialize debugger */
     281#endif /* CONFIG_KCONSOLE */
     282
     283/** Initialize debugger
     284 *
     285 */
    281286void debugger_init()
    282287{
    283         int i;
    284 
     288        unsigned int i;
     289       
    285290        for (i = 0; i < BKPOINTS_MAX; i++)
    286291                breakpoints[i].address = NULL;
    287 
     292       
    288293#ifdef CONFIG_KCONSOLE
    289294        cmd_initialize(&bkpts_info);
    290295        if (!cmd_register(&bkpts_info))
    291296                printf("Cannot register command %s\n", bkpts_info.name);
    292 
     297       
    293298        cmd_initialize(&delbkpt_info);
    294299        if (!cmd_register(&delbkpt_info))
    295300                printf("Cannot register command %s\n", delbkpt_info.name);
    296 
     301       
    297302        cmd_initialize(&addbkpt_info);
    298303        if (!cmd_register(&addbkpt_info))
    299304                printf("Cannot register command %s\n", addbkpt_info.name);
    300 
     305       
    301306        cmd_initialize(&addbkpte_info);
    302307        if (!cmd_register(&addbkpte_info))
    303308                printf("Cannot register command %s\n", addbkpte_info.name);
    304 #endif
     309#endif /* CONFIG_KCONSOLE */
    305310}
    306311
    307312/** Handle breakpoint
    308313 *
    309  * Find breakpoint in breakpoint table. 
     314 * Find breakpoint in breakpoint table.
    310315 * If found, call kconsole, set break on next instruction and reexecute.
    311316 * If we are on "next instruction", set it back on the first and reexecute.
    312317 * If breakpoint not found in breakpoint table, call kconsole and start
    313318 * next instruction.
     319 *
    314320 */
    315321void debugger_bpoint(istate_t *istate)
    316322{
    317         bpinfo_t *cur = NULL;
    318         uintptr_t fireaddr = istate->epc;
    319         int i;
    320 
    321323        /* test branch delay slot */
    322324        if (cp0_cause_read() & 0x80000000)
    323325                panic("Breakpoint in branch delay slot not supported.");
    324 
    325         spinlock_lock(&bkpoint_lock);
     326       
     327        irq_spinlock_lock(&bkpoint_lock, false);
     328       
     329        bpinfo_t *cur = NULL;
     330        uintptr_t fireaddr = istate->epc;
     331        unsigned int i;
     332       
    326333        for (i = 0; i < BKPOINTS_MAX; i++) {
    327334                /* Normal breakpoint */
    328                 if (fireaddr == breakpoints[i].address &&
    329                     !(breakpoints[i].flags & BKPOINT_REINST)) {
     335                if ((fireaddr == breakpoints[i].address) &&
     336                    (!(breakpoints[i].flags & BKPOINT_REINST))) {
    330337                        cur = &breakpoints[i];
    331338                        break;
    332339                }
     340               
    333341                /* Reinst only breakpoint */
    334342                if ((breakpoints[i].flags & BKPOINT_REINST) &&
     
    338346                }
    339347        }
     348       
    340349        if (cur) {
    341350                if (cur->flags & BKPOINT_REINST) {
    342351                        /* Set breakpoint on first instruction */
    343                         ((uint32_t *)cur->address)[0] = 0x0d;
     352                        ((uint32_t *) cur->address)[0] = 0x0d;
    344353                        smc_coherence(((uint32_t *)cur->address)[0]);
     354                       
    345355                        /* Return back the second */
    346                         ((uint32_t *)cur->address)[1] = cur->nextinstruction;
    347                         smc_coherence(((uint32_t *)cur->address)[1]);
     356                        ((uint32_t *) cur->address)[1] = cur->nextinstruction;
     357                        smc_coherence(((uint32_t *) cur->address)[1]);
     358                       
    348359                        cur->flags &= ~BKPOINT_REINST;
    349                         spinlock_unlock(&bkpoint_lock);
     360                        irq_spinlock_unlock(&bkpoint_lock, false);
    350361                        return;
    351                 }
     362                }
     363               
    352364                if (cur->flags & BKPOINT_INPROG)
    353365                        printf("Warning: breakpoint recursion\n");
    354366               
    355367                if (!(cur->flags & BKPOINT_FUNCCALL)) {
    356                         printf("***Breakpoint %d: %p in %s.\n", i, fireaddr,
    357                             symtab_fmt_name_lookup(istate->epc));
    358                 }
    359 
     368                        printf("***Breakpoint %u: %p in %s.\n", i, fireaddr,
     369                            symtab_fmt_name_lookup(fireaddr));
     370                }
     371               
    360372                /* Return first instruction back */
    361373                ((uint32_t *)cur->address)[0] = cur->instruction;
     
    371383                printf("***Breakpoint %d: %p in %s.\n", i, fireaddr,
    372384                    symtab_fmt_name_lookup(fireaddr));
    373 
     385               
    374386                /* Move on to next instruction */
    375387                istate->epc += 4;
    376388        }
     389       
    377390        if (cur)
    378391                cur->counter++;
     392       
    379393        if (cur && (cur->flags & BKPOINT_FUNCCALL)) {
    380394                /* Allow zero bkfunc, just for counting */
     
    383397        } else {
    384398#ifdef CONFIG_KCONSOLE
    385                 /* This disables all other processors - we are not SMP,
     399                /*
     400                 * This disables all other processors - we are not SMP,
    386401                 * actually this gets us to cpu_halt, if scheduler() is run
    387402                 * - we generally do not want scheduler to be run from debug,
    388403                 *   so this is a good idea
    389                  */     
     404                 */
    390405                atomic_set(&haltstate, 1);
    391                 spinlock_unlock(&bkpoint_lock);
     406                irq_spinlock_unlock(&bkpoint_lock, false);
    392407               
    393408                kconsole("debug", "Debug console ready.\n", false);
    394409               
    395                 spinlock_lock(&bkpoint_lock);
     410                irq_spinlock_lock(&bkpoint_lock, false);
    396411                atomic_set(&haltstate, 0);
    397412#endif
    398413        }
    399         if (cur && cur->address == fireaddr && (cur->flags & BKPOINT_INPROG)) {
     414       
     415        if ((cur) && (cur->address == fireaddr)
     416            && ((cur->flags & BKPOINT_INPROG))) {
    400417                /* Remove one-shot breakpoint */
    401418                if ((cur->flags & BKPOINT_ONESHOT))
    402419                        cur->address = NULL;
     420               
    403421                /* Remove in-progress flag */
    404422                cur->flags &= ~BKPOINT_INPROG;
    405         }
    406         spinlock_unlock(&bkpoint_lock);
     423        }
     424       
     425        irq_spinlock_unlock(&bkpoint_lock, false);
    407426}
    408427
Note: See TracChangeset for help on using the changeset viewer.