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

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)