Ignore:
File:
1 edited

Legend:

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

    re16e0d59 r96b02eb9  
    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(sysarg_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);
     165                        irq_spinlock_unlock(&bkpoint_lock, true);
    166166                        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)) {
     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))) {
    170170                        printf("Adjacent breakpoints not supported, conflict "
    171171                            "with %d.\n", i);
    172                         spinlock_unlock(&bkpoint_lock);
     172                        irq_spinlock_unlock(&bkpoint_lock, true);
    173173                        return 0;
    174174                }
    175175               
    176176        }
    177 
    178         for (i = 0; i < BKPOINTS_MAX; i++)
     177       
     178        bpinfo_t *cur = NULL;
     179       
     180        for (i = 0; i < BKPOINTS_MAX; i++) {
    179181                if (!breakpoints[i].address) {
    180182                        cur = &breakpoints[i];
    181183                        break;
    182184                }
     185        }
     186       
    183187        if (!cur) {
    184188                printf("Too many breakpoints.\n");
    185                 spinlock_unlock(&bkpoint_lock);
    186                 interrupts_restore(ipl);
     189                irq_spinlock_unlock(&bkpoint_lock, true);
    187190                return 0;
    188191        }
     192       
     193        printf("Adding breakpoint on address %p\n", (void *) argv->intval);
     194       
    189195        cur->address = (uintptr_t) argv->intval;
    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];
     196        cur->instruction = ((sysarg_t *) cur->address)[0];
     197        cur->nextinstruction = ((sysarg_t *) cur->address)[1];
    193198        if (argv == &add_argv) {
    194199                cur->flags = 0;
    195         } else { /* We are add extended */
     200        } else {  /* We are add extended */
    196201                cur->flags = BKPOINT_FUNCCALL;
    197202                cur->bkfunc = (void (*)(void *, istate_t *)) argv[1].intval;
    198203        }
     204       
    199205        if (is_jump(cur->instruction))
    200206                cur->flags |= BKPOINT_ONESHOT;
     207       
    201208        cur->counter = 0;
    202 
     209       
    203210        /* Set breakpoint */
    204         *((unative_t *)cur->address) = 0x0d;
     211        *((sysarg_t *) cur->address) = 0x0d;
    205212        smc_coherence(cur->address);
    206 
    207         spinlock_unlock(&bkpoint_lock);
    208         interrupts_restore(ipl);
    209 
     213       
     214        irq_spinlock_unlock(&bkpoint_lock, true);
     215       
    210216        return 1;
    211217}
    212218
    213 /** Remove breakpoint from table */
     219/** Remove breakpoint from table
     220 *
     221 */
    214222int cmd_del_breakpoint(cmd_arg_t *argv)
    215223{
    216         bpinfo_t *cur;
    217         ipl_t ipl;
    218 
    219224        if (argv->intval > BKPOINTS_MAX) {
    220225                printf("Invalid breakpoint number.\n");
    221226                return 0;
    222227        }
    223         ipl = interrupts_disable();
    224         spinlock_lock(&bkpoint_lock);
    225 
    226         cur = &breakpoints[argv->intval];
     228       
     229        irq_spinlock_lock(&bkpoint_lock, true);
     230       
     231        bpinfo_t *cur = &breakpoints[argv->intval];
    227232        if (!cur->address) {
    228233                printf("Breakpoint does not exist.\n");
    229                 spinlock_unlock(&bkpoint_lock);
    230                 interrupts_restore(ipl);
     234                irq_spinlock_unlock(&bkpoint_lock, true);
    231235                return 0;
    232236        }
     237       
    233238        if ((cur->flags & BKPOINT_INPROG) && (cur->flags & BKPOINT_ONESHOT)) {
    234239                printf("Cannot remove one-shot breakpoint in-progress\n");
    235                 spinlock_unlock(&bkpoint_lock);
    236                 interrupts_restore(ipl);
     240                irq_spinlock_unlock(&bkpoint_lock, true);
    237241                return 0;
    238242        }
    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);
     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       
     249        cur->address = (uintptr_t) NULL;
     250       
     251        irq_spinlock_unlock(&bkpoint_lock, true);
    248252        return 1;
    249253}
    250254
    251 /** Print table of active breakpoints */
     255/** Print table of active breakpoints
     256 *
     257 */
    252258int cmd_print_breakpoints(cmd_arg_t *argv)
    253259{
    254260        unsigned int i;
    255         char *symbol;
    256        
    257         printf("#  Count Address    INPROG ONESHOT FUNCCALL In symbol\n");
    258         printf("-- ----- ---------- ------ ------- -------- ---------\n");
    259        
    260         for (i = 0; i < BKPOINTS_MAX; i++)
     261       
     262        printf("[nr] [count] [address ] [inprog] [oneshot] [funccall] [in symbol\n");
     263       
     264        for (i = 0; i < BKPOINTS_MAX; i++) {
    261265                if (breakpoints[i].address) {
    262                         symbol = symtab_fmt_name_lookup(
     266                        const char *symbol = symtab_fmt_name_lookup(
    263267                            breakpoints[i].address);
    264 
    265                         printf("%-2u %-5d %#10zx %-6s %-7s %-8s %s\n", i,
    266                             breakpoints[i].counter, breakpoints[i].address,
     268                       
     269                        printf("%-4u %7zu %p %-8s %-9s %-10s %s\n", i,
     270                            breakpoints[i].counter, (void *) breakpoints[i].address,
    267271                            ((breakpoints[i].flags & BKPOINT_INPROG) ? "true" :
    268272                            "false"), ((breakpoints[i].flags & BKPOINT_ONESHOT)
     
    270274                            BKPOINT_FUNCCALL) ? "true" : "false"), symbol);
    271275                }
     276        }
     277       
    272278        return 1;
    273279}
    274280
    275 #endif
    276 
    277 /** Initialize debugger */
     281#endif /* CONFIG_KCONSOLE */
     282
     283/** Initialize debugger
     284 *
     285 */
    278286void debugger_init()
    279287{
    280         int i;
    281 
     288        unsigned int i;
     289       
    282290        for (i = 0; i < BKPOINTS_MAX; i++)
    283                 breakpoints[i].address = NULL;
    284 
     291                breakpoints[i].address = (uintptr_t) NULL;
     292       
    285293#ifdef CONFIG_KCONSOLE
    286294        cmd_initialize(&bkpts_info);
    287295        if (!cmd_register(&bkpts_info))
    288296                printf("Cannot register command %s\n", bkpts_info.name);
    289 
     297       
    290298        cmd_initialize(&delbkpt_info);
    291299        if (!cmd_register(&delbkpt_info))
    292300                printf("Cannot register command %s\n", delbkpt_info.name);
    293 
     301       
    294302        cmd_initialize(&addbkpt_info);
    295303        if (!cmd_register(&addbkpt_info))
    296304                printf("Cannot register command %s\n", addbkpt_info.name);
    297 
     305       
    298306        cmd_initialize(&addbkpte_info);
    299307        if (!cmd_register(&addbkpte_info))
    300308                printf("Cannot register command %s\n", addbkpte_info.name);
    301 #endif
     309#endif /* CONFIG_KCONSOLE */
    302310}
    303311
    304312/** Handle breakpoint
    305313 *
    306  * Find breakpoint in breakpoint table. 
     314 * Find breakpoint in breakpoint table.
    307315 * If found, call kconsole, set break on next instruction and reexecute.
    308316 * If we are on "next instruction", set it back on the first and reexecute.
    309317 * If breakpoint not found in breakpoint table, call kconsole and start
    310318 * next instruction.
     319 *
    311320 */
    312321void debugger_bpoint(istate_t *istate)
    313322{
    314         bpinfo_t *cur = NULL;
    315         uintptr_t fireaddr = istate->epc;
    316         int i;
    317 
    318323        /* test branch delay slot */
    319324        if (cp0_cause_read() & 0x80000000)
    320325                panic("Breakpoint in branch delay slot not supported.");
    321 
    322         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       
    323333        for (i = 0; i < BKPOINTS_MAX; i++) {
    324334                /* Normal breakpoint */
    325                 if (fireaddr == breakpoints[i].address &&
    326                     !(breakpoints[i].flags & BKPOINT_REINST)) {
     335                if ((fireaddr == breakpoints[i].address) &&
     336                    (!(breakpoints[i].flags & BKPOINT_REINST))) {
    327337                        cur = &breakpoints[i];
    328338                        break;
    329339                }
     340               
    330341                /* Reinst only breakpoint */
    331342                if ((breakpoints[i].flags & BKPOINT_REINST) &&
    332                     (fireaddr == breakpoints[i].address + sizeof(unative_t))) {
     343                    (fireaddr == breakpoints[i].address + sizeof(sysarg_t))) {
    333344                        cur = &breakpoints[i];
    334345                        break;
    335346                }
    336347        }
     348       
    337349        if (cur) {
    338350                if (cur->flags & BKPOINT_REINST) {
    339351                        /* Set breakpoint on first instruction */
    340                         ((uint32_t *)cur->address)[0] = 0x0d;
     352                        ((uint32_t *) cur->address)[0] = 0x0d;
    341353                        smc_coherence(((uint32_t *)cur->address)[0]);
     354                       
    342355                        /* Return back the second */
    343                         ((uint32_t *)cur->address)[1] = cur->nextinstruction;
    344                         smc_coherence(((uint32_t *)cur->address)[1]);
     356                        ((uint32_t *) cur->address)[1] = cur->nextinstruction;
     357                        smc_coherence(((uint32_t *) cur->address)[1]);
     358                       
    345359                        cur->flags &= ~BKPOINT_REINST;
    346                         spinlock_unlock(&bkpoint_lock);
     360                        irq_spinlock_unlock(&bkpoint_lock, false);
    347361                        return;
    348                 }
     362                }
     363               
    349364                if (cur->flags & BKPOINT_INPROG)
    350365                        printf("Warning: breakpoint recursion\n");
    351366               
    352367                if (!(cur->flags & BKPOINT_FUNCCALL)) {
    353                         printf("***Breakpoint %d: %p in %s.\n", i, fireaddr,
    354                             symtab_fmt_name_lookup(istate->epc));
    355                 }
    356 
     368                        printf("***Breakpoint %u: %p in %s.\n", i,
     369                            (void *) fireaddr,
     370                            symtab_fmt_name_lookup(fireaddr));
     371                }
     372               
    357373                /* Return first instruction back */
    358374                ((uint32_t *)cur->address)[0] = cur->instruction;
     
    366382                cur->flags |= BKPOINT_INPROG;
    367383        } else {
    368                 printf("***Breakpoint %d: %p in %s.\n", i, fireaddr,
     384                printf("***Breakpoint %d: %p in %s.\n", i,
     385                    (void *) fireaddr,
    369386                    symtab_fmt_name_lookup(fireaddr));
    370 
     387               
    371388                /* Move on to next instruction */
    372389                istate->epc += 4;
    373390        }
     391       
    374392        if (cur)
    375393                cur->counter++;
     394       
    376395        if (cur && (cur->flags & BKPOINT_FUNCCALL)) {
    377396                /* Allow zero bkfunc, just for counting */
     
    380399        } else {
    381400#ifdef CONFIG_KCONSOLE
    382                 /* This disables all other processors - we are not SMP,
     401                /*
     402                 * This disables all other processors - we are not SMP,
    383403                 * actually this gets us to cpu_halt, if scheduler() is run
    384404                 * - we generally do not want scheduler to be run from debug,
    385405                 *   so this is a good idea
    386                  */     
     406                 */
    387407                atomic_set(&haltstate, 1);
    388                 spinlock_unlock(&bkpoint_lock);
     408                irq_spinlock_unlock(&bkpoint_lock, false);
    389409               
    390410                kconsole("debug", "Debug console ready.\n", false);
    391411               
    392                 spinlock_lock(&bkpoint_lock);
     412                irq_spinlock_lock(&bkpoint_lock, false);
    393413                atomic_set(&haltstate, 0);
    394414#endif
    395415        }
    396         if (cur && cur->address == fireaddr && (cur->flags & BKPOINT_INPROG)) {
     416       
     417        if ((cur) && (cur->address == fireaddr)
     418            && ((cur->flags & BKPOINT_INPROG))) {
    397419                /* Remove one-shot breakpoint */
    398420                if ((cur->flags & BKPOINT_ONESHOT))
    399                         cur->address = NULL;
     421                        cur->address = (uintptr_t) NULL;
     422               
    400423                /* Remove in-progress flag */
    401424                cur->flags &= ~BKPOINT_INPROG;
    402         }
    403         spinlock_unlock(&bkpoint_lock);
     425        }
     426       
     427        irq_spinlock_unlock(&bkpoint_lock, false);
    404428}
    405429
Note: See TracChangeset for help on using the changeset viewer.