~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/hexagon/kernel/kgdb.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/hexagon/kernel/kgdb.c (Architecture sparc64) and /arch/mips/kernel/kgdb.c (Architecture mips)


  1 // SPDX-License-Identifier: GPL-2.0-only       << 
  2 /*                                                  1 /*
  3  * arch/hexagon/kernel/kgdb.c - Hexagon KGDB S !!   2  *  Originally written by Glenn Engel, Lake Stevens Instrument Division
  4  *                                                  3  *
  5  * Copyright (c) 2011-2012, The Linux Foundati !!   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.
  6  */                                                23  */
  7                                                    24 
  8 #include <linux/irq.h>                         !!  25 #include <linux/ptrace.h>               /* for linux pt_regs struct */
  9 #include <linux/sched.h>                       << 
 10 #include <linux/sched/task_stack.h>            << 
 11 #include <linux/kdebug.h>                      << 
 12 #include <linux/kgdb.h>                            26 #include <linux/kgdb.h>
 13                                                !!  27 #include <linux/kdebug.h>
 14 /* All registers are 4 bytes, for now */       !!  28 #include <linux/sched.h>
 15 #define GDB_SIZEOF_REG 4                       !!  29 #include <linux/smp.h>
 16                                                !!  30 #include <asm/inst.h>
 17 /* The register names are used during printing !!  31 #include <asm/fpu.h>
 18  * Keep these at three letters to pretty-print !!  32 #include <asm/cacheflush.h>
 19 struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_N !!  33 #include <asm/processor.h>
 20         { " r0", GDB_SIZEOF_REG, offsetof(stru !!  34 #include <asm/sigcontext.h>
 21         { " r1", GDB_SIZEOF_REG, offsetof(stru !!  35 #include <asm/irq_regs.h>
 22         { " r2", GDB_SIZEOF_REG, offsetof(stru !!  36 
 23         { " r3", GDB_SIZEOF_REG, offsetof(stru !!  37 static struct hard_trap_info {
 24         { " r4", GDB_SIZEOF_REG, offsetof(stru !!  38         unsigned char tt;       /* Trap type code for MIPS R3xxx and R4xxx */
 25         { " r5", GDB_SIZEOF_REG, offsetof(stru !!  39         unsigned char signo;    /* Signal that we map this trap into */
 26         { " r6", GDB_SIZEOF_REG, offsetof(stru !!  40 } hard_trap_info[] = {
 27         { " r7", GDB_SIZEOF_REG, offsetof(stru !!  41         { 6, SIGBUS },          /* instruction bus error */
 28         { " r8", GDB_SIZEOF_REG, offsetof(stru !!  42         { 7, SIGBUS },          /* data bus error */
 29         { " r9", GDB_SIZEOF_REG, offsetof(stru !!  43         { 9, SIGTRAP },         /* break */
 30         { "r10", GDB_SIZEOF_REG, offsetof(stru !!  44 /*      { 11, SIGILL }, */      /* CPU unusable */
 31         { "r11", GDB_SIZEOF_REG, offsetof(stru !!  45         { 12, SIGFPE },         /* overflow */
 32         { "r12", GDB_SIZEOF_REG, offsetof(stru !!  46         { 13, SIGTRAP },        /* trap */
 33         { "r13", GDB_SIZEOF_REG, offsetof(stru !!  47         { 14, SIGSEGV },        /* virtual instruction cache coherency */
 34         { "r14", GDB_SIZEOF_REG, offsetof(stru !!  48         { 15, SIGFPE },         /* floating point exception */
 35         { "r15", GDB_SIZEOF_REG, offsetof(stru !!  49         { 23, SIGSEGV },        /* watch */
 36         { "r16", GDB_SIZEOF_REG, offsetof(stru !!  50         { 31, SIGSEGV },        /* virtual data cache coherency */
 37         { "r17", GDB_SIZEOF_REG, offsetof(stru !!  51         { 0, 0}                 /* Must be last */
 38         { "r18", GDB_SIZEOF_REG, offsetof(stru << 
 39         { "r19", GDB_SIZEOF_REG, offsetof(stru << 
 40         { "r20", GDB_SIZEOF_REG, offsetof(stru << 
 41         { "r21", GDB_SIZEOF_REG, offsetof(stru << 
 42         { "r22", GDB_SIZEOF_REG, offsetof(stru << 
 43         { "r23", GDB_SIZEOF_REG, offsetof(stru << 
 44         { "r24", GDB_SIZEOF_REG, offsetof(stru << 
 45         { "r25", GDB_SIZEOF_REG, offsetof(stru << 
 46         { "r26", GDB_SIZEOF_REG, offsetof(stru << 
 47         { "r27", GDB_SIZEOF_REG, offsetof(stru << 
 48         { "r28", GDB_SIZEOF_REG, offsetof(stru << 
 49         { "r29", GDB_SIZEOF_REG, offsetof(stru << 
 50         { "r30", GDB_SIZEOF_REG, offsetof(stru << 
 51         { "r31", GDB_SIZEOF_REG, offsetof(stru << 
 52                                                << 
 53         { "usr", GDB_SIZEOF_REG, offsetof(stru << 
 54         { "preds", GDB_SIZEOF_REG, offsetof(st << 
 55         { " m0", GDB_SIZEOF_REG, offsetof(stru << 
 56         { " m1", GDB_SIZEOF_REG, offsetof(stru << 
 57         { "sa0", GDB_SIZEOF_REG, offsetof(stru << 
 58         { "sa1", GDB_SIZEOF_REG, offsetof(stru << 
 59         { "lc0", GDB_SIZEOF_REG, offsetof(stru << 
 60         { "lc1", GDB_SIZEOF_REG, offsetof(stru << 
 61         { " gp", GDB_SIZEOF_REG, offsetof(stru << 
 62         { "ugp", GDB_SIZEOF_REG, offsetof(stru << 
 63         { "cs0", GDB_SIZEOF_REG, offsetof(stru << 
 64         { "cs1", GDB_SIZEOF_REG, offsetof(stru << 
 65         { "psp", GDB_SIZEOF_REG, offsetof(stru << 
 66         { "elr", GDB_SIZEOF_REG, offsetof(stru << 
 67         { "est", GDB_SIZEOF_REG, offsetof(stru << 
 68         { "badva", GDB_SIZEOF_REG, offsetof(st << 
 69         { "restart_r0", GDB_SIZEOF_REG, offset << 
 70         { "syscall_nr", GDB_SIZEOF_REG, offset << 
 71 };                                                 52 };
 72                                                    53 
 73 const struct kgdb_arch arch_kgdb_ops = {       !!  54 struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] =
 74         /* trap0(#0xDB) 0x0cdb0054 */          !!  55 {
 75         .gdb_bpt_instr = {0x54, 0x00, 0xdb, 0x !!  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 },
 76 };                                                128 };
 77                                                   129 
 78 char *dbg_get_reg(int regno, void *mem, struct !! 130 int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
 79 {                                                 131 {
 80         if (regno >= DBG_MAX_REG_NUM || regno  !! 132         int fp_reg;
 81                 return NULL;                   << 
 82                                                   133 
 83         *((unsigned long *) mem) = *((unsigned !! 134         if (regno < 0 || regno >= DBG_MAX_REG_NUM)
 84                 dbg_reg_def[regno].offset));   !! 135                 return -EINVAL;
 85                                                   136 
 86         return dbg_reg_def[regno].name;        !! 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);
                                                   >> 156 out_save:
                                                   >> 157                 restore_fp(current);
                                                   >> 158         }
                                                   >> 159 
                                                   >> 160         return 0;
 87 }                                                 161 }
 88                                                   162 
 89 int dbg_set_reg(int regno, void *mem, struct p !! 163 char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
 90 {                                                 164 {
                                                   >> 165         int fp_reg;
                                                   >> 166 
 91         if (regno >= DBG_MAX_REG_NUM || regno     167         if (regno >= DBG_MAX_REG_NUM || regno < 0)
 92                 return -EINVAL;                !! 168                 return NULL;
 93                                                   169 
 94         *((unsigned long *) ((void *)regs + db !! 170         if (dbg_reg_def[regno].offset != -1 && regno < 38) {
 95                 *((unsigned long *) mem);      !! 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 
                                                   >> 194 out:
                                                   >> 195         return dbg_reg_def[regno].name;
 96                                                   196 
 97         return 0;                              << 
 98 }                                                 197 }
 99                                                   198 
100 void kgdb_arch_set_pc(struct pt_regs *regs, un !! 199 void arch_kgdb_breakpoint(void)
101 {                                                 200 {
102         instruction_pointer(regs) = pc;        !! 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");
103 }                                                 208 }
104                                                   209 
105                                                !! 210 static int compute_signal(int tt)
106 /*  Not yet working  */                        << 
107 void sleeping_thread_to_gdb_regs(unsigned long << 
108                                  struct task_s << 
109 {                                                 211 {
110         struct pt_regs *thread_regs;           !! 212         struct hard_trap_info *ht;
111                                                   213 
112         if (task == NULL)                      !! 214         for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
113                 return;                        !! 215                 if (ht->tt == tt)
                                                   >> 216                         return ht->signo;
114                                                   217 
115         /* Initialize to zero */               !! 218         return SIGHUP;          /* default for things we don't know about */
116         memset(gdb_regs, 0, NUMREGBYTES);      << 
117                                                << 
118         /* Otherwise, we have only some regist << 
119         thread_regs = task_pt_regs(task);      << 
120         gdb_regs[0] = thread_regs->r00;        << 
121 }                                                 219 }
122                                                   220 
123 /**                                            !! 221 /*
124  * kgdb_arch_handle_exception - Handle archite !! 222  * Similar to regs_to_gdb_regs() except that process is sleeping and so
125  * @vector: The error vector of the exception  !! 223  * we may not be able to get all the info.
126  * @signo: The signal number of the exception  << 
127  * @err_code: The error code of the exception  << 
128  * @remcom_in_buffer: The buffer of the packet << 
129  * @remcom_out_buffer: The buffer of %BUFMAX b << 
130  * @regs: The &struct pt_regs of the current p << 
131  *                                             << 
132  * This function MUST handle the 'c' and 's' c << 
133  * as well packets to set / remove a hardware  << 
134  * If there are additional packets which the h << 
135  * they are handled here.  The code should ret << 
136  * process more packets, and a %0 or %1 if it  << 
137  * kgdb callback.                              << 
138  *                                             << 
139  * Not yet working.                            << 
140  */                                               224  */
141 int kgdb_arch_handle_exception(int vector, int !! 225 void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
142                                char *remcom_in << 
143                                struct pt_regs  << 
144 {                                                 226 {
145         switch (remcom_in_buffer[0]) {         !! 227         int reg;
146         case 's':                              !! 228 #if (KGDB_GDB_REG_SIZE == 32)
147         case 'c':                              !! 229         u32 *ptr = (u32 *)gdb_regs;
148                 return 0;                      !! 230 #else
149         }                                      !! 231         u64 *ptr = (u64 *)gdb_regs;
150         /* Stay in the debugger. */            !! 232 #endif
151         return -1;                             !! 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;
152 }                                                 275 }
153                                                   276 
154 static int __kgdb_notify(struct die_args *args !! 277 void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
155 {                                                 278 {
156         /* cpu roundup */                      !! 279         regs->cp0_epc = pc;
157         if (atomic_read(&kgdb_active) != -1) { !! 280 }
158                 kgdb_nmicallback(smp_processor << 
159                 return NOTIFY_STOP;            << 
160         }                                      << 
161                                                   281 
162         if (user_mode(args->regs))             !! 282 /*
                                                   >> 283  * Calls linux_debug_hook before the kernel dies. If KGDB is enabled,
                                                   >> 284  * then try to fall into the debugger
                                                   >> 285  */
                                                   >> 286 static 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)
163                 return NOTIFY_DONE;               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);
164                                                   308 
165         if (kgdb_handle_exception(args->trapnr !! 309         if (kgdb_handle_exception(trap, compute_signal(trap), cmd, regs))
166                                     args->regs << 
167                 return NOTIFY_DONE;               310                 return NOTIFY_DONE;
168                                                   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 
169         return NOTIFY_STOP;                       320         return NOTIFY_STOP;
170 }                                                 321 }
171                                                   322 
172 static int                                     !! 323 #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
173 kgdb_notify(struct notifier_block *self, unsig !! 324 int kgdb_ll_trap(int cmd, const char *str,
                                                   >> 325                  struct pt_regs *regs, long err, int trap, int sig)
174 {                                                 326 {
175         unsigned long flags;                   !! 327         struct die_args args = {
176         int ret;                               !! 328                 .regs   = regs,
                                                   >> 329                 .str    = str,
                                                   >> 330                 .err    = err,
                                                   >> 331                 .trapnr = trap,
                                                   >> 332                 .signr  = sig,
                                                   >> 333 
                                                   >> 334         };
177                                                   335 
178         local_irq_save(flags);                 !! 336         if (!kgdb_io_module_registered)
179         ret = __kgdb_notify(ptr, cmd);         !! 337                 return NOTIFY_DONE;
180         local_irq_restore(flags);              << 
181                                                   338 
182         return ret;                            !! 339         return kgdb_mips_notify(NULL, cmd, &args);
183 }                                                 340 }
                                                   >> 341 #endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */
184                                                   342 
185 static struct notifier_block kgdb_notifier = {    343 static struct notifier_block kgdb_notifier = {
186         .notifier_call = kgdb_notify,          !! 344         .notifier_call = kgdb_mips_notify,
187                                                << 
188         /*                                     << 
189          * Lowest-prio notifier priority, we w << 
190          */                                    << 
191         .priority = -INT_MAX,                  << 
192 };                                                345 };
193                                                   346 
194 /**                                            !! 347 /*
195  * kgdb_arch_init - Perform any architecture s !! 348  * Handle the 'c' command
196  *                                             << 
197  * This function will handle the initializatio << 
198  * specific callbacks.                         << 
199  */                                               349  */
                                                   >> 350 int 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 
                                                   >> 370 const 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 
200 int kgdb_arch_init(void)                          378 int kgdb_arch_init(void)
201 {                                                 379 {
202         return register_die_notifier(&kgdb_not !! 380         register_die_notifier(&kgdb_notifier);
                                                   >> 381 
                                                   >> 382         return 0;
203 }                                                 383 }
204                                                   384 
205 /**                                            !! 385 /*
206  * kgdb_arch_exit - Perform any architecture s !! 386  *      kgdb_arch_exit - Perform any architecture specific uninitalization.
207  *                                                387  *
208  * This function will handle the uninitalizati !! 388  *      This function will handle the uninitalization of any architecture
209  * specific callbacks, for dynamic registratio !! 389  *      specific callbacks, for dynamic registration and unregistration.
210  */                                               390  */
211 void kgdb_arch_exit(void)                         391 void kgdb_arch_exit(void)
212 {                                                 392 {
213         unregister_die_notifier(&kgdb_notifier    393         unregister_die_notifier(&kgdb_notifier);
214 }                                                 394 }
215                                                   395 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php