Ignore:
File:
1 edited

Legend:

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

    r49ace23 ra000878c  
    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         unative_t dr7 = read_dr7();
    128         dr7 &= ~(0x2 << (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 &= ~(0x3 << (16 + 4 * curidx));
    150                 dr7 &= ~(0x3 << (18 + 4 * curidx));
    151                
    152                 if (!(flags & BKPOINT_INSTR)) {
    153138#ifdef __32_BITS__
    154139                        dr7 |= ((unative_t) 0x3) << (18 + 4 * curidx);
    155140#endif
    156                        
     141
    157142#ifdef __64_BITS__
    158143                        dr7 |= ((unative_t) 0x2) << (18 + 4 * curidx);
     
    164149                                dr7 |= ((unative_t) 0x3) << (16 + 4 * curidx);
    165150                }
    166                
     151
    167152                /* Enable global breakpoint */
    168153                dr7 |= 0x2 << (curidx * 2);
     154
     155                write_dr7(dr7);
    169156               
    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 */
    216203//      ipi_broadcast(VECTOR_DEBUG_IPI);
    217        
     204
    218205        return curidx;
    219206}
    220207
     208#ifdef __64_BITS__
     209        #define getip(x)  ((x)->rip)
     210#else
     211        #define getip(x)  ((x)->eip)
     212#endif
     213
    221214static void handle_exception(int slot, istate_t *istate)
    222215{
    223         ASSERT(slot >= 0);
    224216        ASSERT(breakpoints[slot].address);
    225        
     217
    226218        /* Handle zero checker */
    227         if (!(breakpoints[slot].flags & BKPOINT_INSTR)) {
     219        if (! (breakpoints[slot].flags & BKPOINT_INSTR)) {
    228220                if ((breakpoints[slot].flags & BKPOINT_CHECK_ZERO)) {
    229221                        if (*((unative_t *) breakpoints[slot].address) != 0)
    230222                                return;
    231                        
    232                         printf("*** Found ZERO on address %" PRIp " (slot %d) ***\n",
     223                        printf("*** Found ZERO on address %lx (slot %d) ***\n",
    233224                            breakpoints[slot].address, slot);
    234225                } else {
    235                         printf("Data watchpoint - new data: %" PRIp "\n",
     226                        printf("Data watchpoint - new data: %lx\n",
    236227                            *((unative_t *) breakpoints[slot].address));
    237228                }
    238229        }
    239        
    240         printf("Reached breakpoint %d:%" PRIp " (%s)\n", slot, getip(istate),
     230
     231        printf("Reached breakpoint %d:%lx (%s)\n", slot, getip(istate),
    241232            symtab_fmt_name_lookup(getip(istate)));
    242        
     233
    243234#ifdef CONFIG_KCONSOLE
    244235        atomic_set(&haltstate, 1);
     
    250241void breakpoint_del(int slot)
    251242{
    252         ASSERT(slot >= 0);
    253        
    254         irq_spinlock_lock(&bkpoint_lock, true);
    255        
    256         bpinfo_t *cur = &breakpoints[slot];
     243        bpinfo_t *cur;
     244        ipl_t ipl;
     245
     246        ipl = interrupts_disable();
     247        spinlock_lock(&bkpoint_lock);
     248
     249        cur = &breakpoints[slot];
    257250        if (!cur->address) {
    258                 irq_spinlock_unlock(&bkpoint_lock, true);
     251                spinlock_unlock(&bkpoint_lock);
     252                interrupts_restore(ipl);
    259253                return;
    260254        }
    261        
     255
    262256        cur->address = NULL;
    263        
     257
    264258        setup_dr(slot);
    265        
    266         irq_spinlock_unlock(&bkpoint_lock, true);
     259
     260        spinlock_unlock(&bkpoint_lock);
     261        interrupts_restore(ipl);
    267262//      ipi_broadcast(VECTOR_DEBUG_IPI);
    268263}
    269264
    270 static void debug_exception(unsigned int n __attribute__((unused)), istate_t *istate)
    271 {
     265
     266
     267static void debug_exception(int n __attribute__((unused)), istate_t *istate)
     268{
     269        unative_t dr6;
     270        int i;
     271       
    272272        /* Set RF to restart the instruction  */
    273273#ifdef __64_BITS__
    274274        istate->rflags |= RFLAGS_RF;
    275 #endif
    276        
    277 #ifdef __32_BITS__
     275#else
    278276        istate->eflags |= EFLAGS_RF;
    279277#endif
    280        
    281         unative_t dr6 = read_dr6();
    282        
    283         unsigned int i;
    284         for (i = 0; i < BKPOINTS_MAX; i++) {
     278
     279        dr6 = read_dr6();
     280        for (i=0; i < BKPOINTS_MAX; i++) {
    285281                if (dr6 & (1 << i)) {
    286282                        dr6 &= ~ (1 << i);
     
    293289
    294290#ifdef CONFIG_SMP
    295 static void debug_ipi(unsigned int n __attribute__((unused)),
     291static void
     292debug_ipi(int n __attribute__((unused)),
    296293    istate_t *istate __attribute__((unused)))
    297294{
    298         irq_spinlock_lock(&bkpoint_lock, false);
    299        
    300         unsigned int i;
     295        int i;
     296
     297        spinlock_lock(&bkpoint_lock);
    301298        for (i = 0; i < BKPOINTS_MAX; i++)
    302299                setup_dr(i);
    303        
    304         irq_spinlock_unlock(&bkpoint_lock, false);
    305 }
    306 #endif /* CONFIG_SMP */
    307 
    308 /** Initialize debugger
    309  *
    310  */
     300        spinlock_unlock(&bkpoint_lock);
     301}
     302#endif
     303
     304/** Initialize debugger */
    311305void debugger_init()
    312306{
    313         unsigned int i;
     307        int i;
     308
    314309        for (i = 0; i < BKPOINTS_MAX; i++)
    315310                breakpoints[i].address = NULL;
    316        
     311
    317312#ifdef CONFIG_KCONSOLE
    318313        cmd_initialize(&bkpts_info);
    319314        if (!cmd_register(&bkpts_info))
    320315                printf("Cannot register command %s\n", bkpts_info.name);
    321        
     316
    322317        cmd_initialize(&delbkpt_info);
    323318        if (!cmd_register(&delbkpt_info))
    324319                printf("Cannot register command %s\n", delbkpt_info.name);
    325        
     320
    326321        cmd_initialize(&addbkpt_info);
    327322        if (!cmd_register(&addbkpt_info))
    328323                printf("Cannot register command %s\n", addbkpt_info.name);
    329        
     324
    330325        cmd_initialize(&addwatchp_info);
    331326        if (!cmd_register(&addwatchp_info))
     
    333328#endif /* CONFIG_KCONSOLE */
    334329       
    335         exc_register(VECTOR_DEBUG, "debugger", true,
    336             debug_exception);
    337        
     330        exc_register(VECTOR_DEBUG, "debugger", debug_exception);
    338331#ifdef CONFIG_SMP
    339         exc_register(VECTOR_DEBUG_IPI, "debugger_smp", true,
    340             debug_ipi);
    341 #endif /* CONFIG_SMP */
     332        exc_register(VECTOR_DEBUG_IPI, "debugger_smp", debug_ipi);
     333#endif
    342334}
    343335
    344336#ifdef CONFIG_KCONSOLE
    345 /** Print table of active breakpoints
    346  *
    347  */
     337/** Print table of active breakpoints */
    348338int cmd_print_breakpoints(cmd_arg_t *argv __attribute__((unused)))
    349339{
     340        unsigned int i;
     341
    350342#ifdef __32_BITS__
    351         printf("[nr] [count] [address ] [in symbol\n");
    352 #endif
    353        
     343        printf("#  Count Address    In symbol\n");
     344        printf("-- ----- ---------- ---------\n");
     345#endif
     346
    354347#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++) {
     348        printf("#  Count Address            In symbol\n");
     349        printf("-- ----- ------------------ ---------\n");
     350#endif
     351       
     352        for (i = 0; i < BKPOINTS_MAX; i++)
    360353                if (breakpoints[i].address) {
    361354                        const char *symbol = symtab_fmt_name_lookup(
    362355                            breakpoints[i].address);
    363                        
     356
    364357#ifdef __32_BITS__
    365                         printf("%-4u %7" PRIs " %p %s\n", i,
     358                        printf("%-2u %-5d %#10zx %s\n", i,
    366359                            breakpoints[i].counter, breakpoints[i].address,
    367360                            symbol);
    368361#endif
    369                        
     362
    370363#ifdef __64_BITS__
    371                         printf("%-4u %7" PRIs " %p %s\n", i,
     364                        printf("%-2u %-5d %#18zx %s\n", i,
    372365                            breakpoints[i].counter, breakpoints[i].address,
    373366                            symbol);
    374367#endif
    375                 }
    376         }
    377        
     368
     369                }
    378370        return 1;
    379371}
    380372
    381 /** Remove breakpoint from table
    382  *
    383  */
     373/** Remove breakpoint from table */
    384374int cmd_del_breakpoint(cmd_arg_t *argv)
    385375{
     
    389379                return 0;
    390380        }
    391        
    392381        breakpoint_del(argv->intval);
    393382        return 1;
    394383}
    395384
    396 /** Add new breakpoint to table
    397  *
    398  */
     385/** Add new breakpoint to table */
    399386static int cmd_add_breakpoint(cmd_arg_t *argv)
    400387{
    401         unsigned int flags;
    402         if (argv == &add_argv)
     388        int flags;
     389        int id;
     390
     391        if (argv == &add_argv) {
    403392                flags = BKPOINT_INSTR;
    404         else
     393        } else { /* addwatchp */
    405394                flags = BKPOINT_WRITE;
    406        
     395        }
    407396        printf("Adding breakpoint on address: %p\n", argv->intval);
    408        
    409         int id = breakpoint_add((void *)argv->intval, flags, -1);
     397        id = breakpoint_add((void *)argv->intval, flags, -1);
    410398        if (id < 0)
    411399                printf("Add breakpoint failed.\n");
Note: See TracChangeset for help on using the changeset viewer.