root/arch/arc/kernel/kgdb.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. to_gdb_regs
  2. from_gdb_regs
  3. pt_regs_to_gdb_regs
  4. gdb_regs_to_pt_regs
  5. sleeping_thread_to_gdb_regs
  6. undo_single_step
  7. place_trap
  8. do_single_step
  9. kgdb_arch_handle_exception
  10. kgdb_arch_init
  11. kgdb_trap
  12. kgdb_arch_exit
  13. kgdb_arch_set_pc
  14. kgdb_call_nmi_hook

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * kgdb support for ARC
   4  *
   5  * Copyright (C) 2012 Synopsys, Inc. (www.synopsys.com)
   6  */
   7 
   8 #include <linux/kgdb.h>
   9 #include <linux/sched.h>
  10 #include <linux/sched/task_stack.h>
  11 #include <asm/disasm.h>
  12 #include <asm/cacheflush.h>
  13 
  14 static void to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs,
  15                         struct callee_regs *cregs)
  16 {
  17         int regno;
  18 
  19         for (regno = 0; regno <= 26; regno++)
  20                 gdb_regs[_R0 + regno] = get_reg(regno, kernel_regs, cregs);
  21 
  22         for (regno = 27; regno < GDB_MAX_REGS; regno++)
  23                 gdb_regs[regno] = 0;
  24 
  25         gdb_regs[_FP]           = kernel_regs->fp;
  26         gdb_regs[__SP]          = kernel_regs->sp;
  27         gdb_regs[_BLINK]        = kernel_regs->blink;
  28         gdb_regs[_RET]          = kernel_regs->ret;
  29         gdb_regs[_STATUS32]     = kernel_regs->status32;
  30         gdb_regs[_LP_COUNT]     = kernel_regs->lp_count;
  31         gdb_regs[_LP_END]       = kernel_regs->lp_end;
  32         gdb_regs[_LP_START]     = kernel_regs->lp_start;
  33         gdb_regs[_BTA]          = kernel_regs->bta;
  34         gdb_regs[_STOP_PC]      = kernel_regs->ret;
  35 }
  36 
  37 static void from_gdb_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs,
  38                         struct callee_regs *cregs)
  39 {
  40         int regno;
  41 
  42         for (regno = 0; regno <= 26; regno++)
  43                 set_reg(regno, gdb_regs[regno + _R0], kernel_regs, cregs);
  44 
  45         kernel_regs->fp         = gdb_regs[_FP];
  46         kernel_regs->sp         = gdb_regs[__SP];
  47         kernel_regs->blink      = gdb_regs[_BLINK];
  48         kernel_regs->ret        = gdb_regs[_RET];
  49         kernel_regs->status32   = gdb_regs[_STATUS32];
  50         kernel_regs->lp_count   = gdb_regs[_LP_COUNT];
  51         kernel_regs->lp_end     = gdb_regs[_LP_END];
  52         kernel_regs->lp_start   = gdb_regs[_LP_START];
  53         kernel_regs->bta        = gdb_regs[_BTA];
  54 }
  55 
  56 
  57 void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs)
  58 {
  59         to_gdb_regs(gdb_regs, kernel_regs, (struct callee_regs *)
  60                 current->thread.callee_reg);
  61 }
  62 
  63 void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs)
  64 {
  65         from_gdb_regs(gdb_regs, kernel_regs, (struct callee_regs *)
  66                 current->thread.callee_reg);
  67 }
  68 
  69 void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs,
  70                                  struct task_struct *task)
  71 {
  72         if (task)
  73                 to_gdb_regs(gdb_regs, task_pt_regs(task),
  74                         (struct callee_regs *) task->thread.callee_reg);
  75 }
  76 
  77 struct single_step_data_t {
  78         uint16_t opcode[2];
  79         unsigned long address[2];
  80         int is_branch;
  81         int armed;
  82 } single_step_data;
  83 
  84 static void undo_single_step(struct pt_regs *regs)
  85 {
  86         if (single_step_data.armed) {
  87                 int i;
  88 
  89                 for (i = 0; i < (single_step_data.is_branch ? 2 : 1); i++) {
  90                         memcpy((void *) single_step_data.address[i],
  91                                 &single_step_data.opcode[i],
  92                                 BREAK_INSTR_SIZE);
  93 
  94                         flush_icache_range(single_step_data.address[i],
  95                                 single_step_data.address[i] +
  96                                 BREAK_INSTR_SIZE);
  97                 }
  98                 single_step_data.armed = 0;
  99         }
 100 }
 101 
 102 static void place_trap(unsigned long address, void *save)
 103 {
 104         memcpy(save, (void *) address, BREAK_INSTR_SIZE);
 105         memcpy((void *) address, &arch_kgdb_ops.gdb_bpt_instr,
 106                 BREAK_INSTR_SIZE);
 107         flush_icache_range(address, address + BREAK_INSTR_SIZE);
 108 }
 109 
 110 static void do_single_step(struct pt_regs *regs)
 111 {
 112         single_step_data.is_branch = disasm_next_pc((unsigned long)
 113                 regs->ret, regs, (struct callee_regs *)
 114                 current->thread.callee_reg,
 115                 &single_step_data.address[0],
 116                 &single_step_data.address[1]);
 117 
 118         place_trap(single_step_data.address[0], &single_step_data.opcode[0]);
 119 
 120         if (single_step_data.is_branch) {
 121                 place_trap(single_step_data.address[1],
 122                         &single_step_data.opcode[1]);
 123         }
 124 
 125         single_step_data.armed++;
 126 }
 127 
 128 int kgdb_arch_handle_exception(int e_vector, int signo, int err_code,
 129                                char *remcomInBuffer, char *remcomOutBuffer,
 130                                struct pt_regs *regs)
 131 {
 132         unsigned long addr;
 133         char *ptr;
 134 
 135         undo_single_step(regs);
 136 
 137         switch (remcomInBuffer[0]) {
 138         case 's':
 139         case 'c':
 140                 ptr = &remcomInBuffer[1];
 141                 if (kgdb_hex2long(&ptr, &addr))
 142                         regs->ret = addr;
 143 
 144         case 'D':
 145         case 'k':
 146                 atomic_set(&kgdb_cpu_doing_single_step, -1);
 147 
 148                 if (remcomInBuffer[0] == 's') {
 149                         do_single_step(regs);
 150                         atomic_set(&kgdb_cpu_doing_single_step,
 151                                    smp_processor_id());
 152                 }
 153 
 154                 return 0;
 155         }
 156         return -1;
 157 }
 158 
 159 int kgdb_arch_init(void)
 160 {
 161         single_step_data.armed = 0;
 162         return 0;
 163 }
 164 
 165 void kgdb_trap(struct pt_regs *regs)
 166 {
 167         /* trap_s 3 is used for breakpoints that overwrite existing
 168          * instructions, while trap_s 4 is used for compiled breakpoints.
 169          *
 170          * with trap_s 3 breakpoints the original instruction needs to be
 171          * restored and continuation needs to start at the location of the
 172          * breakpoint.
 173          *
 174          * with trap_s 4 (compiled) breakpoints, continuation needs to
 175          * start after the breakpoint.
 176          */
 177         if (regs->ecr_param == 3)
 178                 instruction_pointer(regs) -= BREAK_INSTR_SIZE;
 179 
 180         kgdb_handle_exception(1, SIGTRAP, 0, regs);
 181 }
 182 
 183 void kgdb_arch_exit(void)
 184 {
 185 }
 186 
 187 void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip)
 188 {
 189         instruction_pointer(regs) = ip;
 190 }
 191 
 192 void kgdb_call_nmi_hook(void *ignored)
 193 {
 194         /* Default implementation passes get_irq_regs() but we don't */
 195         kgdb_nmicallback(raw_smp_processor_id(), NULL);
 196 }
 197 
 198 const struct kgdb_arch arch_kgdb_ops = {
 199         /* breakpoint instruction: TRAP_S 0x3 */
 200 #ifdef CONFIG_CPU_BIG_ENDIAN
 201         .gdb_bpt_instr          = {0x78, 0x7e},
 202 #else
 203         .gdb_bpt_instr          = {0x7e, 0x78},
 204 #endif
 205 };

/* [<][>][^][v][top][bottom][index][help] */