Ignore:
File:
1 edited

Legend:

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

    re16e0d59 r96b02eb9  
    4646#include <symtab.h>
    4747
     48#ifdef __64_BITS__
     49        #define getip(x)  ((x)->rip)
     50#endif
     51
     52#ifdef __32_BITS__
     53        #define getip(x)  ((x)->eip)
     54#endif
     55
    4856typedef struct  {
    49         uintptr_t address;      /**< Breakpoint address */
    50         int flags;              /**< Flags regarding breakpoint */
    51         int counter;            /**< How many times the exception occured */
     57        uintptr_t address;   /**< Breakpoint address */
     58        unsigned int flags;  /**< Flags regarding breakpoint */
     59        size_t counter;      /**< How many times the exception occured */
    5260} bpinfo_t;
    5361
    5462static bpinfo_t breakpoints[BKPOINTS_MAX];
    55 SPINLOCK_INITIALIZE(bkpoint_lock);
     63IRQ_SPINLOCK_STATIC_INITIALIZE(bkpoint_lock);
    5664
    5765#ifdef CONFIG_KCONSOLE
    5866
    59 static int cmd_print_breakpoints(cmd_arg_t *argv);
     67static int cmd_print_breakpoints(cmd_arg_t *);
     68static int cmd_del_breakpoint(cmd_arg_t *);
     69static int cmd_add_breakpoint(cmd_arg_t *);
     70
    6071static cmd_info_t bkpts_info = {
    6172        .name = "bkpts",
     
    6576};
    6677
    67 static int cmd_del_breakpoint(cmd_arg_t *argv);
    6878static cmd_arg_t del_argv = {
    6979        .type = ARG_TYPE_INT
    7080};
     81
    7182static cmd_info_t delbkpt_info = {
    7283        .name = "delbkpt",
    73         .description = "delbkpt <number> - Delete breakpoint.",
     84        .description = "Delete breakpoint.",
    7485        .func = cmd_del_breakpoint,
    7586        .argc = 1,
     
    7788};
    7889
    79 static int cmd_add_breakpoint(cmd_arg_t *argv);
    8090static cmd_arg_t add_argv = {
    8191        .type = ARG_TYPE_INT
    8292};
     93
    8394static cmd_info_t addbkpt_info = {
    8495        .name = "addbkpt",
    85         .description = "addbkpt <&symbol> - new breakpoint.",
     96        .description = "Add breakpoint.",
    8697        .func = cmd_add_breakpoint,
    8798        .argc = 1,
     
    92103        .type = ARG_TYPE_INT
    93104};
     105
    94106static cmd_info_t addwatchp_info = {
    95107        .name = "addwatchp",
    96         .description = "addbwatchp <&symbol> - new write watchpoint.",
     108        .description = "Add write watchpoint.",
    97109        .func = cmd_add_breakpoint,
    98110        .argc = 1,
     
    102114#endif /* CONFIG_KCONSOLE */
    103115
    104 /* Setup DR register according to table */
     116/** Setup DR register according to table
     117 *
     118 */
    105119static void setup_dr(int curidx)
    106120{
    107         unative_t dr7;
     121        ASSERT(curidx >= 0);
     122       
    108123        bpinfo_t *cur = &breakpoints[curidx];
    109         int flags = breakpoints[curidx].flags;
    110 
     124        unsigned int flags = breakpoints[curidx].flags;
     125       
    111126        /* Disable breakpoint in DR7 */
    112         dr7 = read_dr7();
    113         dr7 &= ~(0x2 << (curidx*2));
    114 
    115         if (cur->address) { /* Setup DR register */
     127        sysarg_t dr7 = read_dr7();
     128        dr7 &= ~(0x02U << (curidx * 2));
     129       
     130        /* Setup DR register */
     131        if (cur->address) {
    116132                /* Set breakpoint to debug registers */
    117133                switch (curidx) {
     
    129145                        break;
    130146                }
     147               
    131148                /* Set type to requested breakpoint & length*/
    132                 dr7 &= ~ (0x3 << (16 + 4*curidx));
    133                 dr7 &= ~ (0x3 << (18 + 4*curidx));
    134                 if ((flags & BKPOINT_INSTR)) {
    135                         ;
    136                 } else {
     149                dr7 &= ~(0x03U << (16 + 4 * curidx));
     150                dr7 &= ~(0x03U << (18 + 4 * curidx));
    137151               
     152                if (!(flags & BKPOINT_INSTR)) {
    138153#ifdef __32_BITS__
    139                         dr7 |= ((unative_t) 0x3) << (18 + 4 * curidx);
    140 #endif
    141 
     154                        dr7 |= ((sysarg_t) 0x03U) << (18 + 4 * curidx);
     155#endif
     156                       
    142157#ifdef __64_BITS__
    143                         dr7 |= ((unative_t) 0x2) << (18 + 4 * curidx);
     158                        dr7 |= ((sysarg_t) 0x02U) << (18 + 4 * curidx);
    144159#endif
    145160                       
    146161                        if ((flags & BKPOINT_WRITE))
    147                                 dr7 |= ((unative_t) 0x1) << (16 + 4 * curidx);
     162                                dr7 |= ((sysarg_t) 0x01U) << (16 + 4 * curidx);
    148163                        else if ((flags & BKPOINT_READ_WRITE))
    149                                 dr7 |= ((unative_t) 0x3) << (16 + 4 * curidx);
    150                 }
    151 
     164                                dr7 |= ((sysarg_t) 0x03U) << (16 + 4 * curidx);
     165                }
     166               
    152167                /* Enable global breakpoint */
    153                 dr7 |= 0x2 << (curidx * 2);
    154 
     168                dr7 |= 0x02U << (curidx * 2);
     169               
    155170                write_dr7(dr7);
    156                
    157         }
    158 }
    159        
     171        }
     172}
     173
    160174/** Enable hardware breakpoint
    161175 *
    162176 * @param where Address of HW breakpoint
    163177 * @param flags Type of breakpoint (EXECUTE, WRITE)
     178 *
    164179 * @return Debug slot on success, -1 - no available HW breakpoint
    165  */
    166 int breakpoint_add(const void *where, const int flags, int curidx)
    167 {
    168         ipl_t ipl;
    169         int i;
    170         bpinfo_t *cur;
    171 
     180 *
     181 */
     182int breakpoint_add(const void *where, const unsigned int flags, int curidx)
     183{
    172184        ASSERT(flags & (BKPOINT_INSTR | BKPOINT_WRITE | BKPOINT_READ_WRITE));
    173 
    174         ipl = interrupts_disable();
    175         spinlock_lock(&bkpoint_lock);
     185       
     186        irq_spinlock_lock(&bkpoint_lock, true);
    176187       
    177188        if (curidx == -1) {
    178189                /* Find free space in slots */
    179                 for (i = 0; i < BKPOINTS_MAX; i++)
     190                unsigned int i;
     191                for (i = 0; i < BKPOINTS_MAX; i++) {
    180192                        if (!breakpoints[i].address) {
    181193                                curidx = i;
    182194                                break;
    183195                        }
     196                }
     197               
    184198                if (curidx == -1) {
    185199                        /* Too many breakpoints */
    186                         spinlock_unlock(&bkpoint_lock);
    187                         interrupts_restore(ipl);
     200                        irq_spinlock_unlock(&bkpoint_lock, true);
    188201                        return -1;
    189202                }
    190203        }
    191         cur = &breakpoints[curidx];
    192 
     204       
     205        bpinfo_t *cur = &breakpoints[curidx];
     206       
    193207        cur->address = (uintptr_t) where;
    194208        cur->flags = flags;
    195209        cur->counter = 0;
    196 
     210       
    197211        setup_dr(curidx);
    198 
    199         spinlock_unlock(&bkpoint_lock);
    200         interrupts_restore(ipl);
    201 
     212       
     213        irq_spinlock_unlock(&bkpoint_lock, true);
     214       
    202215        /* Send IPI */
    203 #ifdef CONFIG_SMP
    204216//      ipi_broadcast(VECTOR_DEBUG_IPI);
    205 #endif 
    206 
     217       
    207218        return curidx;
    208219}
    209220
    210 #ifdef __64_BITS__
    211         #define getip(x)  ((x)->rip)
    212 #else
    213         #define getip(x)  ((x)->eip)
    214 #endif
    215 
    216221static void handle_exception(int slot, istate_t *istate)
    217222{
     223        ASSERT(slot >= 0);
    218224        ASSERT(breakpoints[slot].address);
    219 
     225       
    220226        /* Handle zero checker */
    221         if (! (breakpoints[slot].flags & BKPOINT_INSTR)) {
     227        if (!(breakpoints[slot].flags & BKPOINT_INSTR)) {
    222228                if ((breakpoints[slot].flags & BKPOINT_CHECK_ZERO)) {
    223                         if (*((unative_t *) breakpoints[slot].address) != 0)
     229                        if (*((sysarg_t *) breakpoints[slot].address) != 0)
    224230                                return;
    225                         printf("*** Found ZERO on address %lx (slot %d) ***\n",
    226                             breakpoints[slot].address, slot);
     231                       
     232                        printf("*** Found ZERO on address %p (slot %d) ***\n",
     233                            (void *) breakpoints[slot].address, slot);
    227234                } else {
    228                         printf("Data watchpoint - new data: %lx\n",
    229                             *((unative_t *) breakpoints[slot].address));
    230                 }
    231         }
    232 
    233         printf("Reached breakpoint %d:%lx (%s)\n", slot, getip(istate),
    234             symtab_fmt_name_lookup(getip(istate)));
    235 
     235                        printf("Data watchpoint - new data: %#" PRIxn "\n",
     236                            *((sysarg_t *) breakpoints[slot].address));
     237                }
     238        }
     239       
     240        printf("Reached breakpoint %d:%p (%s)\n", slot,
     241            (void *) getip(istate), symtab_fmt_name_lookup(getip(istate)));
     242       
    236243#ifdef CONFIG_KCONSOLE
    237244        atomic_set(&haltstate, 1);
     
    243250void breakpoint_del(int slot)
    244251{
    245         bpinfo_t *cur;
    246         ipl_t ipl;
    247 
    248         ipl = interrupts_disable();
    249         spinlock_lock(&bkpoint_lock);
    250 
    251         cur = &breakpoints[slot];
     252        ASSERT(slot >= 0);
     253       
     254        irq_spinlock_lock(&bkpoint_lock, true);
     255       
     256        bpinfo_t *cur = &breakpoints[slot];
    252257        if (!cur->address) {
    253                 spinlock_unlock(&bkpoint_lock);
    254                 interrupts_restore(ipl);
     258                irq_spinlock_unlock(&bkpoint_lock, true);
    255259                return;
    256260        }
    257 
    258         cur->address = NULL;
    259 
     261       
     262        cur->address = (uintptr_t) NULL;
     263       
    260264        setup_dr(slot);
    261 
    262         spinlock_unlock(&bkpoint_lock);
    263         interrupts_restore(ipl);
    264 #ifdef CONFIG_SMP
    265 //      ipi_broadcast(VECTOR_DEBUG_IPI);       
    266 #endif
    267 }
    268 
    269 
    270 
    271 static void debug_exception(int n __attribute__((unused)), istate_t *istate)
    272 {
    273         unative_t dr6;
    274         int i;
    275        
     265       
     266        irq_spinlock_unlock(&bkpoint_lock, true);
     267//      ipi_broadcast(VECTOR_DEBUG_IPI);
     268}
     269
     270static void debug_exception(unsigned int n __attribute__((unused)), istate_t *istate)
     271{
    276272        /* Set RF to restart the instruction  */
    277273#ifdef __64_BITS__
    278274        istate->rflags |= RFLAGS_RF;
    279 #else
     275#endif
     276       
     277#ifdef __32_BITS__
    280278        istate->eflags |= EFLAGS_RF;
    281279#endif
    282 
    283         dr6 = read_dr6();
    284         for (i=0; i < BKPOINTS_MAX; i++) {
     280       
     281        sysarg_t dr6 = read_dr6();
     282       
     283        unsigned int i;
     284        for (i = 0; i < BKPOINTS_MAX; i++) {
    285285                if (dr6 & (1 << i)) {
    286286                        dr6 &= ~ (1 << i);
     
    293293
    294294#ifdef CONFIG_SMP
    295 static void
    296 debug_ipi(int n __attribute__((unused)),
     295static void debug_ipi(unsigned int n __attribute__((unused)),
    297296    istate_t *istate __attribute__((unused)))
    298297{
    299         int i;
    300 
    301         spinlock_lock(&bkpoint_lock);
     298        irq_spinlock_lock(&bkpoint_lock, false);
     299       
     300        unsigned int i;
    302301        for (i = 0; i < BKPOINTS_MAX; i++)
    303302                setup_dr(i);
    304         spinlock_unlock(&bkpoint_lock);
    305 }
    306 #endif
    307 
    308 /** Initialize debugger */
     303       
     304        irq_spinlock_unlock(&bkpoint_lock, false);
     305}
     306#endif /* CONFIG_SMP */
     307
     308/** Initialize debugger
     309 *
     310 */
    309311void debugger_init()
    310312{
    311         int i;
    312 
     313        unsigned int i;
    313314        for (i = 0; i < BKPOINTS_MAX; i++)
    314                 breakpoints[i].address = NULL;
    315 
     315                breakpoints[i].address = (uintptr_t) NULL;
     316       
    316317#ifdef CONFIG_KCONSOLE
    317318        cmd_initialize(&bkpts_info);
    318319        if (!cmd_register(&bkpts_info))
    319320                printf("Cannot register command %s\n", bkpts_info.name);
    320 
     321       
    321322        cmd_initialize(&delbkpt_info);
    322323        if (!cmd_register(&delbkpt_info))
    323324                printf("Cannot register command %s\n", delbkpt_info.name);
    324 
     325       
    325326        cmd_initialize(&addbkpt_info);
    326327        if (!cmd_register(&addbkpt_info))
    327328                printf("Cannot register command %s\n", addbkpt_info.name);
    328 
     329       
    329330        cmd_initialize(&addwatchp_info);
    330331        if (!cmd_register(&addwatchp_info))
     
    332333#endif /* CONFIG_KCONSOLE */
    333334       
    334         exc_register(VECTOR_DEBUG, "debugger", debug_exception);
     335        exc_register(VECTOR_DEBUG, "debugger", true,
     336            debug_exception);
     337       
    335338#ifdef CONFIG_SMP
    336         exc_register(VECTOR_DEBUG_IPI, "debugger_smp", debug_ipi);
    337 #endif
     339        exc_register(VECTOR_DEBUG_IPI, "debugger_smp", true,
     340            debug_ipi);
     341#endif /* CONFIG_SMP */
    338342}
    339343
    340344#ifdef CONFIG_KCONSOLE
    341 /** Print table of active breakpoints */
     345/** Print table of active breakpoints
     346 *
     347 */
    342348int cmd_print_breakpoints(cmd_arg_t *argv __attribute__((unused)))
    343349{
     350#ifdef __32_BITS__
     351        printf("[nr] [count] [address ] [in symbol\n");
     352#endif
     353       
     354#ifdef __64_BITS__
     355        printf("[nr] [count] [address         ] [in symbol\n");
     356#endif
     357       
    344358        unsigned int i;
    345         char *symbol;
    346 
     359        for (i = 0; i < BKPOINTS_MAX; i++) {
     360                if (breakpoints[i].address) {
     361                        const char *symbol = symtab_fmt_name_lookup(
     362                            breakpoints[i].address);
     363                       
    347364#ifdef __32_BITS__
    348         printf("#  Count Address    In symbol\n");
    349         printf("-- ----- ---------- ---------\n");
    350 #endif
    351 
     365                        printf("%-4u %7zu %p %s\n", i,
     366                            breakpoints[i].counter, (void *) breakpoints[i].address,
     367                            symbol);
     368#endif
     369                       
    352370#ifdef __64_BITS__
    353         printf("#  Count Address            In symbol\n");
    354         printf("-- ----- ------------------ ---------\n");
    355 #endif
    356        
    357         for (i = 0; i < BKPOINTS_MAX; i++)
    358                 if (breakpoints[i].address) {
    359                         symbol = symtab_fmt_name_lookup(
    360                             breakpoints[i].address);
    361 
    362 #ifdef __32_BITS__
    363                         printf("%-2u %-5d %#10zx %s\n", i,
    364                             breakpoints[i].counter, breakpoints[i].address,
     371                        printf("%-4u %7zu %p %s\n", i,
     372                            breakpoints[i].counter, (void *) breakpoints[i].address,
    365373                            symbol);
    366374#endif
    367 
    368 #ifdef __64_BITS__
    369                         printf("%-2u %-5d %#18zx %s\n", i,
    370                             breakpoints[i].counter, breakpoints[i].address,
    371                             symbol);
    372 #endif
    373 
    374                 }
     375                }
     376        }
     377       
    375378        return 1;
    376379}
    377380
    378 /** Remove breakpoint from table */
     381/** Remove breakpoint from table
     382 *
     383 */
    379384int cmd_del_breakpoint(cmd_arg_t *argv)
    380385{
    381         unative_t bpno = argv->intval;
     386        sysarg_t bpno = argv->intval;
    382387        if (bpno > BKPOINTS_MAX) {
    383388                printf("Invalid breakpoint number.\n");
    384389                return 0;
    385390        }
     391       
    386392        breakpoint_del(argv->intval);
    387393        return 1;
    388394}
    389395
    390 /** Add new breakpoint to table */
     396/** Add new breakpoint to table
     397 *
     398 */
    391399static int cmd_add_breakpoint(cmd_arg_t *argv)
    392400{
    393         int flags;
    394         int id;
    395 
    396         if (argv == &add_argv) {
     401        unsigned int flags;
     402        if (argv == &add_argv)
    397403                flags = BKPOINT_INSTR;
    398         } else { /* addwatchp */
     404        else
    399405                flags = BKPOINT_WRITE;
    400         }
    401         printf("Adding breakpoint on address: %p\n", argv->intval);
    402         id = breakpoint_add((void *)argv->intval, flags, -1);
     406       
     407        printf("Adding breakpoint on address: %p\n",
     408            (void *) argv->intval);
     409       
     410        int id = breakpoint_add((void *) argv->intval, flags, -1);
    403411        if (id < 0)
    404412                printf("Add breakpoint failed.\n");
Note: See TracChangeset for help on using the changeset viewer.