1 /* 2 * AArch64 KGDB support 3 * 4 * Based on arch/arm/kernel/kgdb.c 5 * 6 * Copyright (C) 2013 Cavium Inc. 7 * Author: Vijaya Kumar K <vijaya.kumar@caviumnetworks.com> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program. If not, see <http://www.gnu.org/licenses/>. 20 */ 21 22 #include <linux/irq.h> 23 #include <linux/kdebug.h> 24 #include <linux/kgdb.h> 25 #include <asm/traps.h> 26 27 struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = { 28 { "x0", 8, offsetof(struct pt_regs, regs[0])}, 29 { "x1", 8, offsetof(struct pt_regs, regs[1])}, 30 { "x2", 8, offsetof(struct pt_regs, regs[2])}, 31 { "x3", 8, offsetof(struct pt_regs, regs[3])}, 32 { "x4", 8, offsetof(struct pt_regs, regs[4])}, 33 { "x5", 8, offsetof(struct pt_regs, regs[5])}, 34 { "x6", 8, offsetof(struct pt_regs, regs[6])}, 35 { "x7", 8, offsetof(struct pt_regs, regs[7])}, 36 { "x8", 8, offsetof(struct pt_regs, regs[8])}, 37 { "x9", 8, offsetof(struct pt_regs, regs[9])}, 38 { "x10", 8, offsetof(struct pt_regs, regs[10])}, 39 { "x11", 8, offsetof(struct pt_regs, regs[11])}, 40 { "x12", 8, offsetof(struct pt_regs, regs[12])}, 41 { "x13", 8, offsetof(struct pt_regs, regs[13])}, 42 { "x14", 8, offsetof(struct pt_regs, regs[14])}, 43 { "x15", 8, offsetof(struct pt_regs, regs[15])}, 44 { "x16", 8, offsetof(struct pt_regs, regs[16])}, 45 { "x17", 8, offsetof(struct pt_regs, regs[17])}, 46 { "x18", 8, offsetof(struct pt_regs, regs[18])}, 47 { "x19", 8, offsetof(struct pt_regs, regs[19])}, 48 { "x20", 8, offsetof(struct pt_regs, regs[20])}, 49 { "x21", 8, offsetof(struct pt_regs, regs[21])}, 50 { "x22", 8, offsetof(struct pt_regs, regs[22])}, 51 { "x23", 8, offsetof(struct pt_regs, regs[23])}, 52 { "x24", 8, offsetof(struct pt_regs, regs[24])}, 53 { "x25", 8, offsetof(struct pt_regs, regs[25])}, 54 { "x26", 8, offsetof(struct pt_regs, regs[26])}, 55 { "x27", 8, offsetof(struct pt_regs, regs[27])}, 56 { "x28", 8, offsetof(struct pt_regs, regs[28])}, 57 { "x29", 8, offsetof(struct pt_regs, regs[29])}, 58 { "x30", 8, offsetof(struct pt_regs, regs[30])}, 59 { "sp", 8, offsetof(struct pt_regs, sp)}, 60 { "pc", 8, offsetof(struct pt_regs, pc)}, 61 { "pstate", 8, offsetof(struct pt_regs, pstate)}, 62 { "v0", 16, -1 }, 63 { "v1", 16, -1 }, 64 { "v2", 16, -1 }, 65 { "v3", 16, -1 }, 66 { "v4", 16, -1 }, 67 { "v5", 16, -1 }, 68 { "v6", 16, -1 }, 69 { "v7", 16, -1 }, 70 { "v8", 16, -1 }, 71 { "v9", 16, -1 }, 72 { "v10", 16, -1 }, 73 { "v11", 16, -1 }, 74 { "v12", 16, -1 }, 75 { "v13", 16, -1 }, 76 { "v14", 16, -1 }, 77 { "v15", 16, -1 }, 78 { "v16", 16, -1 }, 79 { "v17", 16, -1 }, 80 { "v18", 16, -1 }, 81 { "v19", 16, -1 }, 82 { "v20", 16, -1 }, 83 { "v21", 16, -1 }, 84 { "v22", 16, -1 }, 85 { "v23", 16, -1 }, 86 { "v24", 16, -1 }, 87 { "v25", 16, -1 }, 88 { "v26", 16, -1 }, 89 { "v27", 16, -1 }, 90 { "v28", 16, -1 }, 91 { "v29", 16, -1 }, 92 { "v30", 16, -1 }, 93 { "v31", 16, -1 }, 94 { "fpsr", 4, -1 }, 95 { "fpcr", 4, -1 }, 96 }; 97 98 char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs) 99 { 100 if (regno >= DBG_MAX_REG_NUM || regno < 0) 101 return NULL; 102 103 if (dbg_reg_def[regno].offset != -1) 104 memcpy(mem, (void *)regs + dbg_reg_def[regno].offset, 105 dbg_reg_def[regno].size); 106 else 107 memset(mem, 0, dbg_reg_def[regno].size); 108 return dbg_reg_def[regno].name; 109 } 110 111 int dbg_set_reg(int regno, void *mem, struct pt_regs *regs) 112 { 113 if (regno >= DBG_MAX_REG_NUM || regno < 0) 114 return -EINVAL; 115 116 if (dbg_reg_def[regno].offset != -1) 117 memcpy((void *)regs + dbg_reg_def[regno].offset, mem, 118 dbg_reg_def[regno].size); 119 return 0; 120 } 121 122 void 123 sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task) 124 { 125 struct pt_regs *thread_regs; 126 127 /* Initialize to zero */ 128 memset((char *)gdb_regs, 0, NUMREGBYTES); 129 thread_regs = task_pt_regs(task); 130 memcpy((void *)gdb_regs, (void *)thread_regs->regs, GP_REG_BYTES); 131 } 132 133 void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc) 134 { 135 regs->pc = pc; 136 } 137 138 static int compiled_break; 139 140 static void kgdb_arch_update_addr(struct pt_regs *regs, 141 char *remcom_in_buffer) 142 { 143 unsigned long addr; 144 char *ptr; 145 146 ptr = &remcom_in_buffer[1]; 147 if (kgdb_hex2long(&ptr, &addr)) 148 kgdb_arch_set_pc(regs, addr); 149 else if (compiled_break == 1) 150 kgdb_arch_set_pc(regs, regs->pc + 4); 151 152 compiled_break = 0; 153 } 154 155 int kgdb_arch_handle_exception(int exception_vector, int signo, 156 int err_code, char *remcom_in_buffer, 157 char *remcom_out_buffer, 158 struct pt_regs *linux_regs) 159 { 160 int err; 161 162 switch (remcom_in_buffer[0]) { 163 case 'D': 164 case 'k': 165 /* 166 * Packet D (Detach), k (kill). No special handling 167 * is required here. Handle same as c packet. 168 */ 169 case 'c': 170 /* 171 * Packet c (Continue) to continue executing. 172 * Set pc to required address. 173 * Try to read optional parameter and set pc. 174 * If this was a compiled breakpoint, we need to move 175 * to the next instruction else we will just breakpoint 176 * over and over again. 177 */ 178 kgdb_arch_update_addr(linux_regs, remcom_in_buffer); 179 atomic_set(&kgdb_cpu_doing_single_step, -1); 180 kgdb_single_step = 0; 181 182 /* 183 * Received continue command, disable single step 184 */ 185 if (kernel_active_single_step()) 186 kernel_disable_single_step(); 187 188 err = 0; 189 break; 190 case 's': 191 /* 192 * Update step address value with address passed 193 * with step packet. 194 * On debug exception return PC is copied to ELR 195 * So just update PC. 196 * If no step address is passed, resume from the address 197 * pointed by PC. Do not update PC 198 */ 199 kgdb_arch_update_addr(linux_regs, remcom_in_buffer); 200 atomic_set(&kgdb_cpu_doing_single_step, raw_smp_processor_id()); 201 kgdb_single_step = 1; 202 203 /* 204 * Enable single step handling 205 */ 206 if (!kernel_active_single_step()) 207 kernel_enable_single_step(linux_regs); 208 err = 0; 209 break; 210 default: 211 err = -1; 212 } 213 return err; 214 } 215 216 static int kgdb_brk_fn(struct pt_regs *regs, unsigned int esr) 217 { 218 kgdb_handle_exception(1, SIGTRAP, 0, regs); 219 return 0; 220 } 221 222 static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int esr) 223 { 224 compiled_break = 1; 225 kgdb_handle_exception(1, SIGTRAP, 0, regs); 226 227 return 0; 228 } 229 230 static int kgdb_step_brk_fn(struct pt_regs *regs, unsigned int esr) 231 { 232 kgdb_handle_exception(1, SIGTRAP, 0, regs); 233 return 0; 234 } 235 236 static struct break_hook kgdb_brkpt_hook = { 237 .esr_mask = 0xffffffff, 238 .esr_val = (u32)ESR_ELx_VAL_BRK64(KGDB_DYN_DBG_BRK_IMM), 239 .fn = kgdb_brk_fn 240 }; 241 242 static struct break_hook kgdb_compiled_brkpt_hook = { 243 .esr_mask = 0xffffffff, 244 .esr_val = (u32)ESR_ELx_VAL_BRK64(KGDB_COMPILED_DBG_BRK_IMM), 245 .fn = kgdb_compiled_brk_fn 246 }; 247 248 static struct step_hook kgdb_step_hook = { 249 .fn = kgdb_step_brk_fn 250 }; 251 252 static void kgdb_call_nmi_hook(void *ignored) 253 { 254 kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs()); 255 } 256 257 void kgdb_roundup_cpus(unsigned long flags) 258 { 259 local_irq_enable(); 260 smp_call_function(kgdb_call_nmi_hook, NULL, 0); 261 local_irq_disable(); 262 } 263 264 static int __kgdb_notify(struct die_args *args, unsigned long cmd) 265 { 266 struct pt_regs *regs = args->regs; 267 268 if (kgdb_handle_exception(1, args->signr, cmd, regs)) 269 return NOTIFY_DONE; 270 return NOTIFY_STOP; 271 } 272 273 static int 274 kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr) 275 { 276 unsigned long flags; 277 int ret; 278 279 local_irq_save(flags); 280 ret = __kgdb_notify(ptr, cmd); 281 local_irq_restore(flags); 282 283 return ret; 284 } 285 286 static struct notifier_block kgdb_notifier = { 287 .notifier_call = kgdb_notify, 288 /* 289 * Want to be lowest priority 290 */ 291 .priority = -INT_MAX, 292 }; 293 294 /* 295 * kgdb_arch_init - Perform any architecture specific initalization. 296 * This function will handle the initalization of any architecture 297 * specific callbacks. 298 */ 299 int kgdb_arch_init(void) 300 { 301 int ret = register_die_notifier(&kgdb_notifier); 302 303 if (ret != 0) 304 return ret; 305 306 register_break_hook(&kgdb_brkpt_hook); 307 register_break_hook(&kgdb_compiled_brkpt_hook); 308 register_step_hook(&kgdb_step_hook); 309 return 0; 310 } 311 312 /* 313 * kgdb_arch_exit - Perform any architecture specific uninitalization. 314 * This function will handle the uninitalization of any architecture 315 * specific callbacks, for dynamic registration and unregistration. 316 */ 317 void kgdb_arch_exit(void) 318 { 319 unregister_break_hook(&kgdb_brkpt_hook); 320 unregister_break_hook(&kgdb_compiled_brkpt_hook); 321 unregister_step_hook(&kgdb_step_hook); 322 unregister_die_notifier(&kgdb_notifier); 323 } 324 325 /* 326 * ARM instructions are always in LE. 327 * Break instruction is encoded in LE format 328 */ 329 struct kgdb_arch arch_kgdb_ops = { 330 .gdb_bpt_instr = { 331 KGDB_DYN_BRK_INS_BYTE(0), 332 KGDB_DYN_BRK_INS_BYTE(1), 333 KGDB_DYN_BRK_INS_BYTE(2), 334 KGDB_DYN_BRK_INS_BYTE(3), 335 } 336 }; 337