Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * kgdb support for ARC
0004  *
0005  * Copyright (C) 2012 Synopsys, Inc. (www.synopsys.com)
0006  */
0007 
0008 #include <linux/kgdb.h>
0009 #include <linux/sched.h>
0010 #include <linux/sched/task_stack.h>
0011 #include <asm/disasm.h>
0012 #include <asm/cacheflush.h>
0013 
0014 static void to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs,
0015             struct callee_regs *cregs)
0016 {
0017     int regno;
0018 
0019     for (regno = 0; regno <= 26; regno++)
0020         gdb_regs[_R0 + regno] = get_reg(regno, kernel_regs, cregs);
0021 
0022     for (regno = 27; regno < GDB_MAX_REGS; regno++)
0023         gdb_regs[regno] = 0;
0024 
0025     gdb_regs[_FP]       = kernel_regs->fp;
0026     gdb_regs[__SP]      = kernel_regs->sp;
0027     gdb_regs[_BLINK]    = kernel_regs->blink;
0028     gdb_regs[_RET]      = kernel_regs->ret;
0029     gdb_regs[_STATUS32] = kernel_regs->status32;
0030     gdb_regs[_LP_COUNT] = kernel_regs->lp_count;
0031     gdb_regs[_LP_END]   = kernel_regs->lp_end;
0032     gdb_regs[_LP_START] = kernel_regs->lp_start;
0033     gdb_regs[_BTA]      = kernel_regs->bta;
0034     gdb_regs[_STOP_PC]  = kernel_regs->ret;
0035 }
0036 
0037 static void from_gdb_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs,
0038             struct callee_regs *cregs)
0039 {
0040     int regno;
0041 
0042     for (regno = 0; regno <= 26; regno++)
0043         set_reg(regno, gdb_regs[regno + _R0], kernel_regs, cregs);
0044 
0045     kernel_regs->fp     = gdb_regs[_FP];
0046     kernel_regs->sp     = gdb_regs[__SP];
0047     kernel_regs->blink  = gdb_regs[_BLINK];
0048     kernel_regs->ret    = gdb_regs[_RET];
0049     kernel_regs->status32   = gdb_regs[_STATUS32];
0050     kernel_regs->lp_count   = gdb_regs[_LP_COUNT];
0051     kernel_regs->lp_end = gdb_regs[_LP_END];
0052     kernel_regs->lp_start   = gdb_regs[_LP_START];
0053     kernel_regs->bta    = gdb_regs[_BTA];
0054 }
0055 
0056 
0057 void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs)
0058 {
0059     to_gdb_regs(gdb_regs, kernel_regs, (struct callee_regs *)
0060         current->thread.callee_reg);
0061 }
0062 
0063 void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs)
0064 {
0065     from_gdb_regs(gdb_regs, kernel_regs, (struct callee_regs *)
0066         current->thread.callee_reg);
0067 }
0068 
0069 void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs,
0070                  struct task_struct *task)
0071 {
0072     if (task)
0073         to_gdb_regs(gdb_regs, task_pt_regs(task),
0074             (struct callee_regs *) task->thread.callee_reg);
0075 }
0076 
0077 struct single_step_data_t {
0078     uint16_t opcode[2];
0079     unsigned long address[2];
0080     int is_branch;
0081     int armed;
0082 } single_step_data;
0083 
0084 static void undo_single_step(struct pt_regs *regs)
0085 {
0086     if (single_step_data.armed) {
0087         int i;
0088 
0089         for (i = 0; i < (single_step_data.is_branch ? 2 : 1); i++) {
0090             memcpy((void *) single_step_data.address[i],
0091                 &single_step_data.opcode[i],
0092                 BREAK_INSTR_SIZE);
0093 
0094             flush_icache_range(single_step_data.address[i],
0095                 single_step_data.address[i] +
0096                 BREAK_INSTR_SIZE);
0097         }
0098         single_step_data.armed = 0;
0099     }
0100 }
0101 
0102 static void place_trap(unsigned long address, void *save)
0103 {
0104     memcpy(save, (void *) address, BREAK_INSTR_SIZE);
0105     memcpy((void *) address, &arch_kgdb_ops.gdb_bpt_instr,
0106         BREAK_INSTR_SIZE);
0107     flush_icache_range(address, address + BREAK_INSTR_SIZE);
0108 }
0109 
0110 static void do_single_step(struct pt_regs *regs)
0111 {
0112     single_step_data.is_branch = disasm_next_pc((unsigned long)
0113         regs->ret, regs, (struct callee_regs *)
0114         current->thread.callee_reg,
0115         &single_step_data.address[0],
0116         &single_step_data.address[1]);
0117 
0118     place_trap(single_step_data.address[0], &single_step_data.opcode[0]);
0119 
0120     if (single_step_data.is_branch) {
0121         place_trap(single_step_data.address[1],
0122             &single_step_data.opcode[1]);
0123     }
0124 
0125     single_step_data.armed++;
0126 }
0127 
0128 int kgdb_arch_handle_exception(int e_vector, int signo, int err_code,
0129                    char *remcomInBuffer, char *remcomOutBuffer,
0130                    struct pt_regs *regs)
0131 {
0132     unsigned long addr;
0133     char *ptr;
0134 
0135     undo_single_step(regs);
0136 
0137     switch (remcomInBuffer[0]) {
0138     case 's':
0139     case 'c':
0140         ptr = &remcomInBuffer[1];
0141         if (kgdb_hex2long(&ptr, &addr))
0142             regs->ret = addr;
0143         fallthrough;
0144 
0145     case 'D':
0146     case 'k':
0147         atomic_set(&kgdb_cpu_doing_single_step, -1);
0148 
0149         if (remcomInBuffer[0] == 's') {
0150             do_single_step(regs);
0151             atomic_set(&kgdb_cpu_doing_single_step,
0152                    smp_processor_id());
0153         }
0154 
0155         return 0;
0156     }
0157     return -1;
0158 }
0159 
0160 int kgdb_arch_init(void)
0161 {
0162     single_step_data.armed = 0;
0163     return 0;
0164 }
0165 
0166 void kgdb_trap(struct pt_regs *regs)
0167 {
0168     /* trap_s 3 is used for breakpoints that overwrite existing
0169      * instructions, while trap_s 4 is used for compiled breakpoints.
0170      *
0171      * with trap_s 3 breakpoints the original instruction needs to be
0172      * restored and continuation needs to start at the location of the
0173      * breakpoint.
0174      *
0175      * with trap_s 4 (compiled) breakpoints, continuation needs to
0176      * start after the breakpoint.
0177      */
0178     if (regs->ecr_param == 3)
0179         instruction_pointer(regs) -= BREAK_INSTR_SIZE;
0180 
0181     kgdb_handle_exception(1, SIGTRAP, 0, regs);
0182 }
0183 
0184 void kgdb_arch_exit(void)
0185 {
0186 }
0187 
0188 void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip)
0189 {
0190     instruction_pointer(regs) = ip;
0191 }
0192 
0193 void kgdb_call_nmi_hook(void *ignored)
0194 {
0195     /* Default implementation passes get_irq_regs() but we don't */
0196     kgdb_nmicallback(raw_smp_processor_id(), NULL);
0197 }
0198 
0199 const struct kgdb_arch arch_kgdb_ops = {
0200     /* breakpoint instruction: TRAP_S 0x3 */
0201 #ifdef CONFIG_CPU_BIG_ENDIAN
0202     .gdb_bpt_instr      = {0x78, 0x7e},
0203 #else
0204     .gdb_bpt_instr      = {0x7e, 0x78},
0205 #endif
0206 };