linux/arch/arm/kernel/kgdb.c
<<
>>
Prefs
   1/*
   2 * arch/arm/kernel/kgdb.c
   3 *
   4 * ARM KGDB support
   5 *
   6 * Copyright (c) 2002-2004 MontaVista Software, Inc
   7 * Copyright (c) 2008 Wind River Systems, Inc.
   8 *
   9 * Authors:  George Davis <davis_g@mvista.com>
  10 *           Deepak Saxena <dsaxena@plexity.net>
  11 */
  12#include <linux/kgdb.h>
  13#include <asm/traps.h>
  14
  15/* Make a local copy of the registers passed into the handler (bletch) */
  16void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs)
  17{
  18        int regno;
  19
  20        /* Initialize all to zero. */
  21        for (regno = 0; regno < GDB_MAX_REGS; regno++)
  22                gdb_regs[regno] = 0;
  23
  24        gdb_regs[_R0]           = kernel_regs->ARM_r0;
  25        gdb_regs[_R1]           = kernel_regs->ARM_r1;
  26        gdb_regs[_R2]           = kernel_regs->ARM_r2;
  27        gdb_regs[_R3]           = kernel_regs->ARM_r3;
  28        gdb_regs[_R4]           = kernel_regs->ARM_r4;
  29        gdb_regs[_R5]           = kernel_regs->ARM_r5;
  30        gdb_regs[_R6]           = kernel_regs->ARM_r6;
  31        gdb_regs[_R7]           = kernel_regs->ARM_r7;
  32        gdb_regs[_R8]           = kernel_regs->ARM_r8;
  33        gdb_regs[_R9]           = kernel_regs->ARM_r9;
  34        gdb_regs[_R10]          = kernel_regs->ARM_r10;
  35        gdb_regs[_FP]           = kernel_regs->ARM_fp;
  36        gdb_regs[_IP]           = kernel_regs->ARM_ip;
  37        gdb_regs[_SPT]          = kernel_regs->ARM_sp;
  38        gdb_regs[_LR]           = kernel_regs->ARM_lr;
  39        gdb_regs[_PC]           = kernel_regs->ARM_pc;
  40        gdb_regs[_CPSR]         = kernel_regs->ARM_cpsr;
  41}
  42
  43/* Copy local gdb registers back to kgdb regs, for later copy to kernel */
  44void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs)
  45{
  46        kernel_regs->ARM_r0     = gdb_regs[_R0];
  47        kernel_regs->ARM_r1     = gdb_regs[_R1];
  48        kernel_regs->ARM_r2     = gdb_regs[_R2];
  49        kernel_regs->ARM_r3     = gdb_regs[_R3];
  50        kernel_regs->ARM_r4     = gdb_regs[_R4];
  51        kernel_regs->ARM_r5     = gdb_regs[_R5];
  52        kernel_regs->ARM_r6     = gdb_regs[_R6];
  53        kernel_regs->ARM_r7     = gdb_regs[_R7];
  54        kernel_regs->ARM_r8     = gdb_regs[_R8];
  55        kernel_regs->ARM_r9     = gdb_regs[_R9];
  56        kernel_regs->ARM_r10    = gdb_regs[_R10];
  57        kernel_regs->ARM_fp     = gdb_regs[_FP];
  58        kernel_regs->ARM_ip     = gdb_regs[_IP];
  59        kernel_regs->ARM_sp     = gdb_regs[_SPT];
  60        kernel_regs->ARM_lr     = gdb_regs[_LR];
  61        kernel_regs->ARM_pc     = gdb_regs[_PC];
  62        kernel_regs->ARM_cpsr   = gdb_regs[_CPSR];
  63}
  64
  65void
  66sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
  67{
  68        struct pt_regs *thread_regs;
  69        int regno;
  70
  71        /* Just making sure... */
  72        if (task == NULL)
  73                return;
  74
  75        /* Initialize to zero */
  76        for (regno = 0; regno < GDB_MAX_REGS; regno++)
  77                gdb_regs[regno] = 0;
  78
  79        /* Otherwise, we have only some registers from switch_to() */
  80        thread_regs             = task_pt_regs(task);
  81        gdb_regs[_R0]           = thread_regs->ARM_r0;
  82        gdb_regs[_R1]           = thread_regs->ARM_r1;
  83        gdb_regs[_R2]           = thread_regs->ARM_r2;
  84        gdb_regs[_R3]           = thread_regs->ARM_r3;
  85        gdb_regs[_R4]           = thread_regs->ARM_r4;
  86        gdb_regs[_R5]           = thread_regs->ARM_r5;
  87        gdb_regs[_R6]           = thread_regs->ARM_r6;
  88        gdb_regs[_R7]           = thread_regs->ARM_r7;
  89        gdb_regs[_R8]           = thread_regs->ARM_r8;
  90        gdb_regs[_R9]           = thread_regs->ARM_r9;
  91        gdb_regs[_R10]          = thread_regs->ARM_r10;
  92        gdb_regs[_FP]           = thread_regs->ARM_fp;
  93        gdb_regs[_IP]           = thread_regs->ARM_ip;
  94        gdb_regs[_SPT]          = thread_regs->ARM_sp;
  95        gdb_regs[_LR]           = thread_regs->ARM_lr;
  96        gdb_regs[_PC]           = thread_regs->ARM_pc;
  97        gdb_regs[_CPSR]         = thread_regs->ARM_cpsr;
  98}
  99
 100static int compiled_break;
 101
 102int kgdb_arch_handle_exception(int exception_vector, int signo,
 103                               int err_code, char *remcom_in_buffer,
 104                               char *remcom_out_buffer,
 105                               struct pt_regs *linux_regs)
 106{
 107        unsigned long addr;
 108        char *ptr;
 109
 110        switch (remcom_in_buffer[0]) {
 111        case 'D':
 112        case 'k':
 113        case 'c':
 114                /*
 115                 * Try to read optional parameter, pc unchanged if no parm.
 116                 * If this was a compiled breakpoint, we need to move
 117                 * to the next instruction or we will just breakpoint
 118                 * over and over again.
 119                 */
 120                ptr = &remcom_in_buffer[1];
 121                if (kgdb_hex2long(&ptr, &addr))
 122                        linux_regs->ARM_pc = addr;
 123                else if (compiled_break == 1)
 124                        linux_regs->ARM_pc += 4;
 125
 126                compiled_break = 0;
 127
 128                return 0;
 129        }
 130
 131        return -1;
 132}
 133
 134static int kgdb_brk_fn(struct pt_regs *regs, unsigned int instr)
 135{
 136        kgdb_handle_exception(1, SIGTRAP, 0, regs);
 137
 138        return 0;
 139}
 140
 141static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int instr)
 142{
 143        compiled_break = 1;
 144        kgdb_handle_exception(1, SIGTRAP, 0, regs);
 145
 146        return 0;
 147}
 148
 149static struct undef_hook kgdb_brkpt_hook = {
 150        .instr_mask             = 0xffffffff,
 151        .instr_val              = KGDB_BREAKINST,
 152        .fn                     = kgdb_brk_fn
 153};
 154
 155static struct undef_hook kgdb_compiled_brkpt_hook = {
 156        .instr_mask             = 0xffffffff,
 157        .instr_val              = KGDB_COMPILED_BREAK,
 158        .fn                     = kgdb_compiled_brk_fn
 159};
 160
 161/**
 162 *      kgdb_arch_init - Perform any architecture specific initalization.
 163 *
 164 *      This function will handle the initalization of any architecture
 165 *      specific callbacks.
 166 */
 167int kgdb_arch_init(void)
 168{
 169        register_undef_hook(&kgdb_brkpt_hook);
 170        register_undef_hook(&kgdb_compiled_brkpt_hook);
 171
 172        return 0;
 173}
 174
 175/**
 176 *      kgdb_arch_exit - Perform any architecture specific uninitalization.
 177 *
 178 *      This function will handle the uninitalization of any architecture
 179 *      specific callbacks, for dynamic registration and unregistration.
 180 */
 181void kgdb_arch_exit(void)
 182{
 183        unregister_undef_hook(&kgdb_brkpt_hook);
 184        unregister_undef_hook(&kgdb_compiled_brkpt_hook);
 185}
 186
 187/*
 188 * Register our undef instruction hooks with ARM undef core.
 189 * We regsiter a hook specifically looking for the KGB break inst
 190 * and we handle the normal undef case within the do_undefinstr
 191 * handler.
 192 */
 193struct kgdb_arch arch_kgdb_ops = {
 194#ifndef __ARMEB__
 195        .gdb_bpt_instr          = {0xfe, 0xde, 0xff, 0xe7}
 196#else /* ! __ARMEB__ */
 197        .gdb_bpt_instr          = {0xe7, 0xff, 0xde, 0xfe}
 198#endif
 199};
 200