Ignore:
File:
1 edited

Legend:

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

    r96b02eb9 re16e0d59  
    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
    134  *
    135  */
    136 bool is_jump(sysarg_t instr)
    137 {
    138         unsigned int i;
    139        
     132 * @return true - it is jump instruction, false otherwise
     133 *
     134 */
     135static bool is_jump(unative_t instr)
     136{
     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);
    166166                        return 0;
    167                 } else if ((breakpoints[i].address == (uintptr_t) argv->intval +
    168                     sizeof(sysarg_t)) || (breakpoints[i].address ==
    169                     (uintptr_t) argv->intval - sizeof(sysarg_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)) {
    170170                        printf("Adjacent breakpoints not supported, conflict "
    171171                            "with %d.\n", i);
    172                         irq_spinlock_unlock(&bkpoint_lock, true);
     172                        spinlock_unlock(&bkpoint_lock);
    173173                        return 0;
    174174                }
    175175               
    176176        }
    177        
    178         bpinfo_t *cur = NULL;
    179        
    180         for (i = 0; i < BKPOINTS_MAX; i++) {
     177
     178        for (i = 0; i < BKPOINTS_MAX; i++)
    181179                if (!breakpoints[i].address) {
    182180                        cur = &breakpoints[i];
    183181                        break;
    184182                }
    185         }
    186        
    187183        if (!cur) {
    188184                printf("Too many breakpoints.\n");
    189                 irq_spinlock_unlock(&bkpoint_lock, true);
     185                spinlock_unlock(&bkpoint_lock);
     186                interrupts_restore(ipl);
    190187                return 0;
    191188        }
    192        
    193         printf("Adding breakpoint on address %p\n", (void *) argv->intval);
    194        
    195189        cur->address = (uintptr_t) argv->intval;
    196         cur->instruction = ((sysarg_t *) cur->address)[0];
    197         cur->nextinstruction = ((sysarg_t *) cur->address)[1];
     190        printf("Adding breakpoint on address: %p\n", argv->intval);
     191        cur->instruction = ((unative_t *)cur->address)[0];
     192        cur->nextinstruction = ((unative_t *)cur->address)[1];
    198193        if (argv == &add_argv) {
    199194                cur->flags = 0;
    200         } else {  /* We are add extended */
     195        } else { /* We are add extended */
    201196                cur->flags = BKPOINT_FUNCCALL;
    202197                cur->bkfunc = (void (*)(void *, istate_t *)) argv[1].intval;
    203198        }
    204        
    205199        if (is_jump(cur->instruction))
    206200                cur->flags |= BKPOINT_ONESHOT;
    207        
    208201        cur->counter = 0;
    209        
     202
    210203        /* Set breakpoint */
    211         *((sysarg_t *) cur->address) = 0x0d;
     204        *((unative_t *)cur->address) = 0x0d;
    212205        smc_coherence(cur->address);
    213        
    214         irq_spinlock_unlock(&bkpoint_lock, true);
    215        
     206
     207        spinlock_unlock(&bkpoint_lock);
     208        interrupts_restore(ipl);
     209
    216210        return 1;
    217211}
    218212
    219 /** Remove breakpoint from table
    220  *
    221  */
     213/** Remove breakpoint from table */
    222214int cmd_del_breakpoint(cmd_arg_t *argv)
    223215{
     216        bpinfo_t *cur;
     217        ipl_t ipl;
     218
    224219        if (argv->intval > BKPOINTS_MAX) {
    225220                printf("Invalid breakpoint number.\n");
    226221                return 0;
    227222        }
    228        
    229         irq_spinlock_lock(&bkpoint_lock, true);
    230        
    231         bpinfo_t *cur = &breakpoints[argv->intval];
     223        ipl = interrupts_disable();
     224        spinlock_lock(&bkpoint_lock);
     225
     226        cur = &breakpoints[argv->intval];
    232227        if (!cur->address) {
    233228                printf("Breakpoint does not exist.\n");
    234                 irq_spinlock_unlock(&bkpoint_lock, true);
     229                spinlock_unlock(&bkpoint_lock);
     230                interrupts_restore(ipl);
    235231                return 0;
    236232        }
    237        
    238233        if ((cur->flags & BKPOINT_INPROG) && (cur->flags & BKPOINT_ONESHOT)) {
    239234                printf("Cannot remove one-shot breakpoint in-progress\n");
    240                 irq_spinlock_unlock(&bkpoint_lock, true);
     235                spinlock_unlock(&bkpoint_lock);
     236                interrupts_restore(ipl);
    241237                return 0;
    242238        }
     239        ((uint32_t *)cur->address)[0] = cur->instruction;
     240        smc_coherence(((uint32_t *)cur->address)[0]);
     241        ((uint32_t *)cur->address)[1] = cur->nextinstruction;
     242        smc_coherence(((uint32_t *)cur->address)[1]);
     243
     244        cur->address = NULL;
     245
     246        spinlock_unlock(&bkpoint_lock);
     247        interrupts_restore(ipl);
     248        return 1;
     249}
     250
     251/** Print table of active breakpoints */
     252int cmd_print_breakpoints(cmd_arg_t *argv)
     253{
     254        unsigned int i;
     255        char *symbol;
    243256       
    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]);
     257        printf("#  Count Address    INPROG ONESHOT FUNCCALL In symbol\n");
     258        printf("-- ----- ---------- ------ ------- -------- ---------\n");
    248259       
    249         cur->address = (uintptr_t) NULL;
    250        
    251         irq_spinlock_unlock(&bkpoint_lock, true);
    252         return 1;
    253 }
    254 
    255 /** Print table of active breakpoints
    256  *
    257  */
    258 int cmd_print_breakpoints(cmd_arg_t *argv)
    259 {
    260         unsigned int i;
    261        
    262         printf("[nr] [count] [address ] [inprog] [oneshot] [funccall] [in symbol\n");
    263        
    264         for (i = 0; i < BKPOINTS_MAX; i++) {
     260        for (i = 0; i < BKPOINTS_MAX; i++)
    265261                if (breakpoints[i].address) {
    266                         const char *symbol = symtab_fmt_name_lookup(
     262                        symbol = symtab_fmt_name_lookup(
    267263                            breakpoints[i].address);
    268                        
    269                         printf("%-4u %7zu %p %-8s %-9s %-10s %s\n", i,
    270                             breakpoints[i].counter, (void *) breakpoints[i].address,
     264
     265                        printf("%-2u %-5d %#10zx %-6s %-7s %-8s %s\n", i,
     266                            breakpoints[i].counter, breakpoints[i].address,
    271267                            ((breakpoints[i].flags & BKPOINT_INPROG) ? "true" :
    272268                            "false"), ((breakpoints[i].flags & BKPOINT_ONESHOT)
     
    274270                            BKPOINT_FUNCCALL) ? "true" : "false"), symbol);
    275271                }
    276         }
    277        
    278272        return 1;
    279273}
    280274
    281 #endif /* CONFIG_KCONSOLE */
    282 
    283 /** Initialize debugger
    284  *
    285  */
     275#endif
     276
     277/** Initialize debugger */
    286278void debugger_init()
    287279{
    288         unsigned int i;
    289        
     280        int i;
     281
    290282        for (i = 0; i < BKPOINTS_MAX; i++)
    291                 breakpoints[i].address = (uintptr_t) NULL;
    292        
     283                breakpoints[i].address = NULL;
     284
    293285#ifdef CONFIG_KCONSOLE
    294286        cmd_initialize(&bkpts_info);
    295287        if (!cmd_register(&bkpts_info))
    296288                printf("Cannot register command %s\n", bkpts_info.name);
    297        
     289
    298290        cmd_initialize(&delbkpt_info);
    299291        if (!cmd_register(&delbkpt_info))
    300292                printf("Cannot register command %s\n", delbkpt_info.name);
    301        
     293
    302294        cmd_initialize(&addbkpt_info);
    303295        if (!cmd_register(&addbkpt_info))
    304296                printf("Cannot register command %s\n", addbkpt_info.name);
    305        
     297
    306298        cmd_initialize(&addbkpte_info);
    307299        if (!cmd_register(&addbkpte_info))
    308300                printf("Cannot register command %s\n", addbkpte_info.name);
    309 #endif /* CONFIG_KCONSOLE */
     301#endif
    310302}
    311303
    312304/** Handle breakpoint
    313305 *
    314  * Find breakpoint in breakpoint table.
     306 * Find breakpoint in breakpoint table. 
    315307 * If found, call kconsole, set break on next instruction and reexecute.
    316308 * If we are on "next instruction", set it back on the first and reexecute.
    317309 * If breakpoint not found in breakpoint table, call kconsole and start
    318310 * next instruction.
    319  *
    320311 */
    321312void debugger_bpoint(istate_t *istate)
    322313{
     314        bpinfo_t *cur = NULL;
     315        uintptr_t fireaddr = istate->epc;
     316        int i;
     317
    323318        /* test branch delay slot */
    324319        if (cp0_cause_read() & 0x80000000)
    325320                panic("Breakpoint in branch delay slot not supported.");
    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        
     321
     322        spinlock_lock(&bkpoint_lock);
    333323        for (i = 0; i < BKPOINTS_MAX; i++) {
    334324                /* Normal breakpoint */
    335                 if ((fireaddr == breakpoints[i].address) &&
    336                     (!(breakpoints[i].flags & BKPOINT_REINST))) {
     325                if (fireaddr == breakpoints[i].address &&
     326                    !(breakpoints[i].flags & BKPOINT_REINST)) {
    337327                        cur = &breakpoints[i];
    338328                        break;
    339329                }
    340                
    341330                /* Reinst only breakpoint */
    342331                if ((breakpoints[i].flags & BKPOINT_REINST) &&
    343                     (fireaddr == breakpoints[i].address + sizeof(sysarg_t))) {
     332                    (fireaddr == breakpoints[i].address + sizeof(unative_t))) {
    344333                        cur = &breakpoints[i];
    345334                        break;
    346335                }
    347336        }
    348        
    349337        if (cur) {
    350338                if (cur->flags & BKPOINT_REINST) {
    351339                        /* Set breakpoint on first instruction */
    352                         ((uint32_t *) cur->address)[0] = 0x0d;
     340                        ((uint32_t *)cur->address)[0] = 0x0d;
    353341                        smc_coherence(((uint32_t *)cur->address)[0]);
    354                        
    355342                        /* Return back the second */
    356                         ((uint32_t *) cur->address)[1] = cur->nextinstruction;
    357                         smc_coherence(((uint32_t *) cur->address)[1]);
    358                        
     343                        ((uint32_t *)cur->address)[1] = cur->nextinstruction;
     344                        smc_coherence(((uint32_t *)cur->address)[1]);
    359345                        cur->flags &= ~BKPOINT_REINST;
    360                         irq_spinlock_unlock(&bkpoint_lock, false);
     346                        spinlock_unlock(&bkpoint_lock);
    361347                        return;
    362                 }
    363                
     348                }
    364349                if (cur->flags & BKPOINT_INPROG)
    365350                        printf("Warning: breakpoint recursion\n");
    366351               
    367352                if (!(cur->flags & BKPOINT_FUNCCALL)) {
    368                         printf("***Breakpoint %u: %p in %s.\n", i,
    369                             (void *) fireaddr,
    370                             symtab_fmt_name_lookup(fireaddr));
    371                 }
    372                
     353                        printf("***Breakpoint %d: %p in %s.\n", i, fireaddr,
     354                            symtab_fmt_name_lookup(istate->epc));
     355                }
     356
    373357                /* Return first instruction back */
    374358                ((uint32_t *)cur->address)[0] = cur->instruction;
     
    382366                cur->flags |= BKPOINT_INPROG;
    383367        } else {
    384                 printf("***Breakpoint %d: %p in %s.\n", i,
    385                     (void *) fireaddr,
     368                printf("***Breakpoint %d: %p in %s.\n", i, fireaddr,
    386369                    symtab_fmt_name_lookup(fireaddr));
    387                
     370
    388371                /* Move on to next instruction */
    389372                istate->epc += 4;
    390373        }
    391        
    392374        if (cur)
    393375                cur->counter++;
    394        
    395376        if (cur && (cur->flags & BKPOINT_FUNCCALL)) {
    396377                /* Allow zero bkfunc, just for counting */
     
    399380        } else {
    400381#ifdef CONFIG_KCONSOLE
    401                 /*
    402                  * This disables all other processors - we are not SMP,
     382                /* This disables all other processors - we are not SMP,
    403383                 * actually this gets us to cpu_halt, if scheduler() is run
    404384                 * - we generally do not want scheduler to be run from debug,
    405385                 *   so this is a good idea
    406                  */
     386                 */     
    407387                atomic_set(&haltstate, 1);
    408                 irq_spinlock_unlock(&bkpoint_lock, false);
     388                spinlock_unlock(&bkpoint_lock);
    409389               
    410390                kconsole("debug", "Debug console ready.\n", false);
    411391               
    412                 irq_spinlock_lock(&bkpoint_lock, false);
     392                spinlock_lock(&bkpoint_lock);
    413393                atomic_set(&haltstate, 0);
    414394#endif
    415395        }
    416        
    417         if ((cur) && (cur->address == fireaddr)
    418             && ((cur->flags & BKPOINT_INPROG))) {
     396        if (cur && cur->address == fireaddr && (cur->flags & BKPOINT_INPROG)) {
    419397                /* Remove one-shot breakpoint */
    420398                if ((cur->flags & BKPOINT_ONESHOT))
    421                         cur->address = (uintptr_t) NULL;
    422                
     399                        cur->address = NULL;
    423400                /* Remove in-progress flag */
    424401                cur->flags &= ~BKPOINT_INPROG;
    425         }
    426        
    427         irq_spinlock_unlock(&bkpoint_lock, false);
     402        }
     403        spinlock_unlock(&bkpoint_lock);
    428404}
    429405
Note: See TracChangeset for help on using the changeset viewer.