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