- Improves error handling upon GDB connect
[openocd.git] / src / target / cortex_m3.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2006 by Magnus Lundin *
6 * lundin@mlu.mine.nu *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "replacements.h"
28
29 #include "cortex_m3.h"
30 #include "armv7m.h"
31
32 #include "register.h"
33 #include "target.h"
34 #include "target_request.h"
35 #include "log.h"
36 #include "jtag.h"
37 #include "arm_jtag.h"
38
39 #include <stdlib.h>
40 #include <string.h>
41
42 /* cli handling */
43 int cortex_m3_register_commands(struct command_context_s *cmd_ctx);
44
45 /* forward declarations */
46 void cortex_m3_unset_all_breakpoints_and_watchpoints(struct target_s *target);
47 void cortex_m3_enable_breakpoints(struct target_s *target);
48 void cortex_m3_enable_watchpoints(struct target_s *target);
49 void cortex_m3_disable_bkpts_and_wpts(struct target_s *target);
50 int cortex_m3_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
51 int cortex_m3_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
52 int cortex_m3_quit();
53 int cortex_m3_load_core_reg_u32(target_t *target, enum armv7m_regtype type, u32 num, u32 *value);
54 int cortex_m3_store_core_reg_u32(target_t *target, enum armv7m_regtype type, u32 num, u32 value);
55 int cortex_m3_target_request_data(target_t *target, u32 size, u8 *buffer);
56
57 target_type_t cortexm3_target =
58 {
59 .name = "cortex_m3",
60
61 .poll = cortex_m3_poll,
62 .arch_state = armv7m_arch_state,
63
64 .target_request_data = cortex_m3_target_request_data,
65
66 .halt = cortex_m3_halt,
67 .resume = cortex_m3_resume,
68 .step = cortex_m3_step,
69
70 .assert_reset = cortex_m3_assert_reset,
71 .deassert_reset = cortex_m3_deassert_reset,
72 .soft_reset_halt = cortex_m3_soft_reset_halt,
73 .prepare_reset_halt = cortex_m3_prepare_reset_halt,
74
75 .get_gdb_reg_list = armv7m_get_gdb_reg_list,
76
77 .read_memory = cortex_m3_read_memory,
78 .write_memory = cortex_m3_write_memory,
79 .bulk_write_memory = cortex_m3_bulk_write_memory,
80 .checksum_memory = armv7m_checksum_memory,
81
82 .run_algorithm = armv7m_run_algorithm,
83
84 .add_breakpoint = cortex_m3_add_breakpoint,
85 .remove_breakpoint = cortex_m3_remove_breakpoint,
86 .add_watchpoint = cortex_m3_add_watchpoint,
87 .remove_watchpoint = cortex_m3_remove_watchpoint,
88
89 .register_commands = cortex_m3_register_commands,
90 .target_command = cortex_m3_target_command,
91 .init_target = cortex_m3_init_target,
92 .quit = cortex_m3_quit
93 };
94
95 int cortex_m3_clear_halt(target_t *target)
96 {
97 /* get pointers to arch-specific information */
98 armv7m_common_t *armv7m = target->arch_info;
99 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
100 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
101
102 /* Read Debug Fault Status Register */
103 ahbap_read_system_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr);
104 /* Write Debug Fault Status Register to enable processing to resume ?? Try with and without this !! */
105 ahbap_write_system_atomic_u32(swjdp, NVIC_DFSR, cortex_m3->nvic_dfsr);
106 DEBUG(" NVIC_DFSR 0x%x", cortex_m3->nvic_dfsr);
107
108 return ERROR_OK;
109 }
110
111 int cortex_m3_single_step_core(target_t *target)
112 {
113 /* get pointers to arch-specific information */
114 armv7m_common_t *armv7m = target->arch_info;
115 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
116 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
117
118 if (!(cortex_m3->dcb_dhcsr & C_MASKINTS))
119 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_MASKINTS | C_HALT | C_DEBUGEN );
120 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_MASKINTS | C_STEP | C_DEBUGEN );
121 cortex_m3->dcb_dhcsr |= C_MASKINTS;
122 DEBUG(" ");
123 cortex_m3_clear_halt(target);
124
125 return ERROR_OK;
126 }
127
128 int cortex_m3_exec_opcode(target_t *target,u32 opcode, int len /* MODE, r0_invalue, &r0_outvalue */ )
129 {
130 /* get pointers to arch-specific information */
131 armv7m_common_t *armv7m = target->arch_info;
132 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
133 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
134 u32 savedram;
135 int retvalue;
136
137 ahbap_read_system_u32(swjdp, 0x20000000, &savedram);
138 ahbap_write_system_u32(swjdp, 0x20000000, opcode);
139 ahbap_write_coreregister_u32(swjdp, 0x20000000, 15);
140 cortex_m3_single_step_core(target);
141 armv7m->core_cache->reg_list[15].dirty = armv7m->core_cache->reg_list[15].valid;
142 retvalue = ahbap_write_system_atomic_u32(swjdp, 0x20000000, savedram);
143
144 return retvalue;
145 }
146
147 /* Enable interrupts */
148 int cortex_m3_cpsie(target_t *target, u32 IF)
149 {
150 return cortex_m3_exec_opcode(target, ARMV7M_T_CPSIE(IF), 2);
151 }
152
153 /* Disable interrupts */
154 int cortex_m3_cpsid(target_t *target, u32 IF)
155 {
156 return cortex_m3_exec_opcode(target, ARMV7M_T_CPSID(IF), 2);
157 }
158
159 int cortex_m3_endreset_event(target_t *target)
160 {
161 int i;
162 u32 dcb_demcr;
163
164 /* get pointers to arch-specific information */
165 armv7m_common_t *armv7m = target->arch_info;
166 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
167 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
168 cortex_m3_fp_comparator_t *fp_list = cortex_m3->fp_comparator_list;
169 cortex_m3_dwt_comparator_t *dwt_list = cortex_m3->dwt_comparator_list;
170
171 ahbap_read_system_atomic_u32(swjdp, DCB_DEMCR, &dcb_demcr);
172 DEBUG("DCB_DEMCR = 0x%8.8x",dcb_demcr);
173
174 ahbap_write_system_u32(swjdp, DCB_DCRDR, 0 );
175
176 /* Enable debug requests */
177 ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
178 if (!(cortex_m3->dcb_dhcsr & C_DEBUGEN))
179 ahbap_write_system_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN );
180 /* Enable trace and dwt */
181 ahbap_write_system_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR );
182 /* Monitor bus faults */
183 ahbap_write_system_u32(swjdp, NVIC_SHCSR, SHCSR_BUSFAULTENA );
184
185 /* Enable FPB */
186 target_write_u32(target, FP_CTRL, 3);
187
188 /* Restore FPB registers */
189 for ( i = 0; i < cortex_m3->fp_num_code + cortex_m3->fp_num_lit; i++)
190 {
191 target_write_u32(target, fp_list[i].fpcr_address, fp_list[i].fpcr_value);
192 }
193
194 /* Restore DWT registers */
195 for ( i = 0; i < cortex_m3->dwt_num_comp; i++)
196 {
197 target_write_u32(target, dwt_list[i].dwt_comparator_address, dwt_list[i].comp);
198 target_write_u32(target, dwt_list[i].dwt_comparator_address | 0x4, dwt_list[i].mask);
199 target_write_u32(target, dwt_list[i].dwt_comparator_address | 0x8, dwt_list[i].function);
200 }
201 swjdp_transaction_endcheck(swjdp);
202
203 /* Make sure working_areas are all free */
204 target_free_all_working_areas(target);
205
206 /* We are in process context */
207 armv7m_use_context(target, ARMV7M_PROCESS_CONTEXT);
208 armv7m_invalidate_core_regs(target);
209 return ERROR_OK;
210 }
211
212 int cortex_m3_examine_debug_reason(target_t *target)
213 {
214 /* get pointers to arch-specific information */
215 armv7m_common_t *armv7m = target->arch_info;
216 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
217
218 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
219 /* only check the debug reason if we don't know it already */
220
221 if ((target->debug_reason != DBG_REASON_DBGRQ)
222 && (target->debug_reason != DBG_REASON_SINGLESTEP))
223 {
224 /* INCOMPLETE */
225
226 if (cortex_m3->nvic_dfsr & DFSR_BKPT)
227 {
228 target->debug_reason = DBG_REASON_BREAKPOINT;
229 if (cortex_m3->nvic_dfsr & DFSR_DWTTRAP)
230 target->debug_reason = DBG_REASON_WPTANDBKPT;
231 }
232 else if (cortex_m3->nvic_dfsr & DFSR_DWTTRAP)
233 target->debug_reason = DBG_REASON_WATCHPOINT;
234 }
235
236 return ERROR_OK;
237 }
238
239 int cortex_m3_examine_exception_reason(target_t *target)
240 {
241 u32 shcsr, except_sr, cfsr = -1, except_ar = -1;
242
243 /* get pointers to arch-specific information */
244 armv7m_common_t *armv7m = target->arch_info;
245 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
246 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
247
248 ahbap_read_system_u32(swjdp, NVIC_SHCSR, &shcsr);
249 switch (armv7m->exception_number)
250 {
251 case 2: /* NMI */
252 break;
253 case 3: /* Hard Fault */
254 ahbap_read_system_atomic_u32(swjdp, NVIC_HFSR, &except_sr);
255 if (except_sr & 0x40000000)
256 {
257 ahbap_read_system_u32(swjdp, NVIC_CFSR, &cfsr);
258 }
259 break;
260 case 4: /* Memory Management */
261 ahbap_read_system_u32(swjdp, NVIC_CFSR, &except_sr);
262 ahbap_read_system_u32(swjdp, NVIC_MMFAR, &except_ar);
263 break;
264 case 5: /* Bus Fault */
265 ahbap_read_system_u32(swjdp, NVIC_CFSR, &except_sr);
266 ahbap_read_system_u32(swjdp, NVIC_BFAR, &except_ar);
267 break;
268 case 6: /* Usage Fault */
269 ahbap_read_system_u32(swjdp, NVIC_CFSR, &except_sr);
270 break;
271 case 11: /* SVCall */
272 break;
273 case 12: /* Debug Monitor */
274 ahbap_read_system_u32(swjdp, NVIC_DFSR, &except_sr);
275 break;
276 case 14: /* PendSV */
277 break;
278 case 15: /* SysTick */
279 break;
280 default:
281 except_sr = 0;
282 break;
283 }
284 swjdp_transaction_endcheck(swjdp);
285 DEBUG("%s SHCSR 0x%x, SR 0x%x, CFSR 0x%x, AR 0x%x", armv7m_exception_string(armv7m->exception_number), \
286 shcsr, except_sr, cfsr, except_ar);
287 return ERROR_OK;
288 }
289
290 int cortex_m3_debug_entry(target_t *target)
291 {
292 int i;
293 u32 xPSR;
294 int retval;
295
296 /* get pointers to arch-specific information */
297 armv7m_common_t *armv7m = target->arch_info;
298 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
299 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
300
301 DEBUG(" ");
302 if (armv7m->pre_debug_entry)
303 armv7m->pre_debug_entry(target);
304
305 cortex_m3_clear_halt(target);
306 ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
307
308 if ((retval = armv7m->examine_debug_reason(target)) != ERROR_OK)
309 return retval;
310
311 /* Examine target state and mode */
312 /* First load register acessible through core debug port*/
313 for (i = 0; i < ARMV7M_PRIMASK; i++)
314 {
315 if (!armv7m->core_cache->reg_list[i].valid)
316 armv7m->read_core_reg(target, i);
317 }
318
319 xPSR = buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32);
320
321 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec*/
322 if (xPSR & 0xf00)
323 {
324 armv7m->core_cache->reg_list[ARMV7M_xPSR].dirty = armv7m->core_cache->reg_list[ARMV7M_xPSR].valid;
325 cortex_m3_store_core_reg_u32(target, ARMV7M_REGISTER_CORE_GP, 16, xPSR &~ 0xff);
326 }
327
328
329 /* Now we can load SP core registers */
330 for (i = ARMV7M_PRIMASK; i < ARMV7NUMCOREREGS; i++)
331 {
332 if (!armv7m->core_cache->reg_list[i].valid)
333 armv7m->read_core_reg(target, i);
334 }
335
336 /* Are we in an exception handler */
337 armv7m->core_mode = (xPSR & 0x1FF) ? ARMV7M_MODE_HANDLER : ARMV7M_MODE_THREAD;
338 armv7m->exception_number = xPSR & 0x1FF;
339 if (armv7m->exception_number)
340 {
341 cortex_m3_examine_exception_reason(target);
342 }
343
344 DEBUG("entered debug state at PC 0x%x, target->state: %s ", *(u32*)(armv7m->core_cache->reg_list[15].value), target_state_strings[target->state]);
345
346 if (armv7m->post_debug_entry)
347 armv7m->post_debug_entry(target);
348
349 return ERROR_OK;
350 }
351
352 int cortex_m3_poll(target_t *target)
353 {
354 int retval;
355 u32 prev_target_state = target->state;
356
357 /* get pointers to arch-specific information */
358 armv7m_common_t *armv7m = target->arch_info;
359 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
360 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
361
362 /* Read from Debug Halting Control and Status Register */
363 retval = ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
364 if (retval != ERROR_OK)
365 {
366 target->state = TARGET_UNKNOWN;
367 return retval;
368 }
369
370 if (cortex_m3->dcb_dhcsr & S_RESET_ST)
371 {
372 /* check if still in reset */
373 ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
374
375 if (cortex_m3->dcb_dhcsr & S_RESET_ST)
376 {
377 target->state = TARGET_RESET;
378 return ERROR_OK;
379 }
380 }
381
382 if (target->state == TARGET_RESET)
383 {
384 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
385 DEBUG("Exit from reset with dcb_dhcsr 0x%x", cortex_m3->dcb_dhcsr);
386 cortex_m3_endreset_event(target);
387 target->state = TARGET_RUNNING;
388 prev_target_state = TARGET_RUNNING;
389 }
390
391 if (cortex_m3->dcb_dhcsr & S_HALT)
392 {
393 target->state = TARGET_HALTED;
394
395 if ((prev_target_state == TARGET_RUNNING) || (prev_target_state == TARGET_RESET))
396 {
397 if ((retval = cortex_m3_debug_entry(target)) != ERROR_OK)
398 return retval;
399
400 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
401 }
402 if (prev_target_state == TARGET_DEBUG_RUNNING)
403 {
404 DEBUG(" ");
405 if ((retval = cortex_m3_debug_entry(target)) != ERROR_OK)
406 return retval;
407
408 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
409 }
410 }
411
412 /*
413 if (cortex_m3->dcb_dhcsr & S_SLEEP)
414 target->state = TARGET_SLEEP;
415 */
416
417 /* Read Debug Fault Status Register, added to figure out the lockup when running flashtest.script */
418 ahbap_read_system_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr);
419 DEBUG("dcb_dhcsr 0x%x, nvic_dfsr 0x%x, target->state: %s", cortex_m3->dcb_dhcsr, cortex_m3->nvic_dfsr, target_state_strings[target->state]);
420 return ERROR_OK;
421 }
422
423 int cortex_m3_halt(target_t *target)
424 {
425 /* get pointers to arch-specific information */
426 armv7m_common_t *armv7m = target->arch_info;
427 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
428 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
429
430 DEBUG("target->state: %s", target_state_strings[target->state]);
431
432 if (target->state == TARGET_HALTED)
433 {
434 WARNING("target was already halted");
435 return ERROR_OK;
436 }
437
438 if (target->state == TARGET_UNKNOWN)
439 {
440 WARNING("target was in unknown state when halt was requested");
441 }
442
443 if (target->state == TARGET_RESET)
444 {
445 if ((jtag_reset_config & RESET_SRST_PULLS_TRST) && jtag_srst)
446 {
447 ERROR("can't request a halt while in reset if nSRST pulls nTRST");
448 return ERROR_TARGET_FAILURE;
449 }
450 else
451 {
452 /* we came here in a reset_halt or reset_init sequence
453 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
454 */
455 target->debug_reason = DBG_REASON_DBGRQ;
456
457 return ERROR_OK;
458 }
459 }
460
461 /* Write to Debug Halting Control and Status Register */
462 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN | C_HALT );
463
464 target->debug_reason = DBG_REASON_DBGRQ;
465
466 return ERROR_OK;
467 }
468
469 int cortex_m3_soft_reset_halt(struct target_s *target)
470 {
471 /* get pointers to arch-specific information */
472 armv7m_common_t *armv7m = target->arch_info;
473 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
474 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
475 u32 dcb_dhcsr = 0;
476 int retval, timeout = 0;
477
478 /* Check that we are using process_context, or change and print warning */
479 if (armv7m_get_context(target) != ARMV7M_PROCESS_CONTEXT)
480 {
481 DEBUG("Changing to process contex registers");
482 armv7m_use_context(target, ARMV7M_PROCESS_CONTEXT);
483 }
484
485 /* Enter debug state on reset, cf. end_reset_event() */
486 ahbap_write_system_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET );
487
488 /* Request a reset */
489 ahbap_write_system_atomic_u32(swjdp, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_VECTRESET );
490 target->state = TARGET_RESET;
491
492 /* registers are now invalid */
493 armv7m_invalidate_core_regs(target);
494
495 while (timeout < 100)
496 {
497 retval = ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &dcb_dhcsr);
498 if (retval == ERROR_OK)
499 {
500 ahbap_read_system_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr);
501 if ((dcb_dhcsr & S_HALT) && (cortex_m3->nvic_dfsr & DFSR_VCATCH))
502 {
503 DEBUG("system reset-halted, dcb_dhcsr 0x%x, nvic_dfsr 0x%x", dcb_dhcsr, cortex_m3->nvic_dfsr);
504 cortex_m3_poll(target);
505 return ERROR_OK;
506 }
507 else
508 DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%x, %i ms", dcb_dhcsr, timeout);
509 }
510 timeout++;
511 usleep(1000);
512 }
513
514 return ERROR_OK;
515 }
516
517 int cortex_m3_prepare_reset_halt(struct target_s *target)
518 {
519 armv7m_common_t *armv7m = target->arch_info;
520 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
521 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
522 u32 dcb_demcr, dcb_dhcsr;
523
524 /* Enable debug requests */
525 ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
526 if (!(cortex_m3->dcb_dhcsr & C_DEBUGEN))
527 ahbap_write_system_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN );
528
529 /* Enter debug state on reset, cf. end_reset_event() */
530 ahbap_write_system_atomic_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET );
531
532 ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &dcb_dhcsr);
533 ahbap_read_system_atomic_u32(swjdp, DCB_DEMCR, &dcb_demcr);
534 DEBUG("dcb_dhcsr 0x%x, dcb_demcr 0x%x, ", dcb_dhcsr, dcb_demcr);
535
536 return ERROR_OK;
537 }
538
539 int cortex_m3_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution)
540 {
541 /* get pointers to arch-specific information */
542 armv7m_common_t *armv7m = target->arch_info;
543 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
544 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
545 breakpoint_t *breakpoint = NULL;
546 u32 dcb_dhcsr, resume_pc;
547
548 if (target->state != TARGET_HALTED)
549 {
550 WARNING("target not halted");
551 return ERROR_TARGET_NOT_HALTED;
552 }
553
554 if (!debug_execution)
555 {
556 /* Check that we are using process_context, or change and print warning */
557 if (armv7m_get_context(target) != ARMV7M_PROCESS_CONTEXT)
558 {
559 WARNING("Incorrect context in resume");
560 armv7m_use_context(target, ARMV7M_PROCESS_CONTEXT);
561 }
562
563 target_free_all_working_areas(target);
564 cortex_m3_enable_breakpoints(target);
565 cortex_m3_enable_watchpoints(target);
566
567 /* TODOLATER Interrupt handling/disable for debug execution, cache ... ... */
568 }
569
570 dcb_dhcsr = DBGKEY | C_DEBUGEN;
571 if (debug_execution)
572 {
573 /* Check that we are using debug_context, or change and print warning */
574 if (armv7m_get_context(target) != ARMV7M_DEBUG_CONTEXT)
575 {
576 WARNING("Incorrect context in debug_exec resume");
577 armv7m_use_context(target, ARMV7M_DEBUG_CONTEXT);
578 }
579 /* Disable interrupts */
580 /*
581 We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
582 This is probably the same inssue as Cortex-M3 Errata 377493:
583 C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken.
584 */
585 buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_PRIMASK].value, 0, 32, 1);
586 /* Make sure we are in Thumb mode */
587 buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32,
588 buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32) | (1<<24));
589 }
590
591 /* current = 1: continue on current pc, otherwise continue at <address> */
592 if (!current)
593 {
594 buf_set_u32(armv7m->core_cache->reg_list[15].value, 0, 32, address);
595 armv7m->core_cache->reg_list[15].dirty = 1;
596 armv7m->core_cache->reg_list[15].valid = 1;
597 }
598
599 resume_pc = buf_get_u32(armv7m->core_cache->reg_list[15].value, 0, 32);
600
601 armv7m_restore_context(target);
602
603 /* the front-end may request us not to handle breakpoints */
604 if (handle_breakpoints)
605 {
606 /* Single step past breakpoint at current address */
607 if ((breakpoint = breakpoint_find(target, resume_pc)))
608 {
609 DEBUG("unset breakpoint at 0x%8.8x", breakpoint->address);
610 cortex_m3_unset_breakpoint(target, breakpoint);
611 cortex_m3_single_step_core(target);
612 cortex_m3_set_breakpoint(target, breakpoint);
613 }
614 }
615
616 /* Set/Clear C_MASKINTS in a separate operation */
617 if ((cortex_m3->dcb_dhcsr & C_MASKINTS) != (dcb_dhcsr & C_MASKINTS))
618 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, dcb_dhcsr | C_HALT );
619
620 /* Restart core */
621 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, dcb_dhcsr );
622 target->debug_reason = DBG_REASON_NOTHALTED;
623
624 /* registers are now invalid */
625 armv7m_invalidate_core_regs(target);
626 if (!debug_execution)
627 {
628 target->state = TARGET_RUNNING;
629 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
630 DEBUG("target resumed at 0x%x",resume_pc);
631 }
632 else
633 {
634 target->state = TARGET_DEBUG_RUNNING;
635 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
636 DEBUG("target debug resumed at 0x%x",resume_pc);
637 }
638
639 return ERROR_OK;
640 }
641
642 /* int irqstepcount=0; */
643 int cortex_m3_step(struct target_s *target, int current, u32 address, int handle_breakpoints)
644 {
645 /* get pointers to arch-specific information */
646 armv7m_common_t *armv7m = target->arch_info;
647 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
648 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
649 breakpoint_t *breakpoint = NULL;
650
651 if (target->state != TARGET_HALTED)
652 {
653 WARNING("target not halted");
654 return ERROR_TARGET_NOT_HALTED;
655 }
656
657 /* Check that we are using process_context, or change and print warning */
658 if (armv7m_get_context(target) != ARMV7M_PROCESS_CONTEXT)
659 {
660 WARNING("Incorrect context in step, must be process");
661 armv7m_use_context(target, ARMV7M_PROCESS_CONTEXT);
662 }
663
664 /* current = 1: continue on current pc, otherwise continue at <address> */
665 if (!current)
666 buf_set_u32(armv7m->core_cache->reg_list[15].value, 0, 32, address);
667
668 /* the front-end may request us not to handle breakpoints */
669 if (handle_breakpoints)
670 if ((breakpoint = breakpoint_find(target, buf_get_u32(armv7m->core_cache->reg_list[15].value, 0, 32))))
671 cortex_m3_unset_breakpoint(target, breakpoint);
672
673 target->debug_reason = DBG_REASON_SINGLESTEP;
674
675 armv7m_restore_context(target);
676
677 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
678
679 if (cortex_m3->dcb_dhcsr & C_MASKINTS)
680 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN );
681 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY| C_STEP | C_DEBUGEN);
682 ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
683
684 /* If we run in process context then registers are now invalid */
685 if (armv7m_get_context(target) == ARMV7M_PROCESS_CONTEXT)
686 armv7m_invalidate_core_regs(target);
687
688 if (breakpoint)
689 cortex_m3_set_breakpoint(target, breakpoint);
690
691 DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3->dcb_dhcsr, cortex_m3->nvic_icsr);
692
693 cortex_m3_debug_entry(target);
694 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
695
696 DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3->dcb_dhcsr, cortex_m3->nvic_icsr);
697 return ERROR_OK;
698 }
699
700 int cortex_m3_assert_reset(target_t *target)
701 {
702 int retval;
703 armv7m_common_t *armv7m = target->arch_info;
704 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
705 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
706
707 DEBUG("target->state: %s", target_state_strings[target->state]);
708
709 ahbap_write_system_u32(swjdp, DCB_DCRDR, 0 );
710
711 if (target->reset_mode == RESET_RUN)
712 {
713 /* Set/Clear C_MASKINTS in a separate operation */
714 if (cortex_m3->dcb_dhcsr & C_MASKINTS)
715 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN | C_HALT );
716
717 cortex_m3_clear_halt(target);
718
719 /* Enter debug state on reset, cf. end_reset_event() */
720 ahbap_write_system_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN );
721 ahbap_write_system_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR);
722 }
723
724 if (target->state == TARGET_HALTED || target->state == TARGET_UNKNOWN)
725 {
726 /* assert SRST and TRST */
727 /* system would get ouf sync if we didn't reset test-logic, too */
728 if ((retval = jtag_add_reset(1, 1)) != ERROR_OK)
729 {
730 if (retval == ERROR_JTAG_RESET_CANT_SRST)
731 {
732 WARNING("can't assert srst");
733 return retval;
734 }
735 else
736 {
737 ERROR("unknown error");
738 exit(-1);
739 }
740 }
741 jtag_add_sleep(5000);
742 if ((retval = jtag_add_reset(0, 1)) != ERROR_OK)
743 {
744 if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST)
745 {
746 WARNING("srst resets test logic, too");
747 retval = jtag_add_reset(1, 1);
748 }
749 }
750 }
751 else
752 {
753 if ((retval = jtag_add_reset(0, 1)) != ERROR_OK)
754 {
755 if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST)
756 {
757 WARNING("srst resets test logic, too");
758 retval = jtag_add_reset(1, 1);
759 }
760
761 if (retval == ERROR_JTAG_RESET_CANT_SRST)
762 {
763 WARNING("can't assert srsrt");
764 return retval;
765 }
766 else if (retval != ERROR_OK)
767 {
768 ERROR("unknown error");
769 exit(-1);
770 }
771 }
772 }
773
774 target->state = TARGET_RESET;
775 jtag_add_sleep(50000);
776
777 armv7m_use_context(target, ARMV7M_PROCESS_CONTEXT);
778 armv7m_invalidate_core_regs(target);
779
780 return ERROR_OK;
781 }
782
783 int cortex_m3_deassert_reset(target_t *target)
784 {
785 DEBUG("target->state: %s", target_state_strings[target->state]);
786
787 /* deassert reset lines */
788 jtag_add_reset(0, 0);
789
790 return ERROR_OK;
791 }
792
793 void cortex_m3_unset_all_breakpoints_and_watchpoints(struct target_s *target)
794 {
795
796 }
797
798 void cortex_m3_enable_breakpoints(struct target_s *target)
799 {
800 breakpoint_t *breakpoint = target->breakpoints;
801
802 /* set any pending breakpoints */
803 while (breakpoint)
804 {
805 if (breakpoint->set == 0)
806 cortex_m3_set_breakpoint(target, breakpoint);
807 breakpoint = breakpoint->next;
808 }
809 }
810
811 int cortex_m3_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
812 {
813 int fp_num=0;
814 u32 hilo;
815
816 /* get pointers to arch-specific information */
817 armv7m_common_t *armv7m = target->arch_info;
818 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
819
820 cortex_m3_fp_comparator_t * comparator_list = cortex_m3->fp_comparator_list;
821
822 if (breakpoint->set)
823 {
824 WARNING("breakpoint already set");
825 return ERROR_OK;
826 }
827
828 if (cortex_m3->auto_bp_type)
829 {
830 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
831 }
832
833 if (breakpoint->type == BKPT_HARD)
834 {
835 while(comparator_list[fp_num].used && (fp_num < cortex_m3->fp_num_code))
836 fp_num++;
837 if (fp_num >= cortex_m3->fp_num_code)
838 {
839 DEBUG("ERROR Can not find free FP Comparator");
840 WARNING("ERROR Can not find free FP Comparator");
841 exit(-1);
842 }
843 breakpoint->set = fp_num + 1;
844 hilo = (breakpoint->address & 0x2) ? FPCR_REPLACE_BKPT_HIGH : FPCR_REPLACE_BKPT_LOW;
845 comparator_list[fp_num].used = 1;
846 comparator_list[fp_num].fpcr_value = (breakpoint->address & 0x1FFFFFFC) | hilo | 1;
847 target_write_u32(target, comparator_list[fp_num].fpcr_address, comparator_list[fp_num].fpcr_value);
848 DEBUG("fpc_num %i fpcr_value 0x%x", fp_num, comparator_list[fp_num].fpcr_value);
849 }
850 else if (breakpoint->type == BKPT_SOFT)
851 {
852 u8 code[4];
853 buf_set_u32(code, 0, 32, ARMV7M_T_BKPT(0x11));
854 target->type->read_memory(target, breakpoint->address & 0xFFFFFFFE, breakpoint->length, 1, breakpoint->orig_instr);
855 target->type->write_memory(target, breakpoint->address & 0xFFFFFFFE, breakpoint->length, 1, code);
856 breakpoint->set = 0x11; /* Any nice value but 0 */
857 }
858
859 return ERROR_OK;
860 }
861
862 int cortex_m3_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
863 {
864 /* get pointers to arch-specific information */
865 armv7m_common_t *armv7m = target->arch_info;
866 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
867 cortex_m3_fp_comparator_t * comparator_list = cortex_m3->fp_comparator_list;
868
869 if (!breakpoint->set)
870 {
871 WARNING("breakpoint not set");
872 return ERROR_OK;
873 }
874
875 if (breakpoint->type == BKPT_HARD)
876 {
877 int fp_num = breakpoint->set - 1;
878 if ((fp_num < 0) || (fp_num >= cortex_m3->fp_num_code))
879 {
880 DEBUG("Invalid FP Comparator number in breakpoint");
881 return ERROR_OK;
882 }
883 comparator_list[fp_num].used = 0;
884 comparator_list[fp_num].fpcr_value = 0;
885 target_write_u32(target, comparator_list[fp_num].fpcr_address, comparator_list[fp_num].fpcr_value);
886 }
887 else
888 {
889 /* restore original instruction (kept in target endianness) */
890 if (breakpoint->length == 4)
891 {
892 target->type->write_memory(target, breakpoint->address & 0xFFFFFFFE, 4, 1, breakpoint->orig_instr);
893 }
894 else
895 {
896 target->type->write_memory(target, breakpoint->address & 0xFFFFFFFE, 2, 1, breakpoint->orig_instr);
897 }
898 }
899 breakpoint->set = 0;
900
901 return ERROR_OK;
902 }
903
904 int cortex_m3_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
905 {
906 /* get pointers to arch-specific information */
907 armv7m_common_t *armv7m = target->arch_info;
908 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
909
910 if (cortex_m3->auto_bp_type)
911 {
912 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
913 }
914
915 if ((breakpoint->type == BKPT_HARD) && (breakpoint->address >= 0x20000000))
916 {
917 INFO("flash patch comparator requested outside code memory region");
918 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
919 }
920
921 if ((breakpoint->type == BKPT_SOFT) && (breakpoint->address < 0x20000000))
922 {
923 INFO("soft breakpoint requested in code (flash) memory region");
924 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
925 }
926
927 if ((breakpoint->type == BKPT_HARD) && (cortex_m3->fp_code_available < 1))
928 {
929 INFO("no flash patch comparator unit available for hardware breakpoint");
930 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
931 }
932
933 if ((breakpoint->length != 2))
934 {
935 INFO("only breakpoints of two bytes length supported");
936 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
937 }
938
939 if (breakpoint->type == BKPT_HARD)
940 cortex_m3->fp_code_available--;
941 cortex_m3_set_breakpoint(target, breakpoint);
942
943 return ERROR_OK;
944 }
945
946 int cortex_m3_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
947 {
948 /* get pointers to arch-specific information */
949 armv7m_common_t *armv7m = target->arch_info;
950 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
951
952 if (target->state != TARGET_HALTED)
953 {
954 WARNING("target not halted");
955 return ERROR_TARGET_NOT_HALTED;
956 }
957
958 if (cortex_m3->auto_bp_type)
959 {
960 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
961 }
962
963 if (breakpoint->set)
964 {
965 cortex_m3_unset_breakpoint(target, breakpoint);
966 }
967
968 if (breakpoint->type == BKPT_HARD)
969 cortex_m3->fp_code_available++;
970
971 return ERROR_OK;
972 }
973
974 int cortex_m3_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
975 {
976 int dwt_num=0;
977 u32 mask, temp;
978
979 /* get pointers to arch-specific information */
980 armv7m_common_t *armv7m = target->arch_info;
981 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
982 cortex_m3_dwt_comparator_t * comparator_list = cortex_m3->dwt_comparator_list;
983
984 if (watchpoint->set)
985 {
986 WARNING("watchpoint already set");
987 return ERROR_OK;
988 }
989
990 if (watchpoint->mask == 0xffffffffu)
991 {
992 while(comparator_list[dwt_num].used && (dwt_num < cortex_m3->dwt_num_comp))
993 dwt_num++;
994 if (dwt_num >= cortex_m3->dwt_num_comp)
995 {
996 DEBUG("ERROR Can not find free DWT Comparator");
997 WARNING("ERROR Can not find free DWT Comparator");
998 return -1;
999 }
1000 watchpoint->set = dwt_num + 1;
1001 mask = 0;
1002 temp = watchpoint->length;
1003 while (temp > 1)
1004 {
1005 temp = temp / 2;
1006 mask++;
1007 }
1008 comparator_list[dwt_num].used = 1;
1009 comparator_list[dwt_num].comp = watchpoint->address;
1010 comparator_list[dwt_num].mask = mask;
1011 comparator_list[dwt_num].function = watchpoint->rw + 5;
1012 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address, comparator_list[dwt_num].comp);
1013 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address|0x4, comparator_list[dwt_num].mask);
1014 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address|0x8, comparator_list[dwt_num].function);
1015 DEBUG("dwt_num %i 0x%x 0x%x 0x%x", dwt_num, comparator_list[dwt_num].comp, comparator_list[dwt_num].mask, comparator_list[dwt_num].function);
1016 }
1017 else
1018 {
1019 WARNING("Cannot watch data values"); /* Move this test to add_watchpoint */
1020 return ERROR_OK;
1021 }
1022
1023 return ERROR_OK;
1024
1025 }
1026
1027 int cortex_m3_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1028 {
1029 /* get pointers to arch-specific information */
1030 armv7m_common_t *armv7m = target->arch_info;
1031 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1032 cortex_m3_dwt_comparator_t * comparator_list = cortex_m3->dwt_comparator_list;
1033 int dwt_num;
1034
1035 if (!watchpoint->set)
1036 {
1037 WARNING("watchpoint not set");
1038 return ERROR_OK;
1039 }
1040
1041 dwt_num = watchpoint->set - 1;
1042
1043 if ((dwt_num < 0) || (dwt_num >= cortex_m3->dwt_num_comp))
1044 {
1045 DEBUG("Invalid DWT Comparator number in watchpoint");
1046 return ERROR_OK;
1047 }
1048 comparator_list[dwt_num].used = 0;
1049 comparator_list[dwt_num].function = 0;
1050 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address|0x8, comparator_list[dwt_num].function);
1051
1052 watchpoint->set = 0;
1053
1054 return ERROR_OK;
1055 }
1056
1057 int cortex_m3_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1058 {
1059 /* get pointers to arch-specific information */
1060 armv7m_common_t *armv7m = target->arch_info;
1061 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1062
1063 if (target->state != TARGET_HALTED)
1064 {
1065 WARNING("target not halted");
1066 return ERROR_TARGET_NOT_HALTED;
1067 }
1068
1069 if (cortex_m3->dwt_comp_available < 1)
1070 {
1071 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1072 }
1073
1074 if ((watchpoint->length != 1) && (watchpoint->length != 2) && (watchpoint->length != 4))
1075 {
1076 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1077 }
1078
1079 cortex_m3->dwt_comp_available--;
1080
1081 return ERROR_OK;
1082 }
1083
1084 int cortex_m3_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1085 {
1086 /* get pointers to arch-specific information */
1087 armv7m_common_t *armv7m = target->arch_info;
1088 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1089
1090 if (target->state != TARGET_HALTED)
1091 {
1092 WARNING("target not halted");
1093 return ERROR_TARGET_NOT_HALTED;
1094 }
1095
1096 if (watchpoint->set)
1097 {
1098 cortex_m3_unset_watchpoint(target, watchpoint);
1099 }
1100
1101 cortex_m3->dwt_comp_available++;
1102
1103 return ERROR_OK;
1104 }
1105
1106 void cortex_m3_enable_watchpoints(struct target_s *target)
1107 {
1108 watchpoint_t *watchpoint = target->watchpoints;
1109
1110 /* set any pending watchpoints */
1111 while (watchpoint)
1112 {
1113 if (watchpoint->set == 0)
1114 cortex_m3_set_watchpoint(target, watchpoint);
1115 watchpoint = watchpoint->next;
1116 }
1117 }
1118
1119 int cortex_m3_load_core_reg_u32(struct target_s *target, enum armv7m_regtype type, u32 num, u32 * value)
1120 {
1121 int retval;
1122 /* get pointers to arch-specific information */
1123 armv7m_common_t *armv7m = target->arch_info;
1124 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1125 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1126
1127 if ((type == ARMV7M_REGISTER_CORE_GP) && (num <= ARMV7M_PSP))
1128 {
1129 /* read a normal core register */
1130 retval = ahbap_read_coreregister_u32(swjdp, value, num);
1131
1132 if (retval != ERROR_OK)
1133 {
1134 ERROR("JTAG failure %i",retval);
1135 return ERROR_JTAG_DEVICE_ERROR;
1136 }
1137 /* DEBUG("load from core reg %i value 0x%x",num,*value); */
1138 }
1139 else if (type == ARMV7M_REGISTER_CORE_SP) /* Special purpose core register */
1140 {
1141 /* read other registers */
1142 /* cortex_m3_MRS(struct target_s *target, int num, u32* value) */
1143 u32 savedram;
1144 u32 SYSm;
1145 u32 instr;
1146 SYSm = num & 0x1F;
1147 ahbap_read_system_u32(swjdp, 0x20000000, &savedram);
1148 instr = ARMV7M_T_MRS(0, SYSm);
1149 ahbap_write_system_u32(swjdp, 0x20000000, ARMV7M_T_MRS(0, SYSm));
1150 ahbap_write_coreregister_u32(swjdp, 0x20000000, 15);
1151 cortex_m3_single_step_core(target);
1152 ahbap_read_coreregister_u32(swjdp, value, 0);
1153 armv7m->core_cache->reg_list[0].dirty = armv7m->core_cache->reg_list[0].valid;
1154 armv7m->core_cache->reg_list[15].dirty = armv7m->core_cache->reg_list[15].valid;
1155 ahbap_write_system_u32(swjdp, 0x20000000, savedram);
1156 swjdp_transaction_endcheck(swjdp);
1157 DEBUG("load from special reg %i value 0x%x", SYSm, *value);
1158 }
1159 else return ERROR_INVALID_ARGUMENTS;
1160
1161 return ERROR_OK;
1162 }
1163
1164 int cortex_m3_store_core_reg_u32(struct target_s *target, enum armv7m_regtype type, u32 num, u32 value)
1165 {
1166 int retval;
1167
1168 /* get pointers to arch-specific information */
1169 armv7m_common_t *armv7m = target->arch_info;
1170 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1171 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1172
1173 if ((type == ARMV7M_REGISTER_CORE_GP) && (num <= ARMV7M_PSP))
1174 {
1175 retval = ahbap_write_coreregister_u32(swjdp, value, num);
1176 if (retval != ERROR_OK)
1177 {
1178 ERROR("JTAG failure %i", retval);
1179 armv7m->core_cache->reg_list[num].dirty = armv7m->core_cache->reg_list[num].valid;
1180 return ERROR_JTAG_DEVICE_ERROR;
1181 }
1182 DEBUG("write core reg %i value 0x%x", num, value);
1183 }
1184 else if (type == ARMV7M_REGISTER_CORE_SP) /* Special purpose core register */
1185 {
1186 /* write other registers */
1187 u32 savedram , tempr0;
1188 u32 SYSm;
1189 u32 instr;
1190 SYSm = num & 0x1F;
1191 ahbap_read_system_u32(swjdp, 0x20000000, &savedram);
1192 instr = ARMV7M_T_MSR(SYSm, 0);
1193 ahbap_write_system_u32(swjdp, 0x20000000, ARMV7M_T_MSR(SYSm, 0));
1194 ahbap_read_coreregister_u32(swjdp, &tempr0, 0);
1195 ahbap_write_coreregister_u32(swjdp, value, 0);
1196 ahbap_write_coreregister_u32(swjdp, 0x20000000, 15);
1197 cortex_m3_single_step_core(target);
1198 ahbap_write_coreregister_u32(swjdp, tempr0, 0);
1199 armv7m->core_cache->reg_list[15].dirty = armv7m->core_cache->reg_list[15].valid;
1200 ahbap_write_system_u32(swjdp, 0x20000000, savedram);
1201 swjdp_transaction_endcheck(swjdp);
1202 DEBUG("write special reg %i value 0x%x ", SYSm, value);
1203 }
1204 else return ERROR_INVALID_ARGUMENTS;
1205
1206 return ERROR_OK;
1207 }
1208
1209 int cortex_m3_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1210 {
1211 /* get pointers to arch-specific information */
1212 armv7m_common_t *armv7m = target->arch_info;
1213 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1214 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1215
1216 /* sanitize arguments */
1217 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1218 return ERROR_INVALID_ARGUMENTS;
1219
1220 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
1221 return ERROR_TARGET_UNALIGNED_ACCESS;
1222
1223 /* Is not optimal, autoincrement of tar should be used ( ahbap_block_read and CSW_ADDRINC_SINGLE ) */
1224 switch (size)
1225 {
1226 case 4:
1227 /* TODOLATER Check error return value ! */
1228 {
1229 ahbap_read_buf(swjdp, buffer, 4 * count, address);
1230 }
1231 break;
1232 case 2:
1233 {
1234 ahbap_read_buf_u16(swjdp, buffer, 2 * count, address);
1235 }
1236 break;
1237 case 1:
1238 {
1239 ahbap_read_buf(swjdp, buffer, count, address);
1240 }
1241 break;
1242 default:
1243 ERROR("BUG: we shouldn't get here");
1244 exit(-1);
1245 }
1246
1247 return ERROR_OK;
1248 }
1249
1250 int cortex_m3_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1251 {
1252 /* get pointers to arch-specific information */
1253 armv7m_common_t *armv7m = target->arch_info;
1254 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1255 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1256
1257 /* sanitize arguments */
1258 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1259 return ERROR_INVALID_ARGUMENTS;
1260
1261 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
1262 return ERROR_TARGET_UNALIGNED_ACCESS;
1263
1264 switch (size)
1265 {
1266 case 4:
1267 /* TODOLATER Check error return value ! */
1268 {
1269 ahbap_write_buf(swjdp, buffer, 4 * count, address);
1270 }
1271 break;
1272 case 2:
1273 {
1274 ahbap_write_buf_u16(swjdp, buffer, 2 * count, address);
1275 }
1276 break;
1277 case 1:
1278 {
1279 ahbap_write_buf(swjdp, buffer, count, address);
1280 }
1281 break;
1282 default:
1283 ERROR("BUG: we shouldn't get here");
1284 exit(-1);
1285 }
1286
1287 return ERROR_OK;
1288 }
1289
1290 int cortex_m3_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer)
1291 {
1292 cortex_m3_write_memory(target, address, 4, count, buffer);
1293
1294 return ERROR_OK;
1295 }
1296
1297 void cortex_m3_build_reg_cache(target_t *target)
1298 {
1299 armv7m_build_reg_cache(target);
1300 }
1301
1302 int cortex_m3_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
1303 {
1304 u32 cpuid, fpcr, dwtcr, ictr;
1305 int i;
1306
1307 /* get pointers to arch-specific information */
1308 armv7m_common_t *armv7m = target->arch_info;
1309 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1310 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1311
1312 cortex_m3_build_reg_cache(target);
1313 ahbap_debugport_init(swjdp);
1314
1315 /* Read from Device Identification Registers */
1316 target_read_u32(target, CPUID, &cpuid);
1317 if (((cpuid >> 4) & 0xc3f) == 0xc23)
1318 DEBUG("CORTEX-M3 processor detected");
1319 DEBUG("cpuid: 0x%8.8x", cpuid);
1320
1321 target_read_u32(target, NVIC_ICTR, &ictr);
1322 cortex_m3->intlinesnum = (ictr & 0x1F) + 1;
1323 cortex_m3->intsetenable = calloc(cortex_m3->intlinesnum, 4);
1324 for (i = 0; i < cortex_m3->intlinesnum; i++)
1325 {
1326 target_read_u32(target, NVIC_ISE0 + 4 * i, cortex_m3->intsetenable + i);
1327 DEBUG("interrupt enable[%i] = 0x%8.8x", i, cortex_m3->intsetenable[i]);
1328 }
1329
1330 /* Setup FPB */
1331 target_read_u32(target, FP_CTRL, &fpcr);
1332 cortex_m3->auto_bp_type = 1;
1333 cortex_m3->fp_num_code = (fpcr >> 4) & 0xF;
1334 cortex_m3->fp_num_lit = (fpcr >> 8) & 0xF;
1335 cortex_m3->fp_code_available = cortex_m3->fp_num_code;
1336 cortex_m3->fp_comparator_list = calloc(cortex_m3->fp_num_code + cortex_m3->fp_num_lit, sizeof(cortex_m3_fp_comparator_t));
1337 for (i = 0; i < cortex_m3->fp_num_code + cortex_m3->fp_num_lit; i++)
1338 {
1339 cortex_m3->fp_comparator_list[i].type = (i < cortex_m3->fp_num_code) ? FPCR_CODE : FPCR_LITERAL;
1340 cortex_m3->fp_comparator_list[i].fpcr_address = FP_COMP0 + 4 * i;
1341 }
1342 DEBUG("FPB fpcr 0x%x, numcode %i, numlit %i", fpcr, cortex_m3->fp_num_code, cortex_m3->fp_num_lit);
1343
1344 /* Setup DWT */
1345 target_read_u32(target, DWT_CTRL, &dwtcr);
1346 cortex_m3->dwt_num_comp = (dwtcr >> 28) & 0xF;
1347 cortex_m3->dwt_comp_available = cortex_m3->dwt_num_comp;
1348 cortex_m3->dwt_comparator_list=calloc(cortex_m3->dwt_num_comp, sizeof(cortex_m3_dwt_comparator_t));
1349 for (i = 0; i < cortex_m3->dwt_num_comp; i++)
1350 {
1351 cortex_m3->dwt_comparator_list[i].dwt_comparator_address = DWT_COMP0 + 0x10 * i;
1352 }
1353
1354 return ERROR_OK;
1355 }
1356
1357 int cortex_m3_quit()
1358 {
1359
1360 return ERROR_OK;
1361 }
1362
1363 int cortex_m3_dcc_read(swjdp_common_t *swjdp, u8 *value, u8 *ctrl)
1364 {
1365 u16 dcrdr;
1366
1367 ahbap_read_buf_u16( swjdp, (u8*)&dcrdr, 1, DCB_DCRDR);
1368 *ctrl = (u8)dcrdr;
1369 *value = (u8)(dcrdr >> 8);
1370
1371 DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
1372
1373 /* write ack back to software dcc register
1374 * signify we have read data */
1375 if (dcrdr & (1 << 0))
1376 {
1377 dcrdr = 0;
1378 ahbap_write_buf_u16( swjdp, (u8*)&dcrdr, 1, DCB_DCRDR);
1379 }
1380
1381 return ERROR_OK;
1382 }
1383
1384 int cortex_m3_target_request_data(target_t *target, u32 size, u8 *buffer)
1385 {
1386 armv7m_common_t *armv7m = target->arch_info;
1387 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1388 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1389 u8 data;
1390 u8 ctrl;
1391 int i;
1392
1393 for (i = 0; i < (size * 4); i++)
1394 {
1395 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1396 buffer[i] = data;
1397 }
1398
1399 return ERROR_OK;
1400 }
1401
1402 int cortex_m3_handle_target_request(void *priv)
1403 {
1404 target_t *target = priv;
1405 armv7m_common_t *armv7m = target->arch_info;
1406 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1407 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1408
1409 if (!target->dbg_msg_enabled)
1410 return ERROR_OK;
1411
1412 if (target->state == TARGET_RUNNING)
1413 {
1414 u8 data;
1415 u8 ctrl;
1416
1417 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1418
1419 /* check if we have data */
1420 if (ctrl & (1 << 0))
1421 {
1422 u32 request;
1423
1424 /* we assume target is quick enough */
1425 request = data;
1426 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1427 request |= (data << 8);
1428 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1429 request |= (data << 16);
1430 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1431 request |= (data << 24);
1432 target_request(target, request);
1433 }
1434 }
1435
1436 return ERROR_OK;
1437 }
1438
1439 int cortex_m3_init_arch_info(target_t *target, cortex_m3_common_t *cortex_m3, int chain_pos, char *variant)
1440 {
1441 armv7m_common_t *armv7m;
1442 armv7m = &cortex_m3->armv7m;
1443
1444 /* prepare JTAG information for the new target */
1445 cortex_m3->jtag_info.chain_pos = chain_pos;
1446 cortex_m3->jtag_info.scann_size = 4;
1447
1448 cortex_m3->swjdp_info.dp_select_value = -1;
1449 cortex_m3->swjdp_info.ap_csw_value = -1;
1450 cortex_m3->swjdp_info.ap_tar_value = -1;
1451 cortex_m3->swjdp_info.jtag_info = &cortex_m3->jtag_info;
1452
1453 /* initialize arch-specific breakpoint handling */
1454
1455 cortex_m3->common_magic = CORTEX_M3_COMMON_MAGIC;
1456 cortex_m3->arch_info = NULL;
1457
1458 /* register arch-specific functions */
1459 armv7m->examine_debug_reason = cortex_m3_examine_debug_reason;
1460
1461 armv7m->pre_debug_entry = NULL;
1462 armv7m->post_debug_entry = NULL;
1463
1464 armv7m->pre_restore_context = NULL;
1465 armv7m->post_restore_context = NULL;
1466
1467 armv7m_init_arch_info(target, armv7m);
1468 armv7m->arch_info = cortex_m3;
1469 armv7m->load_core_reg_u32 = cortex_m3_load_core_reg_u32;
1470 armv7m->store_core_reg_u32 = cortex_m3_store_core_reg_u32;
1471 /* armv7m->full_context = cortex_m3_full_context; */
1472
1473 target_register_timer_callback(cortex_m3_handle_target_request, 1, 1, target);
1474
1475 return ERROR_OK;
1476 }
1477
1478 /* target cortex_m3 <endianess> <startup_mode> <chain_pos> <variant>*/
1479 int cortex_m3_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
1480 {
1481 int chain_pos;
1482 char *variant = NULL;
1483 cortex_m3_common_t *cortex_m3 = malloc(sizeof(cortex_m3_common_t));
1484 memset(cortex_m3, 0, sizeof(*cortex_m3));
1485
1486 if (argc < 4)
1487 {
1488 ERROR("'target cortex_m3' requires at least one additional argument");
1489 exit(-1);
1490 }
1491
1492 chain_pos = strtoul(args[3], NULL, 0);
1493
1494 if (argc >= 5)
1495 variant = args[4];
1496
1497 cortex_m3_init_arch_info(target, cortex_m3, chain_pos, variant);
1498 cortex_m3_register_commands(cmd_ctx);
1499
1500 return ERROR_OK;
1501 }
1502
1503 int cortex_m3_register_commands(struct command_context_s *cmd_ctx)
1504 {
1505 int retval;
1506
1507 retval = armv7m_register_commands(cmd_ctx);
1508
1509 return retval;
1510 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)