Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * arch/arm/kernel/kgdb.c
0004  *
0005  * ARM KGDB support
0006  *
0007  * Copyright (c) 2002-2004 MontaVista Software, Inc
0008  * Copyright (c) 2008 Wind River Systems, Inc.
0009  *
0010  * Authors:  George Davis <davis_g@mvista.com>
0011  *           Deepak Saxena <dsaxena@plexity.net>
0012  */
0013 #include <linux/irq.h>
0014 #include <linux/kdebug.h>
0015 #include <linux/kgdb.h>
0016 #include <linux/uaccess.h>
0017 
0018 #include <asm/patch.h>
0019 #include <asm/traps.h>
0020 
0021 struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] =
0022 {
0023     { "r0", 4, offsetof(struct pt_regs, ARM_r0)},
0024     { "r1", 4, offsetof(struct pt_regs, ARM_r1)},
0025     { "r2", 4, offsetof(struct pt_regs, ARM_r2)},
0026     { "r3", 4, offsetof(struct pt_regs, ARM_r3)},
0027     { "r4", 4, offsetof(struct pt_regs, ARM_r4)},
0028     { "r5", 4, offsetof(struct pt_regs, ARM_r5)},
0029     { "r6", 4, offsetof(struct pt_regs, ARM_r6)},
0030     { "r7", 4, offsetof(struct pt_regs, ARM_r7)},
0031     { "r8", 4, offsetof(struct pt_regs, ARM_r8)},
0032     { "r9", 4, offsetof(struct pt_regs, ARM_r9)},
0033     { "r10", 4, offsetof(struct pt_regs, ARM_r10)},
0034     { "fp", 4, offsetof(struct pt_regs, ARM_fp)},
0035     { "ip", 4, offsetof(struct pt_regs, ARM_ip)},
0036     { "sp", 4, offsetof(struct pt_regs, ARM_sp)},
0037     { "lr", 4, offsetof(struct pt_regs, ARM_lr)},
0038     { "pc", 4, offsetof(struct pt_regs, ARM_pc)},
0039     { "f0", 12, -1 },
0040     { "f1", 12, -1 },
0041     { "f2", 12, -1 },
0042     { "f3", 12, -1 },
0043     { "f4", 12, -1 },
0044     { "f5", 12, -1 },
0045     { "f6", 12, -1 },
0046     { "f7", 12, -1 },
0047     { "fps", 4, -1 },
0048     { "cpsr", 4, offsetof(struct pt_regs, ARM_cpsr)},
0049 };
0050 
0051 char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
0052 {
0053     if (regno >= DBG_MAX_REG_NUM || regno < 0)
0054         return NULL;
0055 
0056     if (dbg_reg_def[regno].offset != -1)
0057         memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
0058                dbg_reg_def[regno].size);
0059     else
0060         memset(mem, 0, dbg_reg_def[regno].size);
0061     return dbg_reg_def[regno].name;
0062 }
0063 
0064 int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
0065 {
0066     if (regno >= DBG_MAX_REG_NUM || regno < 0)
0067         return -EINVAL;
0068 
0069     if (dbg_reg_def[regno].offset != -1)
0070         memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
0071                dbg_reg_def[regno].size);
0072     return 0;
0073 }
0074 
0075 void
0076 sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
0077 {
0078     struct thread_info *ti;
0079     int regno;
0080 
0081     /* Just making sure... */
0082     if (task == NULL)
0083         return;
0084 
0085     /* Initialize to zero */
0086     for (regno = 0; regno < GDB_MAX_REGS; regno++)
0087         gdb_regs[regno] = 0;
0088 
0089     /* Otherwise, we have only some registers from switch_to() */
0090     ti          = task_thread_info(task);
0091     gdb_regs[_R4]       = ti->cpu_context.r4;
0092     gdb_regs[_R5]       = ti->cpu_context.r5;
0093     gdb_regs[_R6]       = ti->cpu_context.r6;
0094     gdb_regs[_R7]       = ti->cpu_context.r7;
0095     gdb_regs[_R8]       = ti->cpu_context.r8;
0096     gdb_regs[_R9]       = ti->cpu_context.r9;
0097     gdb_regs[_R10]      = ti->cpu_context.sl;
0098     gdb_regs[_FP]       = ti->cpu_context.fp;
0099     gdb_regs[_SPT]      = ti->cpu_context.sp;
0100     gdb_regs[_PC]       = ti->cpu_context.pc;
0101 }
0102 
0103 void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
0104 {
0105     regs->ARM_pc = pc;
0106 }
0107 
0108 static int compiled_break;
0109 
0110 int kgdb_arch_handle_exception(int exception_vector, int signo,
0111                    int err_code, char *remcom_in_buffer,
0112                    char *remcom_out_buffer,
0113                    struct pt_regs *linux_regs)
0114 {
0115     unsigned long addr;
0116     char *ptr;
0117 
0118     switch (remcom_in_buffer[0]) {
0119     case 'D':
0120     case 'k':
0121     case 'c':
0122         /*
0123          * Try to read optional parameter, pc unchanged if no parm.
0124          * If this was a compiled breakpoint, we need to move
0125          * to the next instruction or we will just breakpoint
0126          * over and over again.
0127          */
0128         ptr = &remcom_in_buffer[1];
0129         if (kgdb_hex2long(&ptr, &addr))
0130             linux_regs->ARM_pc = addr;
0131         else if (compiled_break == 1)
0132             linux_regs->ARM_pc += 4;
0133 
0134         compiled_break = 0;
0135 
0136         return 0;
0137     }
0138 
0139     return -1;
0140 }
0141 
0142 static int kgdb_brk_fn(struct pt_regs *regs, unsigned int instr)
0143 {
0144     kgdb_handle_exception(1, SIGTRAP, 0, regs);
0145 
0146     return 0;
0147 }
0148 
0149 static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int instr)
0150 {
0151     compiled_break = 1;
0152     kgdb_handle_exception(1, SIGTRAP, 0, regs);
0153 
0154     return 0;
0155 }
0156 
0157 static struct undef_hook kgdb_brkpt_arm_hook = {
0158     .instr_mask     = 0xffffffff,
0159     .instr_val      = KGDB_BREAKINST,
0160     .cpsr_mask      = PSR_T_BIT | MODE_MASK,
0161     .cpsr_val       = SVC_MODE,
0162     .fn         = kgdb_brk_fn
0163 };
0164 
0165 static struct undef_hook kgdb_brkpt_thumb_hook = {
0166     .instr_mask     = 0xffff,
0167     .instr_val      = KGDB_BREAKINST & 0xffff,
0168     .cpsr_mask      = PSR_T_BIT | MODE_MASK,
0169     .cpsr_val       = PSR_T_BIT | SVC_MODE,
0170     .fn         = kgdb_brk_fn
0171 };
0172 
0173 static struct undef_hook kgdb_compiled_brkpt_arm_hook = {
0174     .instr_mask     = 0xffffffff,
0175     .instr_val      = KGDB_COMPILED_BREAK,
0176     .cpsr_mask      = PSR_T_BIT | MODE_MASK,
0177     .cpsr_val       = SVC_MODE,
0178     .fn         = kgdb_compiled_brk_fn
0179 };
0180 
0181 static struct undef_hook kgdb_compiled_brkpt_thumb_hook = {
0182     .instr_mask     = 0xffff,
0183     .instr_val      = KGDB_COMPILED_BREAK & 0xffff,
0184     .cpsr_mask      = PSR_T_BIT | MODE_MASK,
0185     .cpsr_val       = PSR_T_BIT | SVC_MODE,
0186     .fn         = kgdb_compiled_brk_fn
0187 };
0188 
0189 static int __kgdb_notify(struct die_args *args, unsigned long cmd)
0190 {
0191     struct pt_regs *regs = args->regs;
0192 
0193     if (kgdb_handle_exception(1, args->signr, cmd, regs))
0194         return NOTIFY_DONE;
0195     return NOTIFY_STOP;
0196 }
0197 static int
0198 kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr)
0199 {
0200     unsigned long flags;
0201     int ret;
0202 
0203     local_irq_save(flags);
0204     ret = __kgdb_notify(ptr, cmd);
0205     local_irq_restore(flags);
0206 
0207     return ret;
0208 }
0209 
0210 static struct notifier_block kgdb_notifier = {
0211     .notifier_call  = kgdb_notify,
0212     .priority   = -INT_MAX,
0213 };
0214 
0215 
0216 /**
0217  *  kgdb_arch_init - Perform any architecture specific initalization.
0218  *
0219  *  This function will handle the initalization of any architecture
0220  *  specific callbacks.
0221  */
0222 int kgdb_arch_init(void)
0223 {
0224     int ret = register_die_notifier(&kgdb_notifier);
0225 
0226     if (ret != 0)
0227         return ret;
0228 
0229     register_undef_hook(&kgdb_brkpt_arm_hook);
0230     register_undef_hook(&kgdb_brkpt_thumb_hook);
0231     register_undef_hook(&kgdb_compiled_brkpt_arm_hook);
0232     register_undef_hook(&kgdb_compiled_brkpt_thumb_hook);
0233 
0234     return 0;
0235 }
0236 
0237 /**
0238  *  kgdb_arch_exit - Perform any architecture specific uninitalization.
0239  *
0240  *  This function will handle the uninitalization of any architecture
0241  *  specific callbacks, for dynamic registration and unregistration.
0242  */
0243 void kgdb_arch_exit(void)
0244 {
0245     unregister_undef_hook(&kgdb_brkpt_arm_hook);
0246     unregister_undef_hook(&kgdb_brkpt_thumb_hook);
0247     unregister_undef_hook(&kgdb_compiled_brkpt_arm_hook);
0248     unregister_undef_hook(&kgdb_compiled_brkpt_thumb_hook);
0249     unregister_die_notifier(&kgdb_notifier);
0250 }
0251 
0252 int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
0253 {
0254     int err;
0255 
0256     /* patch_text() only supports int-sized breakpoints */
0257     BUILD_BUG_ON(sizeof(int) != BREAK_INSTR_SIZE);
0258 
0259     err = copy_from_kernel_nofault(bpt->saved_instr, (char *)bpt->bpt_addr,
0260                 BREAK_INSTR_SIZE);
0261     if (err)
0262         return err;
0263 
0264     /* Machine is already stopped, so we can use __patch_text() directly */
0265     __patch_text((void *)bpt->bpt_addr,
0266              *(unsigned int *)arch_kgdb_ops.gdb_bpt_instr);
0267 
0268     return err;
0269 }
0270 
0271 int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
0272 {
0273     /* Machine is already stopped, so we can use __patch_text() directly */
0274     __patch_text((void *)bpt->bpt_addr, *(unsigned int *)bpt->saved_instr);
0275 
0276     return 0;
0277 }
0278 
0279 /*
0280  * Register our undef instruction hooks with ARM undef core.
0281  * We register a hook specifically looking for the KGB break inst
0282  * and we handle the normal undef case within the do_undefinstr
0283  * handler.
0284  */
0285 const struct kgdb_arch arch_kgdb_ops = {
0286 #ifndef __ARMEB__
0287     .gdb_bpt_instr      = {0xfe, 0xde, 0xff, 0xe7}
0288 #else /* ! __ARMEB__ */
0289     .gdb_bpt_instr      = {0xe7, 0xff, 0xde, 0xfe}
0290 #endif
0291 };