Commit 44679a4f142b69ae0c68ed815a48bbd164827281

Authored by Vijaya Kumar K
Committed by Catalin Marinas
1 parent bcf5763b0d

arm64: KGDB: Add step debugging support

Add KGDB software step debugging support for EL1 debug
in AArch64 mode.

KGDB registers step debug handler with debug monitor.
On receiving 'step' command from GDB tool, target enables
software step debugging and step address is updated in ELR.

Software Step debugging is disabled when 'continue' command
is received

Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
Reviewed-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>

Showing 1 changed file with 56 additions and 8 deletions Side-by-side Diff

arch/arm64/kernel/kgdb.c
... ... @@ -137,13 +137,26 @@
137 137  
138 138 static int compiled_break;
139 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 +
140 155 int kgdb_arch_handle_exception(int exception_vector, int signo,
141 156 int err_code, char *remcom_in_buffer,
142 157 char *remcom_out_buffer,
143 158 struct pt_regs *linux_regs)
144 159 {
145   - unsigned long addr;
146   - char *ptr;
147 160 int err;
148 161  
149 162 switch (remcom_in_buffer[0]) {
150 163  
151 164  
... ... @@ -162,15 +175,38 @@
162 175 * to the next instruction else we will just breakpoint
163 176 * over and over again.
164 177 */
165   - ptr = &remcom_in_buffer[1];
166   - if (kgdb_hex2long(&ptr, &addr))
167   - kgdb_arch_set_pc(linux_regs, addr);
168   - else if (compiled_break == 1)
169   - kgdb_arch_set_pc(linux_regs, linux_regs->pc + 4);
  178 + kgdb_arch_update_addr(linux_regs, remcom_in_buffer);
  179 + atomic_set(&kgdb_cpu_doing_single_step, -1);
  180 + kgdb_single_step = 0;
170 181  
171   - compiled_break = 0;
  182 + /*
  183 + * Received continue command, disable single step
  184 + */
  185 + if (kernel_active_single_step())
  186 + kernel_disable_single_step();
  187 +
172 188 err = 0;
173 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;
174 210 default:
175 211 err = -1;
176 212 }
... ... @@ -191,6 +227,12 @@
191 227 return 0;
192 228 }
193 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 +
194 236 static struct break_hook kgdb_brkpt_hook = {
195 237 .esr_mask = 0xffffffff,
196 238 .esr_val = DBG_ESR_VAL_BRK(KGDB_DYN_DGB_BRK_IMM),
... ... @@ -203,6 +245,10 @@
203 245 .fn = kgdb_compiled_brk_fn
204 246 };
205 247  
  248 +static struct step_hook kgdb_step_hook = {
  249 + .fn = kgdb_step_brk_fn
  250 +};
  251 +
206 252 static void kgdb_call_nmi_hook(void *ignored)
207 253 {
208 254 kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs());
... ... @@ -259,6 +305,7 @@
259 305  
260 306 register_break_hook(&kgdb_brkpt_hook);
261 307 register_break_hook(&kgdb_compiled_brkpt_hook);
  308 + register_step_hook(&kgdb_step_hook);
262 309 return 0;
263 310 }
264 311  
... ... @@ -271,6 +318,7 @@
271 318 {
272 319 unregister_break_hook(&kgdb_brkpt_hook);
273 320 unregister_break_hook(&kgdb_compiled_brkpt_hook);
  321 + unregister_step_hook(&kgdb_step_hook);
274 322 unregister_die_notifier(&kgdb_notifier);
275 323 }
276 324