Ignore:
File:
1 edited

Legend:

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

    r96b02eb9 re16e0d59  
    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 
    5648typedef struct  {
    57         uintptr_t address;   /**< Breakpoint address */
    58         unsigned int flags;  /**< Flags regarding breakpoint */
    59         size_t counter;      /**< How many times the exception occured */
     49        uintptr_t address;      /**< Breakpoint address */
     50        int flags;              /**< Flags regarding breakpoint */
     51        int counter;            /**< How many times the exception occured */
    6052} bpinfo_t;
    6153
    6254static bpinfo_t breakpoints[BKPOINTS_MAX];
    63 IRQ_SPINLOCK_STATIC_INITIALIZE(bkpoint_lock);
     55SPINLOCK_INITIALIZE(bkpoint_lock);
    6456
    6557#ifdef CONFIG_KCONSOLE
    6658
    67 static int cmd_print_breakpoints(cmd_arg_t *);
    68 static int cmd_del_breakpoint(cmd_arg_t *);
    69 static int cmd_add_breakpoint(cmd_arg_t *);
    70 
     59static int cmd_print_breakpoints(cmd_arg_t *argv);
    7160static cmd_info_t bkpts_info = {
    7261        .name = "bkpts",
     
    7665};
    7766
     67static int cmd_del_breakpoint(cmd_arg_t *argv);
    7868static cmd_arg_t del_argv = {
    7969        .type = ARG_TYPE_INT
    8070};
    81 
    8271static cmd_info_t delbkpt_info = {
    8372        .name = "delbkpt",
    84         .description = "Delete breakpoint.",
     73        .description = "delbkpt <number> - Delete breakpoint.",
    8574        .func = cmd_del_breakpoint,
    8675        .argc = 1,
     
    8877};
    8978
     79static int cmd_add_breakpoint(cmd_arg_t *argv);
    9080static cmd_arg_t add_argv = {
    9181        .type = ARG_TYPE_INT
    9282};
    93 
    9483static cmd_info_t addbkpt_info = {
    9584        .name = "addbkpt",
    96         .description = "Add breakpoint.",
     85        .description = "addbkpt <&symbol> - new breakpoint.",
    9786        .func = cmd_add_breakpoint,
    9887        .argc = 1,
     
    10392        .type = ARG_TYPE_INT
    10493};
    105 
    10694static cmd_info_t addwatchp_info = {
    10795        .name = "addwatchp",
    108         .description = "Add write watchpoint.",
     96        .description = "addbwatchp <&symbol> - new write watchpoint.",
    10997        .func = cmd_add_breakpoint,
    11098        .argc = 1,
     
    114102#endif /* CONFIG_KCONSOLE */
    115103
    116 /** Setup DR register according to table
    117  *
    118  */
     104/* Setup DR register according to table */
    119105static void setup_dr(int curidx)
    120106{
    121         ASSERT(curidx >= 0);
    122        
     107        unative_t dr7;
    123108        bpinfo_t *cur = &breakpoints[curidx];
    124         unsigned int flags = breakpoints[curidx].flags;
    125        
     109        int flags = breakpoints[curidx].flags;
     110
    126111        /* Disable breakpoint in DR7 */
    127         sysarg_t dr7 = read_dr7();
    128         dr7 &= ~(0x02U << (curidx * 2));
    129        
    130         /* Setup DR register */
    131         if (cur->address) {
     112        dr7 = read_dr7();
     113        dr7 &= ~(0x2 << (curidx*2));
     114
     115        if (cur->address) { /* Setup DR register */
    132116                /* Set breakpoint to debug registers */
    133117                switch (curidx) {
     
    145129                        break;
    146130                }
     131                /* 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 {
    147137               
    148                 /* Set type to requested breakpoint & length*/
    149                 dr7 &= ~(0x03U << (16 + 4 * curidx));
    150                 dr7 &= ~(0x03U << (18 + 4 * curidx));
    151                
    152                 if (!(flags & BKPOINT_INSTR)) {
    153138#ifdef __32_BITS__
    154                         dr7 |= ((sysarg_t) 0x03U) << (18 + 4 * curidx);
    155 #endif
    156                        
     139                        dr7 |= ((unative_t) 0x3) << (18 + 4 * curidx);
     140#endif
     141
    157142#ifdef __64_BITS__
    158                         dr7 |= ((sysarg_t) 0x02U) << (18 + 4 * curidx);
     143                        dr7 |= ((unative_t) 0x2) << (18 + 4 * curidx);
    159144#endif
    160145                       
    161146                        if ((flags & BKPOINT_WRITE))
    162                                 dr7 |= ((sysarg_t) 0x01U) << (16 + 4 * curidx);
     147                                dr7 |= ((unative_t) 0x1) << (16 + 4 * curidx);
    163148                        else if ((flags & BKPOINT_READ_WRITE))
    164                                 dr7 |= ((sysarg_t) 0x03U) << (16 + 4 * curidx);
    165                 }
     149                                dr7 |= ((unative_t) 0x3) << (16 + 4 * curidx);
     150                }
     151
     152                /* Enable global breakpoint */
     153                dr7 |= 0x2 << (curidx * 2);
     154
     155                write_dr7(dr7);
    166156               
    167                 /* Enable global breakpoint */
    168                 dr7 |= 0x02U << (curidx * 2);
    169                
    170                 write_dr7(dr7);
    171         }
    172 }
    173 
     157        }
     158}
     159       
    174160/** Enable hardware breakpoint
    175161 *
    176162 * @param where Address of HW breakpoint
    177163 * @param flags Type of breakpoint (EXECUTE, WRITE)
    178  *
    179164 * @return Debug slot on success, -1 - no available HW breakpoint
    180  *
    181165 */
    182 int breakpoint_add(const void *where, const unsigned int flags, int curidx)
    183 {
     166int breakpoint_add(const void *where, const int flags, int curidx)
     167{
     168        ipl_t ipl;
     169        int i;
     170        bpinfo_t *cur;
     171
    184172        ASSERT(flags & (BKPOINT_INSTR | BKPOINT_WRITE | BKPOINT_READ_WRITE));
    185        
    186         irq_spinlock_lock(&bkpoint_lock, true);
     173
     174        ipl = interrupts_disable();
     175        spinlock_lock(&bkpoint_lock);
    187176       
    188177        if (curidx == -1) {
    189178                /* Find free space in slots */
    190                 unsigned int i;
    191                 for (i = 0; i < BKPOINTS_MAX; i++) {
     179                for (i = 0; i < BKPOINTS_MAX; i++)
    192180                        if (!breakpoints[i].address) {
    193181                                curidx = i;
    194182                                break;
    195183                        }
    196                 }
    197                
    198184                if (curidx == -1) {
    199185                        /* Too many breakpoints */
    200                         irq_spinlock_unlock(&bkpoint_lock, true);
     186                        spinlock_unlock(&bkpoint_lock);
     187                        interrupts_restore(ipl);
    201188                        return -1;
    202189                }
    203190        }
    204        
    205         bpinfo_t *cur = &breakpoints[curidx];
    206        
     191        cur = &breakpoints[curidx];
     192
    207193        cur->address = (uintptr_t) where;
    208194        cur->flags = flags;
    209195        cur->counter = 0;
    210        
     196
    211197        setup_dr(curidx);
    212        
    213         irq_spinlock_unlock(&bkpoint_lock, true);
    214        
     198
     199        spinlock_unlock(&bkpoint_lock);
     200        interrupts_restore(ipl);
     201
    215202        /* Send IPI */
     203#ifdef CONFIG_SMP
    216204//      ipi_broadcast(VECTOR_DEBUG_IPI);
    217        
     205#endif 
     206
    218207        return curidx;
    219208}
    220209
     210#ifdef __64_BITS__
     211        #define getip(x)  ((x)->rip)
     212#else
     213        #define getip(x)  ((x)->eip)
     214#endif
     215
    221216static void handle_exception(int slot, istate_t *istate)
    222217{
    223         ASSERT(slot >= 0);
    224218        ASSERT(breakpoints[slot].address);
    225        
     219
    226220        /* Handle zero checker */
    227         if (!(breakpoints[slot].flags & BKPOINT_INSTR)) {
     221        if (! (breakpoints[slot].flags & BKPOINT_INSTR)) {
    228222                if ((breakpoints[slot].flags & BKPOINT_CHECK_ZERO)) {
    229                         if (*((sysarg_t *) breakpoints[slot].address) != 0)
     223                        if (*((unative_t *) breakpoints[slot].address) != 0)
    230224                                return;
    231                        
    232                         printf("*** Found ZERO on address %p (slot %d) ***\n",
    233                             (void *) breakpoints[slot].address, slot);
     225                        printf("*** Found ZERO on address %lx (slot %d) ***\n",
     226                            breakpoints[slot].address, slot);
    234227                } else {
    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        
     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
    243236#ifdef CONFIG_KCONSOLE
    244237        atomic_set(&haltstate, 1);
     
    250243void breakpoint_del(int slot)
    251244{
    252         ASSERT(slot >= 0);
    253        
    254         irq_spinlock_lock(&bkpoint_lock, true);
    255        
    256         bpinfo_t *cur = &breakpoints[slot];
     245        bpinfo_t *cur;
     246        ipl_t ipl;
     247
     248        ipl = interrupts_disable();
     249        spinlock_lock(&bkpoint_lock);
     250
     251        cur = &breakpoints[slot];
    257252        if (!cur->address) {
    258                 irq_spinlock_unlock(&bkpoint_lock, true);
     253                spinlock_unlock(&bkpoint_lock);
     254                interrupts_restore(ipl);
    259255                return;
    260256        }
    261        
    262         cur->address = (uintptr_t) NULL;
    263        
     257
     258        cur->address = NULL;
     259
    264260        setup_dr(slot);
    265        
    266         irq_spinlock_unlock(&bkpoint_lock, true);
    267 //      ipi_broadcast(VECTOR_DEBUG_IPI);
    268 }
    269 
    270 static void debug_exception(unsigned int n __attribute__((unused)), istate_t *istate)
    271 {
     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
     271static void debug_exception(int n __attribute__((unused)), istate_t *istate)
     272{
     273        unative_t dr6;
     274        int i;
     275       
    272276        /* Set RF to restart the instruction  */
    273277#ifdef __64_BITS__
    274278        istate->rflags |= RFLAGS_RF;
    275 #endif
    276        
    277 #ifdef __32_BITS__
     279#else
    278280        istate->eflags |= EFLAGS_RF;
    279281#endif
    280        
    281         sysarg_t dr6 = read_dr6();
    282        
    283         unsigned int i;
    284         for (i = 0; i < BKPOINTS_MAX; i++) {
     282
     283        dr6 = read_dr6();
     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 debug_ipi(unsigned int n __attribute__((unused)),
     295static void
     296debug_ipi(int n __attribute__((unused)),
    296297    istate_t *istate __attribute__((unused)))
    297298{
    298         irq_spinlock_lock(&bkpoint_lock, false);
    299        
    300         unsigned int i;
     299        int i;
     300
     301        spinlock_lock(&bkpoint_lock);
    301302        for (i = 0; i < BKPOINTS_MAX; i++)
    302303                setup_dr(i);
    303        
    304         irq_spinlock_unlock(&bkpoint_lock, false);
    305 }
    306 #endif /* CONFIG_SMP */
    307 
    308 /** Initialize debugger
    309  *
    310  */
     304        spinlock_unlock(&bkpoint_lock);
     305}
     306#endif
     307
     308/** Initialize debugger */
    311309void debugger_init()
    312310{
    313         unsigned int i;
     311        int i;
     312
    314313        for (i = 0; i < BKPOINTS_MAX; i++)
    315                 breakpoints[i].address = (uintptr_t) NULL;
    316        
     314                breakpoints[i].address = NULL;
     315
    317316#ifdef CONFIG_KCONSOLE
    318317        cmd_initialize(&bkpts_info);
    319318        if (!cmd_register(&bkpts_info))
    320319                printf("Cannot register command %s\n", bkpts_info.name);
    321        
     320
    322321        cmd_initialize(&delbkpt_info);
    323322        if (!cmd_register(&delbkpt_info))
    324323                printf("Cannot register command %s\n", delbkpt_info.name);
    325        
     324
    326325        cmd_initialize(&addbkpt_info);
    327326        if (!cmd_register(&addbkpt_info))
    328327                printf("Cannot register command %s\n", addbkpt_info.name);
    329        
     328
    330329        cmd_initialize(&addwatchp_info);
    331330        if (!cmd_register(&addwatchp_info))
     
    333332#endif /* CONFIG_KCONSOLE */
    334333       
    335         exc_register(VECTOR_DEBUG, "debugger", true,
    336             debug_exception);
    337        
     334        exc_register(VECTOR_DEBUG, "debugger", debug_exception);
    338335#ifdef CONFIG_SMP
    339         exc_register(VECTOR_DEBUG_IPI, "debugger_smp", true,
    340             debug_ipi);
    341 #endif /* CONFIG_SMP */
     336        exc_register(VECTOR_DEBUG_IPI, "debugger_smp", debug_ipi);
     337#endif
    342338}
    343339
    344340#ifdef CONFIG_KCONSOLE
    345 /** Print table of active breakpoints
    346  *
    347  */
     341/** Print table of active breakpoints */
    348342int cmd_print_breakpoints(cmd_arg_t *argv __attribute__((unused)))
    349343{
     344        unsigned int i;
     345        char *symbol;
     346
    350347#ifdef __32_BITS__
    351         printf("[nr] [count] [address ] [in symbol\n");
    352 #endif
    353        
     348        printf("#  Count Address    In symbol\n");
     349        printf("-- ----- ---------- ---------\n");
     350#endif
     351
    354352#ifdef __64_BITS__
    355         printf("[nr] [count] [address         ] [in symbol\n");
    356 #endif
    357        
    358         unsigned int i;
    359         for (i = 0; i < BKPOINTS_MAX; i++) {
     353        printf("#  Count Address            In symbol\n");
     354        printf("-- ----- ------------------ ---------\n");
     355#endif
     356       
     357        for (i = 0; i < BKPOINTS_MAX; i++)
    360358                if (breakpoints[i].address) {
    361                         const char *symbol = symtab_fmt_name_lookup(
     359                        symbol = symtab_fmt_name_lookup(
    362360                            breakpoints[i].address);
    363                        
     361
    364362#ifdef __32_BITS__
    365                         printf("%-4u %7zu %p %s\n", i,
    366                             breakpoints[i].counter, (void *) breakpoints[i].address,
     363                        printf("%-2u %-5d %#10zx %s\n", i,
     364                            breakpoints[i].counter, breakpoints[i].address,
    367365                            symbol);
    368366#endif
    369                        
     367
    370368#ifdef __64_BITS__
    371                         printf("%-4u %7zu %p %s\n", i,
    372                             breakpoints[i].counter, (void *) breakpoints[i].address,
     369                        printf("%-2u %-5d %#18zx %s\n", i,
     370                            breakpoints[i].counter, breakpoints[i].address,
    373371                            symbol);
    374372#endif
    375                 }
    376         }
    377        
     373
     374                }
    378375        return 1;
    379376}
    380377
    381 /** Remove breakpoint from table
    382  *
    383  */
     378/** Remove breakpoint from table */
    384379int cmd_del_breakpoint(cmd_arg_t *argv)
    385380{
    386         sysarg_t bpno = argv->intval;
     381        unative_t bpno = argv->intval;
    387382        if (bpno > BKPOINTS_MAX) {
    388383                printf("Invalid breakpoint number.\n");
    389384                return 0;
    390385        }
    391        
    392386        breakpoint_del(argv->intval);
    393387        return 1;
    394388}
    395389
    396 /** Add new breakpoint to table
    397  *
    398  */
     390/** Add new breakpoint to table */
    399391static int cmd_add_breakpoint(cmd_arg_t *argv)
    400392{
    401         unsigned int flags;
    402         if (argv == &add_argv)
     393        int flags;
     394        int id;
     395
     396        if (argv == &add_argv) {
    403397                flags = BKPOINT_INSTR;
    404         else
     398        } else { /* addwatchp */
    405399                flags = BKPOINT_WRITE;
    406        
    407         printf("Adding breakpoint on address: %p\n",
    408             (void *) argv->intval);
    409        
    410         int id = breakpoint_add((void *) argv->intval, flags, -1);
     400        }
     401        printf("Adding breakpoint on address: %p\n", argv->intval);
     402        id = breakpoint_add((void *)argv->intval, flags, -1);
    411403        if (id < 0)
    412404                printf("Add breakpoint failed.\n");
Note: See TracChangeset for help on using the changeset viewer.