Ignore:
File:
1 edited

Legend:

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

    r63bdde6 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
    134  *
    135  */
    136 bool is_jump(unative_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);
     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{
    260256        unsigned int i;
    261257       
    262         printf("[nr] [count] [address ] [inprog] [oneshot] [funccall] [in symbol\n");
     258        printf("#  Count Address    INPROG ONESHOT FUNCCALL In symbol\n");
     259        printf("-- ----- ---------- ------ ------- -------- ---------\n");
    263260       
    264261        for (i = 0; i < BKPOINTS_MAX; i++) {
     
    267264                            breakpoints[i].address);
    268265                       
    269                         printf("%-4u %7" PRIs " %p %-8s %-9s %-10s %s\n", i,
     266                        printf("%-2u %-5d %#10zx %-6s %-7s %-8s %s\n", i,
    270267                            breakpoints[i].counter, breakpoints[i].address,
    271268                            ((breakpoints[i].flags & BKPOINT_INPROG) ? "true" :
     
    279276}
    280277
    281 #endif /* CONFIG_KCONSOLE */
    282 
    283 /** Initialize debugger
    284  *
    285  */
     278#endif
     279
     280/** Initialize debugger */
    286281void debugger_init()
    287282{
    288         unsigned int i;
    289        
     283        int i;
     284
    290285        for (i = 0; i < BKPOINTS_MAX; i++)
    291286                breakpoints[i].address = NULL;
    292        
     287
    293288#ifdef CONFIG_KCONSOLE
    294289        cmd_initialize(&bkpts_info);
    295290        if (!cmd_register(&bkpts_info))
    296291                printf("Cannot register command %s\n", bkpts_info.name);
    297        
     292
    298293        cmd_initialize(&delbkpt_info);
    299294        if (!cmd_register(&delbkpt_info))
    300295                printf("Cannot register command %s\n", delbkpt_info.name);
    301        
     296
    302297        cmd_initialize(&addbkpt_info);
    303298        if (!cmd_register(&addbkpt_info))
    304299                printf("Cannot register command %s\n", addbkpt_info.name);
    305        
     300
    306301        cmd_initialize(&addbkpte_info);
    307302        if (!cmd_register(&addbkpte_info))
    308303                printf("Cannot register command %s\n", addbkpte_info.name);
    309 #endif /* CONFIG_KCONSOLE */
     304#endif
    310305}
    311306
    312307/** Handle breakpoint
    313308 *
    314  * Find breakpoint in breakpoint table.
     309 * Find breakpoint in breakpoint table. 
    315310 * If found, call kconsole, set break on next instruction and reexecute.
    316311 * If we are on "next instruction", set it back on the first and reexecute.
    317312 * If breakpoint not found in breakpoint table, call kconsole and start
    318313 * next instruction.
    319  *
    320314 */
    321315void debugger_bpoint(istate_t *istate)
    322316{
     317        bpinfo_t *cur = NULL;
     318        uintptr_t fireaddr = istate->epc;
     319        int i;
     320
    323321        /* test branch delay slot */
    324322        if (cp0_cause_read() & 0x80000000)
    325323                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        
     324
     325        spinlock_lock(&bkpoint_lock);
    333326        for (i = 0; i < BKPOINTS_MAX; i++) {
    334327                /* Normal breakpoint */
    335                 if ((fireaddr == breakpoints[i].address) &&
    336                     (!(breakpoints[i].flags & BKPOINT_REINST))) {
     328                if (fireaddr == breakpoints[i].address &&
     329                    !(breakpoints[i].flags & BKPOINT_REINST)) {
    337330                        cur = &breakpoints[i];
    338331                        break;
    339332                }
    340                
    341333                /* Reinst only breakpoint */
    342334                if ((breakpoints[i].flags & BKPOINT_REINST) &&
     
    346338                }
    347339        }
    348        
    349340        if (cur) {
    350341                if (cur->flags & BKPOINT_REINST) {
    351342                        /* Set breakpoint on first instruction */
    352                         ((uint32_t *) cur->address)[0] = 0x0d;
     343                        ((uint32_t *)cur->address)[0] = 0x0d;
    353344                        smc_coherence(((uint32_t *)cur->address)[0]);
    354                        
    355345                        /* Return back the second */
    356                         ((uint32_t *) cur->address)[1] = cur->nextinstruction;
    357                         smc_coherence(((uint32_t *) cur->address)[1]);
    358                        
     346                        ((uint32_t *)cur->address)[1] = cur->nextinstruction;
     347                        smc_coherence(((uint32_t *)cur->address)[1]);
    359348                        cur->flags &= ~BKPOINT_REINST;
    360                         irq_spinlock_unlock(&bkpoint_lock, false);
     349                        spinlock_unlock(&bkpoint_lock);
    361350                        return;
    362                 }
    363                
     351                }
    364352                if (cur->flags & BKPOINT_INPROG)
    365353                        printf("Warning: breakpoint recursion\n");
    366354               
    367355                if (!(cur->flags & BKPOINT_FUNCCALL)) {
    368                         printf("***Breakpoint %u: %p in %s.\n", i, fireaddr,
    369                             symtab_fmt_name_lookup(fireaddr));
    370                 }
    371                
     356                        printf("***Breakpoint %d: %p in %s.\n", i, fireaddr,
     357                            symtab_fmt_name_lookup(istate->epc));
     358                }
     359
    372360                /* Return first instruction back */
    373361                ((uint32_t *)cur->address)[0] = cur->instruction;
     
    383371                printf("***Breakpoint %d: %p in %s.\n", i, fireaddr,
    384372                    symtab_fmt_name_lookup(fireaddr));
    385                
     373
    386374                /* Move on to next instruction */
    387375                istate->epc += 4;
    388376        }
    389        
    390377        if (cur)
    391378                cur->counter++;
    392        
    393379        if (cur && (cur->flags & BKPOINT_FUNCCALL)) {
    394380                /* Allow zero bkfunc, just for counting */
     
    397383        } else {
    398384#ifdef CONFIG_KCONSOLE
    399                 /*
    400                  * This disables all other processors - we are not SMP,
     385                /* This disables all other processors - we are not SMP,
    401386                 * actually this gets us to cpu_halt, if scheduler() is run
    402387                 * - we generally do not want scheduler to be run from debug,
    403388                 *   so this is a good idea
    404                  */
     389                 */     
    405390                atomic_set(&haltstate, 1);
    406                 irq_spinlock_unlock(&bkpoint_lock, false);
     391                spinlock_unlock(&bkpoint_lock);
    407392               
    408393                kconsole("debug", "Debug console ready.\n", false);
    409394               
    410                 irq_spinlock_lock(&bkpoint_lock, false);
     395                spinlock_lock(&bkpoint_lock);
    411396                atomic_set(&haltstate, 0);
    412397#endif
    413398        }
    414        
    415         if ((cur) && (cur->address == fireaddr)
    416             && ((cur->flags & BKPOINT_INPROG))) {
     399        if (cur && cur->address == fireaddr && (cur->flags & BKPOINT_INPROG)) {
    417400                /* Remove one-shot breakpoint */
    418401                if ((cur->flags & BKPOINT_ONESHOT))
    419402                        cur->address = NULL;
    420                
    421403                /* Remove in-progress flag */
    422404                cur->flags &= ~BKPOINT_INPROG;
    423         }
    424        
    425         irq_spinlock_unlock(&bkpoint_lock, false);
     405        }
     406        spinlock_unlock(&bkpoint_lock);
    426407}
    427408
Note: See TracChangeset for help on using the changeset viewer.