linux/arch/mips/kernel/kgdb.c
<<
>>
Prefs
   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
  38static 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
  55struct 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
 131int 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);
 157out_save:
 158                restore_fp(current);
 159        }
 160
 161        return 0;
 162}
 163
 164char *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
 195out:
 196        return dbg_reg_def[regno].name;
 197
 198}
 199
 200void 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
 211void 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
 223static 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 */
 238void 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
 290void 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 */
 299static 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
 345int 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
 364static struct notifier_block kgdb_notifier = {
 365        .notifier_call = kgdb_mips_notify,
 366};
 367
 368/*
 369 * Handle the 'c' command
 370 */
 371int 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
 391const 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
 399int 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 */
 412void kgdb_arch_exit(void)
 413{
 414        unregister_die_notifier(&kgdb_notifier);
 415}
 416