@@ -137,13 +137,26 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
137137
138138static int compiled_break ;
139139
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+
140155int kgdb_arch_handle_exception (int exception_vector , int signo ,
141156 int err_code , char * remcom_in_buffer ,
142157 char * remcom_out_buffer ,
143158 struct pt_regs * linux_regs )
144159{
145- unsigned long addr ;
146- char * ptr ;
147160 int err ;
148161
149162 switch (remcom_in_buffer [0 ]) {
@@ -162,13 +175,36 @@ int kgdb_arch_handle_exception(int exception_vector, int signo,
162175 * to the next instruction else we will just breakpoint
163176 * over and over again.
164177 */
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 ;
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 ;
170202
171- compiled_break = 0 ;
203+ /*
204+ * Enable single step handling
205+ */
206+ if (!kernel_active_single_step ())
207+ kernel_enable_single_step (linux_regs );
172208 err = 0 ;
173209 break ;
174210 default :
@@ -191,6 +227,12 @@ static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int esr)
191227 return 0 ;
192228}
193229
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+
194236static struct break_hook kgdb_brkpt_hook = {
195237 .esr_mask = 0xffffffff ,
196238 .esr_val = DBG_ESR_VAL_BRK (KGDB_DYN_DGB_BRK_IMM ),
@@ -203,6 +245,10 @@ static struct break_hook kgdb_compiled_brkpt_hook = {
203245 .fn = kgdb_compiled_brk_fn
204246};
205247
248+ static struct step_hook kgdb_step_hook = {
249+ .fn = kgdb_step_brk_fn
250+ };
251+
206252static void kgdb_call_nmi_hook (void * ignored )
207253{
208254 kgdb_nmicallback (raw_smp_processor_id (), get_irq_regs ());
@@ -259,6 +305,7 @@ int kgdb_arch_init(void)
259305
260306 register_break_hook (& kgdb_brkpt_hook );
261307 register_break_hook (& kgdb_compiled_brkpt_hook );
308+ register_step_hook (& kgdb_step_hook );
262309 return 0 ;
263310}
264311
@@ -271,6 +318,7 @@ void kgdb_arch_exit(void)
271318{
272319 unregister_break_hook (& kgdb_brkpt_hook );
273320 unregister_break_hook (& kgdb_compiled_brkpt_hook );
321+ unregister_step_hook (& kgdb_step_hook );
274322 unregister_die_notifier (& kgdb_notifier );
275323}
276324
0 commit comments