root/arch/mips/kernel/kgdb.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dbg_set_reg
  2. dbg_get_reg
  3. arch_kgdb_breakpoint
  4. kgdb_call_nmi_hook
  5. compute_signal
  6. sleeping_thread_to_gdb_regs
  7. kgdb_arch_set_pc
  8. kgdb_mips_notify
  9. kgdb_ll_trap
  10. kgdb_arch_handle_exception
  11. kgdb_arch_init
  12. kgdb_arch_exit

   1 /*
   2  *  Originally written by Glenn Engel, Lake Stevens Instrument Division
   3  *
   4  *  Contributed by HP Systems
   5  *
   6  *  Modified for Linux/MIPS (and MIPS in general) by Andreas Busse
   7  *  Send complaints, suggestions etc. to <andy@waldorf-gmbh.de>
   8  *
   9  *  Copyright (C) 1995 Andreas Busse
  10  *
  11  *  Copyright (C) 2003 MontaVista Software Inc.
  12  *  Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
  13  *
  14  *  Copyright (C) 2004-2005 MontaVista Software Inc.
  15  *  Author: Manish Lachwani, mlachwani@mvista.com or manish@koffee-break.com
  16  *
  17  *  Copyright (C) 2007-2008 Wind River Systems, Inc.
  18  *  Author/Maintainer: Jason Wessel, jason.wessel@windriver.com
  19  *
  20  *  This file is licensed under the terms of the GNU General Public License
  21  *  version 2. This program is licensed "as is" without any warranty of any
  22  *  kind, whether express or implied.
  23  */
  24 
  25 #include <linux/ptrace.h>               /* for linux pt_regs struct */
  26 #include <linux/kgdb.h>
  27 #include <linux/kdebug.h>
  28 #include <linux/sched.h>
  29 #include <linux/smp.h>
  30 #include <asm/inst.h>
  31 #include <asm/fpu.h>
  32 #include <asm/cacheflush.h>
  33 #include <asm/processor.h>
  34 #include <asm/sigcontext.h>
  35 #include <linux/uaccess.h>
  36 #include <asm/irq_regs.h>
  37 
  38 static struct hard_trap_info {
  39         unsigned char tt;       /* Trap type code for MIPS R3xxx and R4xxx */
  40         unsigned char signo;    /* Signal that we map this trap into */
  41 } hard_trap_info[] = {
  42         { 6, SIGBUS },          /* instruction bus error */
  43         { 7, SIGBUS },          /* data bus error */
  44         { 9, SIGTRAP },         /* break */
  45 /*      { 11, SIGILL }, */      /* CPU unusable */
  46         { 12, SIGFPE },         /* overflow */
  47         { 13, SIGTRAP },        /* trap */
  48         { 14, SIGSEGV },        /* virtual instruction cache coherency */
  49         { 15, SIGFPE },         /* floating point exception */
  50         { 23, SIGSEGV },        /* watch */
  51         { 31, SIGSEGV },        /* virtual data cache coherency */
  52         { 0, 0}                 /* Must be last */
  53 };
  54 
  55 struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] =
  56 {
  57         { "zero", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[0]) },
  58         { "at", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[1]) },
  59         { "v0", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[2]) },
  60         { "v1", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[3]) },
  61         { "a0", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[4]) },
  62         { "a1", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[5]) },
  63         { "a2", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[6]) },
  64         { "a3", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[7]) },
  65         { "t0", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[8]) },
  66         { "t1", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[9]) },
  67         { "t2", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[10]) },
  68         { "t3", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[11]) },
  69         { "t4", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[12]) },
  70         { "t5", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[13]) },
  71         { "t6", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[14]) },
  72         { "t7", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[15]) },
  73         { "s0", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[16]) },
  74         { "s1", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[17]) },
  75         { "s2", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[18]) },
  76         { "s3", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[19]) },
  77         { "s4", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[20]) },
  78         { "s5", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[21]) },
  79         { "s6", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[22]) },
  80         { "s7", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[23]) },
  81         { "t8", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[24]) },
  82         { "t9", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[25]) },
  83         { "k0", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[26]) },
  84         { "k1", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[27]) },
  85         { "gp", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[28]) },
  86         { "sp", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[29]) },
  87         { "s8", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[30]) },
  88         { "ra", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[31]) },
  89         { "sr", GDB_SIZEOF_REG, offsetof(struct pt_regs, cp0_status) },
  90         { "lo", GDB_SIZEOF_REG, offsetof(struct pt_regs, lo) },
  91         { "hi", GDB_SIZEOF_REG, offsetof(struct pt_regs, hi) },
  92         { "bad", GDB_SIZEOF_REG, offsetof(struct pt_regs, cp0_badvaddr) },
  93         { "cause", GDB_SIZEOF_REG, offsetof(struct pt_regs, cp0_cause) },
  94         { "pc", GDB_SIZEOF_REG, offsetof(struct pt_regs, cp0_epc) },
  95         { "f0", GDB_SIZEOF_REG, 0 },
  96         { "f1", GDB_SIZEOF_REG, 1 },
  97         { "f2", GDB_SIZEOF_REG, 2 },
  98         { "f3", GDB_SIZEOF_REG, 3 },
  99         { "f4", GDB_SIZEOF_REG, 4 },
 100         { "f5", GDB_SIZEOF_REG, 5 },
 101         { "f6", GDB_SIZEOF_REG, 6 },
 102         { "f7", GDB_SIZEOF_REG, 7 },
 103         { "f8", GDB_SIZEOF_REG, 8 },
 104         { "f9", GDB_SIZEOF_REG, 9 },
 105         { "f10", GDB_SIZEOF_REG, 10 },
 106         { "f11", GDB_SIZEOF_REG, 11 },
 107         { "f12", GDB_SIZEOF_REG, 12 },
 108         { "f13", GDB_SIZEOF_REG, 13 },
 109         { "f14", GDB_SIZEOF_REG, 14 },
 110         { "f15", GDB_SIZEOF_REG, 15 },
 111         { "f16", GDB_SIZEOF_REG, 16 },
 112         { "f17", GDB_SIZEOF_REG, 17 },
 113         { "f18", GDB_SIZEOF_REG, 18 },
 114         { "f19", GDB_SIZEOF_REG, 19 },
 115         { "f20", GDB_SIZEOF_REG, 20 },
 116         { "f21", GDB_SIZEOF_REG, 21 },
 117         { "f22", GDB_SIZEOF_REG, 22 },
 118         { "f23", GDB_SIZEOF_REG, 23 },
 119         { "f24", GDB_SIZEOF_REG, 24 },
 120         { "f25", GDB_SIZEOF_REG, 25 },
 121         { "f26", GDB_SIZEOF_REG, 26 },
 122         { "f27", GDB_SIZEOF_REG, 27 },
 123         { "f28", GDB_SIZEOF_REG, 28 },
 124         { "f29", GDB_SIZEOF_REG, 29 },
 125         { "f30", GDB_SIZEOF_REG, 30 },
 126         { "f31", GDB_SIZEOF_REG, 31 },
 127         { "fsr", GDB_SIZEOF_REG, 0 },
 128         { "fir", GDB_SIZEOF_REG, 0 },
 129 };
 130 
 131 int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
 132 {
 133         int fp_reg;
 134 
 135         if (regno < 0 || regno >= DBG_MAX_REG_NUM)
 136                 return -EINVAL;
 137 
 138         if (dbg_reg_def[regno].offset != -1 && regno < 38) {
 139                 memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
 140                        dbg_reg_def[regno].size);
 141         } else if (current && dbg_reg_def[regno].offset != -1 && regno < 72) {
 142                 /* FP registers 38 -> 69 */
 143                 if (!(regs->cp0_status & ST0_CU1))
 144                         return 0;
 145                 if (regno == 70) {
 146                         /* Process the fcr31/fsr (register 70) */
 147                         memcpy((void *)&current->thread.fpu.fcr31, mem,
 148                                dbg_reg_def[regno].size);
 149                         goto out_save;
 150                 } else if (regno == 71) {
 151                         /* Ignore the fir (register 71) */
 152                         goto out_save;
 153                 }
 154                 fp_reg = dbg_reg_def[regno].offset;
 155                 memcpy((void *)&current->thread.fpu.fpr[fp_reg], mem,
 156                        dbg_reg_def[regno].size);
 157 out_save:
 158                 restore_fp(current);
 159         }
 160 
 161         return 0;
 162 }
 163 
 164 char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
 165 {
 166         int fp_reg;
 167 
 168         if (regno >= DBG_MAX_REG_NUM || regno < 0)
 169                 return NULL;
 170 
 171         if (dbg_reg_def[regno].offset != -1 && regno < 38) {
 172                 /* First 38 registers */
 173                 memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
 174                        dbg_reg_def[regno].size);
 175         } else if (current && dbg_reg_def[regno].offset != -1 && regno < 72) {
 176                 /* FP registers 38 -> 69 */
 177                 if (!(regs->cp0_status & ST0_CU1))
 178                         goto out;
 179                 save_fp(current);
 180                 if (regno == 70) {
 181                         /* Process the fcr31/fsr (register 70) */
 182                         memcpy(mem, (void *)&current->thread.fpu.fcr31,
 183                                dbg_reg_def[regno].size);
 184                         goto out;
 185                 } else if (regno == 71) {
 186                         /* Ignore the fir (register 71) */
 187                         memset(mem, 0, dbg_reg_def[regno].size);
 188                         goto out;
 189                 }
 190                 fp_reg = dbg_reg_def[regno].offset;
 191                 memcpy(mem, (void *)&current->thread.fpu.fpr[fp_reg],
 192                        dbg_reg_def[regno].size);
 193         }
 194 
 195 out:
 196         return dbg_reg_def[regno].name;
 197 
 198 }
 199 
 200 void arch_kgdb_breakpoint(void)
 201 {
 202         __asm__ __volatile__(
 203                 ".globl breakinst\n\t"
 204                 ".set\tnoreorder\n\t"
 205                 "nop\n"
 206                 "breakinst:\tbreak\n\t"
 207                 "nop\n\t"
 208                 ".set\treorder");
 209 }
 210 
 211 void kgdb_call_nmi_hook(void *ignored)
 212 {
 213         mm_segment_t old_fs;
 214 
 215         old_fs = get_fs();
 216         set_fs(KERNEL_DS);
 217 
 218         kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs());
 219 
 220         set_fs(old_fs);
 221 }
 222 
 223 static int compute_signal(int tt)
 224 {
 225         struct hard_trap_info *ht;
 226 
 227         for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
 228                 if (ht->tt == tt)
 229                         return ht->signo;
 230 
 231         return SIGHUP;          /* default for things we don't know about */
 232 }
 233 
 234 /*
 235  * Similar to regs_to_gdb_regs() except that process is sleeping and so
 236  * we may not be able to get all the info.
 237  */
 238 void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
 239 {
 240         int reg;
 241 #if (KGDB_GDB_REG_SIZE == 32)
 242         u32 *ptr = (u32 *)gdb_regs;
 243 #else
 244         u64 *ptr = (u64 *)gdb_regs;
 245 #endif
 246 
 247         for (reg = 0; reg < 16; reg++)
 248                 *(ptr++) = 0;
 249 
 250         /* S0 - S7 */
 251         *(ptr++) = p->thread.reg16;
 252         *(ptr++) = p->thread.reg17;
 253         *(ptr++) = p->thread.reg18;
 254         *(ptr++) = p->thread.reg19;
 255         *(ptr++) = p->thread.reg20;
 256         *(ptr++) = p->thread.reg21;
 257         *(ptr++) = p->thread.reg22;
 258         *(ptr++) = p->thread.reg23;
 259 
 260         for (reg = 24; reg < 28; reg++)
 261                 *(ptr++) = 0;
 262 
 263         /* GP, SP, FP, RA */
 264         *(ptr++) = (long)p;
 265         *(ptr++) = p->thread.reg29;
 266         *(ptr++) = p->thread.reg30;
 267         *(ptr++) = p->thread.reg31;
 268 
 269         *(ptr++) = p->thread.cp0_status;
 270 
 271         /* lo, hi */
 272         *(ptr++) = 0;
 273         *(ptr++) = 0;
 274 
 275         /*
 276          * BadVAddr, Cause
 277          * Ideally these would come from the last exception frame up the stack
 278          * but that requires unwinding, otherwise we can't know much for sure.
 279          */
 280         *(ptr++) = 0;
 281         *(ptr++) = 0;
 282 
 283         /*
 284          * PC
 285          * use return address (RA), i.e. the moment after return from resume()
 286          */
 287         *(ptr++) = p->thread.reg31;
 288 }
 289 
 290 void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
 291 {
 292         regs->cp0_epc = pc;
 293 }
 294 
 295 /*
 296  * Calls linux_debug_hook before the kernel dies. If KGDB is enabled,
 297  * then try to fall into the debugger
 298  */
 299 static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd,
 300                             void *ptr)
 301 {
 302         struct die_args *args = (struct die_args *)ptr;
 303         struct pt_regs *regs = args->regs;
 304         int trap = (regs->cp0_cause & 0x7c) >> 2;
 305         mm_segment_t old_fs;
 306 
 307 #ifdef CONFIG_KPROBES
 308         /*
 309          * Return immediately if the kprobes fault notifier has set
 310          * DIE_PAGE_FAULT.
 311          */
 312         if (cmd == DIE_PAGE_FAULT)
 313                 return NOTIFY_DONE;
 314 #endif /* CONFIG_KPROBES */
 315 
 316         /* Userspace events, ignore. */
 317         if (user_mode(regs))
 318                 return NOTIFY_DONE;
 319 
 320         /* Kernel mode. Set correct address limit */
 321         old_fs = get_fs();
 322         set_fs(KERNEL_DS);
 323 
 324         if (atomic_read(&kgdb_active) != -1)
 325                 kgdb_nmicallback(smp_processor_id(), regs);
 326 
 327         if (kgdb_handle_exception(trap, compute_signal(trap), cmd, regs)) {
 328                 set_fs(old_fs);
 329                 return NOTIFY_DONE;
 330         }
 331 
 332         if (atomic_read(&kgdb_setting_breakpoint))
 333                 if ((trap == 9) && (regs->cp0_epc == (unsigned long)breakinst))
 334                         regs->cp0_epc += 4;
 335 
 336         /* In SMP mode, __flush_cache_all does IPI */
 337         local_irq_enable();
 338         __flush_cache_all();
 339 
 340         set_fs(old_fs);
 341         return NOTIFY_STOP;
 342 }
 343 
 344 #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
 345 int kgdb_ll_trap(int cmd, const char *str,
 346                  struct pt_regs *regs, long err, int trap, int sig)
 347 {
 348         struct die_args args = {
 349                 .regs   = regs,
 350                 .str    = str,
 351                 .err    = err,
 352                 .trapnr = trap,
 353                 .signr  = sig,
 354 
 355         };
 356 
 357         if (!kgdb_io_module_registered)
 358                 return NOTIFY_DONE;
 359 
 360         return kgdb_mips_notify(NULL, cmd, &args);
 361 }
 362 #endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */
 363 
 364 static struct notifier_block kgdb_notifier = {
 365         .notifier_call = kgdb_mips_notify,
 366 };
 367 
 368 /*
 369  * Handle the 'c' command
 370  */
 371 int kgdb_arch_handle_exception(int vector, int signo, int err_code,
 372                                char *remcom_in_buffer, char *remcom_out_buffer,
 373                                struct pt_regs *regs)
 374 {
 375         char *ptr;
 376         unsigned long address;
 377 
 378         switch (remcom_in_buffer[0]) {
 379         case 'c':
 380                 /* handle the optional parameter */
 381                 ptr = &remcom_in_buffer[1];
 382                 if (kgdb_hex2long(&ptr, &address))
 383                         regs->cp0_epc = address;
 384 
 385                 return 0;
 386         }
 387 
 388         return -1;
 389 }
 390 
 391 const struct kgdb_arch arch_kgdb_ops = {
 392 #ifdef CONFIG_CPU_BIG_ENDIAN
 393         .gdb_bpt_instr = { spec_op << 2, 0x00, 0x00, break_op },
 394 #else
 395         .gdb_bpt_instr = { break_op, 0x00, 0x00, spec_op << 2 },
 396 #endif
 397 };
 398 
 399 int kgdb_arch_init(void)
 400 {
 401         register_die_notifier(&kgdb_notifier);
 402 
 403         return 0;
 404 }
 405 
 406 /*
 407  *      kgdb_arch_exit - Perform any architecture specific uninitalization.
 408  *
 409  *      This function will handle the uninitalization of any architecture
 410  *      specific callbacks, for dynamic registration and unregistration.
 411  */
 412 void kgdb_arch_exit(void)
 413 {
 414         unregister_die_notifier(&kgdb_notifier);
 415 }

/* [<][>][^][v][top][bottom][index][help] */