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

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)