Ignore:
File:
1 edited

Legend:

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

    ra000878c r49ace23  
    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        unative_t dr7 = read_dr7();
     128        dr7 &= ~(0x2 << (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 &= ~(0x3 << (16 + 4 * curidx));
     150                dr7 &= ~(0x3 << (18 + 4 * curidx));
    137151               
     152                if (!(flags & BKPOINT_INSTR)) {
    138153#ifdef __32_BITS__
    139154                        dr7 |= ((unative_t) 0x3) << (18 + 4 * curidx);
    140155#endif
    141 
     156                       
    142157#ifdef __64_BITS__
    143158                        dr7 |= ((unative_t) 0x2) << (18 + 4 * curidx);
     
    149164                                dr7 |= ((unative_t) 0x3) << (16 + 4 * curidx);
    150165                }
    151 
     166               
    152167                /* Enable global breakpoint */
    153168                dr7 |= 0x2 << (curidx * 2);
    154 
     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 */
    203216//      ipi_broadcast(VECTOR_DEBUG_IPI);
    204 
     217       
    205218        return curidx;
    206219}
    207220
    208 #ifdef __64_BITS__
    209         #define getip(x)  ((x)->rip)
    210 #else
    211         #define getip(x)  ((x)->eip)
    212 #endif
    213 
    214221static void handle_exception(int slot, istate_t *istate)
    215222{
     223        ASSERT(slot >= 0);
    216224        ASSERT(breakpoints[slot].address);
    217 
     225       
    218226        /* Handle zero checker */
    219         if (! (breakpoints[slot].flags & BKPOINT_INSTR)) {
     227        if (!(breakpoints[slot].flags & BKPOINT_INSTR)) {
    220228                if ((breakpoints[slot].flags & BKPOINT_CHECK_ZERO)) {
    221229                        if (*((unative_t *) breakpoints[slot].address) != 0)
    222230                                return;
    223                         printf("*** Found ZERO on address %lx (slot %d) ***\n",
     231                       
     232                        printf("*** Found ZERO on address %" PRIp " (slot %d) ***\n",
    224233                            breakpoints[slot].address, slot);
    225234                } else {
    226                         printf("Data watchpoint - new data: %lx\n",
     235                        printf("Data watchpoint - new data: %" PRIp "\n",
    227236                            *((unative_t *) breakpoints[slot].address));
    228237                }
    229238        }
    230 
    231         printf("Reached breakpoint %d:%lx (%s)\n", slot, getip(istate),
     239       
     240        printf("Reached breakpoint %d:%" PRIp " (%s)\n", slot, getip(istate),
    232241            symtab_fmt_name_lookup(getip(istate)));
    233 
     242       
    234243#ifdef CONFIG_KCONSOLE
    235244        atomic_set(&haltstate, 1);
     
    241250void breakpoint_del(int slot)
    242251{
    243         bpinfo_t *cur;
    244         ipl_t ipl;
    245 
    246         ipl = interrupts_disable();
    247         spinlock_lock(&bkpoint_lock);
    248 
    249         cur = &breakpoints[slot];
     252        ASSERT(slot >= 0);
     253       
     254        irq_spinlock_lock(&bkpoint_lock, true);
     255       
     256        bpinfo_t *cur = &breakpoints[slot];
    250257        if (!cur->address) {
    251                 spinlock_unlock(&bkpoint_lock);
    252                 interrupts_restore(ipl);
     258                irq_spinlock_unlock(&bkpoint_lock, true);
    253259                return;
    254260        }
    255 
     261       
    256262        cur->address = NULL;
    257 
     263       
    258264        setup_dr(slot);
    259 
    260         spinlock_unlock(&bkpoint_lock);
    261         interrupts_restore(ipl);
     265       
     266        irq_spinlock_unlock(&bkpoint_lock, true);
    262267//      ipi_broadcast(VECTOR_DEBUG_IPI);
    263268}
    264269
    265 
    266 
    267 static void debug_exception(int n __attribute__((unused)), istate_t *istate)
    268 {
    269         unative_t dr6;
    270         int i;
    271        
     270static void debug_exception(unsigned int n __attribute__((unused)), istate_t *istate)
     271{
    272272        /* Set RF to restart the instruction  */
    273273#ifdef __64_BITS__
    274274        istate->rflags |= RFLAGS_RF;
    275 #else
     275#endif
     276       
     277#ifdef __32_BITS__
    276278        istate->eflags |= EFLAGS_RF;
    277279#endif
    278 
    279         dr6 = read_dr6();
    280         for (i=0; i < BKPOINTS_MAX; i++) {
     280       
     281        unative_t dr6 = read_dr6();
     282       
     283        unsigned int i;
     284        for (i = 0; i < BKPOINTS_MAX; i++) {
    281285                if (dr6 & (1 << i)) {
    282286                        dr6 &= ~ (1 << i);
     
    289293
    290294#ifdef CONFIG_SMP
    291 static void
    292 debug_ipi(int n __attribute__((unused)),
     295static void debug_ipi(unsigned int n __attribute__((unused)),
    293296    istate_t *istate __attribute__((unused)))
    294297{
    295         int i;
    296 
    297         spinlock_lock(&bkpoint_lock);
     298        irq_spinlock_lock(&bkpoint_lock, false);
     299       
     300        unsigned int i;
    298301        for (i = 0; i < BKPOINTS_MAX; i++)
    299302                setup_dr(i);
    300         spinlock_unlock(&bkpoint_lock);
    301 }
    302 #endif
    303 
    304 /** Initialize debugger */
     303       
     304        irq_spinlock_unlock(&bkpoint_lock, false);
     305}
     306#endif /* CONFIG_SMP */
     307
     308/** Initialize debugger
     309 *
     310 */
    305311void debugger_init()
    306312{
    307         int i;
    308 
     313        unsigned int i;
    309314        for (i = 0; i < BKPOINTS_MAX; i++)
    310315                breakpoints[i].address = NULL;
    311 
     316       
    312317#ifdef CONFIG_KCONSOLE
    313318        cmd_initialize(&bkpts_info);
    314319        if (!cmd_register(&bkpts_info))
    315320                printf("Cannot register command %s\n", bkpts_info.name);
    316 
     321       
    317322        cmd_initialize(&delbkpt_info);
    318323        if (!cmd_register(&delbkpt_info))
    319324                printf("Cannot register command %s\n", delbkpt_info.name);
    320 
     325       
    321326        cmd_initialize(&addbkpt_info);
    322327        if (!cmd_register(&addbkpt_info))
    323328                printf("Cannot register command %s\n", addbkpt_info.name);
    324 
     329       
    325330        cmd_initialize(&addwatchp_info);
    326331        if (!cmd_register(&addwatchp_info))
     
    328333#endif /* CONFIG_KCONSOLE */
    329334       
    330         exc_register(VECTOR_DEBUG, "debugger", debug_exception);
     335        exc_register(VECTOR_DEBUG, "debugger", true,
     336            debug_exception);
     337       
    331338#ifdef CONFIG_SMP
    332         exc_register(VECTOR_DEBUG_IPI, "debugger_smp", debug_ipi);
    333 #endif
     339        exc_register(VECTOR_DEBUG_IPI, "debugger_smp", true,
     340            debug_ipi);
     341#endif /* CONFIG_SMP */
    334342}
    335343
    336344#ifdef CONFIG_KCONSOLE
    337 /** Print table of active breakpoints */
     345/** Print table of active breakpoints
     346 *
     347 */
    338348int cmd_print_breakpoints(cmd_arg_t *argv __attribute__((unused)))
    339349{
     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       
    340358        unsigned int i;
    341 
    342 #ifdef __32_BITS__
    343         printf("#  Count Address    In symbol\n");
    344         printf("-- ----- ---------- ---------\n");
    345 #endif
    346 
    347 #ifdef __64_BITS__
    348         printf("#  Count Address            In symbol\n");
    349         printf("-- ----- ------------------ ---------\n");
    350 #endif
    351        
    352         for (i = 0; i < BKPOINTS_MAX; i++)
     359        for (i = 0; i < BKPOINTS_MAX; i++) {
    353360                if (breakpoints[i].address) {
    354361                        const char *symbol = symtab_fmt_name_lookup(
    355362                            breakpoints[i].address);
    356 
     363                       
    357364#ifdef __32_BITS__
    358                         printf("%-2u %-5d %#10zx %s\n", i,
     365                        printf("%-4u %7" PRIs " %p %s\n", i,
    359366                            breakpoints[i].counter, breakpoints[i].address,
    360367                            symbol);
    361368#endif
    362 
     369                       
    363370#ifdef __64_BITS__
    364                         printf("%-2u %-5d %#18zx %s\n", i,
     371                        printf("%-4u %7" PRIs " %p %s\n", i,
    365372                            breakpoints[i].counter, breakpoints[i].address,
    366373                            symbol);
    367374#endif
    368 
    369                 }
     375                }
     376        }
     377       
    370378        return 1;
    371379}
    372380
    373 /** Remove breakpoint from table */
     381/** Remove breakpoint from table
     382 *
     383 */
    374384int cmd_del_breakpoint(cmd_arg_t *argv)
    375385{
     
    379389                return 0;
    380390        }
     391       
    381392        breakpoint_del(argv->intval);
    382393        return 1;
    383394}
    384395
    385 /** Add new breakpoint to table */
     396/** Add new breakpoint to table
     397 *
     398 */
    386399static int cmd_add_breakpoint(cmd_arg_t *argv)
    387400{
    388         int flags;
    389         int id;
    390 
    391         if (argv == &add_argv) {
     401        unsigned int flags;
     402        if (argv == &add_argv)
    392403                flags = BKPOINT_INSTR;
    393         } else { /* addwatchp */
     404        else
    394405                flags = BKPOINT_WRITE;
    395         }
     406       
    396407        printf("Adding breakpoint on address: %p\n", argv->intval);
    397         id = breakpoint_add((void *)argv->intval, flags, -1);
     408       
     409        int id = breakpoint_add((void *)argv->intval, flags, -1);
    398410        if (id < 0)
    399411                printf("Add breakpoint failed.\n");
Note: See TracChangeset for help on using the changeset viewer.