allows launching OpenOCD w/telnet+gdb server w/the
[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 (target->state == TARGET_HALTED || target->state == TARGET_UNKNOWN)
695 {
696 /* assert SRST and TRST */
697 /* system would get ouf sync if we didn't reset test-logic, too */
698 jtag_add_reset(1, 1);
699 jtag_add_sleep(5000);
700 }
701
702 if (jtag_reset_config & RESET_SRST_PULLS_TRST)
703 {
704 jtag_add_reset(1, 1);
705 }
706 else
707 {
708 jtag_add_reset(0, 1);
709 }
710
711 target->state = TARGET_RESET;
712 jtag_add_sleep(50000);
713
714 armv7m_invalidate_core_regs(target);
715
716 return ERROR_OK;
717 }
718
719 int cortex_m3_deassert_reset(target_t *target)
720 {
721 LOG_DEBUG("target->state: %s", target_state_strings[target->state]);
722
723 /* deassert reset lines */
724 jtag_add_reset(0, 0);
725
726 return ERROR_OK;
727 }
728
729 void cortex_m3_enable_breakpoints(struct target_s *target)
730 {
731 breakpoint_t *breakpoint = target->breakpoints;
732
733 /* set any pending breakpoints */
734 while (breakpoint)
735 {
736 if (breakpoint->set == 0)
737 cortex_m3_set_breakpoint(target, breakpoint);
738 breakpoint = breakpoint->next;
739 }
740 }
741
742 int cortex_m3_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
743 {
744 int fp_num=0;
745 u32 hilo;
746
747 /* get pointers to arch-specific information */
748 armv7m_common_t *armv7m = target->arch_info;
749 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
750
751 cortex_m3_fp_comparator_t * comparator_list = cortex_m3->fp_comparator_list;
752
753 if (breakpoint->set)
754 {
755 LOG_WARNING("breakpoint already set");
756 return ERROR_OK;
757 }
758
759 if (cortex_m3->auto_bp_type)
760 {
761 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
762 }
763
764 if (breakpoint->type == BKPT_HARD)
765 {
766 while(comparator_list[fp_num].used && (fp_num < cortex_m3->fp_num_code))
767 fp_num++;
768 if (fp_num >= cortex_m3->fp_num_code)
769 {
770 LOG_DEBUG("ERROR Can not find free FP Comparator");
771 LOG_WARNING("ERROR Can not find free FP Comparator");
772 exit(-1);
773 }
774 breakpoint->set = fp_num + 1;
775 hilo = (breakpoint->address & 0x2) ? FPCR_REPLACE_BKPT_HIGH : FPCR_REPLACE_BKPT_LOW;
776 comparator_list[fp_num].used = 1;
777 comparator_list[fp_num].fpcr_value = (breakpoint->address & 0x1FFFFFFC) | hilo | 1;
778 target_write_u32(target, comparator_list[fp_num].fpcr_address, comparator_list[fp_num].fpcr_value);
779 LOG_DEBUG("fpc_num %i fpcr_value 0x%x", fp_num, comparator_list[fp_num].fpcr_value);
780 }
781 else if (breakpoint->type == BKPT_SOFT)
782 {
783 u8 code[4];
784 buf_set_u32(code, 0, 32, ARMV7M_T_BKPT(0x11));
785 target->type->read_memory(target, breakpoint->address & 0xFFFFFFFE, breakpoint->length, 1, breakpoint->orig_instr);
786 target->type->write_memory(target, breakpoint->address & 0xFFFFFFFE, breakpoint->length, 1, code);
787 breakpoint->set = 0x11; /* Any nice value but 0 */
788 }
789
790 return ERROR_OK;
791 }
792
793 int cortex_m3_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
794 {
795 /* get pointers to arch-specific information */
796 armv7m_common_t *armv7m = target->arch_info;
797 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
798 cortex_m3_fp_comparator_t * comparator_list = cortex_m3->fp_comparator_list;
799
800 if (!breakpoint->set)
801 {
802 LOG_WARNING("breakpoint not set");
803 return ERROR_OK;
804 }
805
806 if (breakpoint->type == BKPT_HARD)
807 {
808 int fp_num = breakpoint->set - 1;
809 if ((fp_num < 0) || (fp_num >= cortex_m3->fp_num_code))
810 {
811 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
812 return ERROR_OK;
813 }
814 comparator_list[fp_num].used = 0;
815 comparator_list[fp_num].fpcr_value = 0;
816 target_write_u32(target, comparator_list[fp_num].fpcr_address, comparator_list[fp_num].fpcr_value);
817 }
818 else
819 {
820 /* restore original instruction (kept in target endianness) */
821 if (breakpoint->length == 4)
822 {
823 target->type->write_memory(target, breakpoint->address & 0xFFFFFFFE, 4, 1, breakpoint->orig_instr);
824 }
825 else
826 {
827 target->type->write_memory(target, breakpoint->address & 0xFFFFFFFE, 2, 1, breakpoint->orig_instr);
828 }
829 }
830 breakpoint->set = 0;
831
832 return ERROR_OK;
833 }
834
835 int cortex_m3_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
836 {
837 /* get pointers to arch-specific information */
838 armv7m_common_t *armv7m = target->arch_info;
839 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
840
841 if (cortex_m3->auto_bp_type)
842 {
843 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
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 ((type == ARMV7M_REGISTER_CORE_GP) && (num <= ARMV7M_PSP))
1115 {
1116 retval = ahbap_write_coreregister_u32(swjdp, value, num);
1117 if (retval != ERROR_OK)
1118 {
1119 LOG_ERROR("JTAG failure %i", retval);
1120 armv7m->core_cache->reg_list[num].dirty = armv7m->core_cache->reg_list[num].valid;
1121 return ERROR_JTAG_DEVICE_ERROR;
1122 }
1123 LOG_DEBUG("write core reg %i value 0x%x", num, value);
1124 }
1125 else if (type == ARMV7M_REGISTER_CORE_SP) /* Special purpose core register */
1126 {
1127 /* write other registers */
1128
1129 ahbap_read_coreregister_u32(swjdp, &reg, 20);
1130
1131 switch (num)
1132 {
1133 case 19:
1134 buf_set_u32((u8*)&reg, 0, 8, value);
1135 break;
1136
1137 case 20:
1138 buf_set_u32((u8*)&reg, 8, 8, value);
1139 break;
1140
1141 case 21:
1142 buf_set_u32((u8*)&reg, 16, 8, value);
1143 break;
1144
1145 case 22:
1146 buf_set_u32((u8*)&reg, 24, 8, value);
1147 break;
1148 }
1149
1150 ahbap_write_coreregister_u32(swjdp, reg, 20);
1151
1152 LOG_DEBUG("write special reg %i value 0x%x ", num, value);
1153 }
1154 else
1155 {
1156 return ERROR_INVALID_ARGUMENTS;
1157 }
1158
1159 return ERROR_OK;
1160 }
1161
1162 int cortex_m3_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1163 {
1164 /* get pointers to arch-specific information */
1165 armv7m_common_t *armv7m = target->arch_info;
1166 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1167 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1168 int retval;
1169
1170 /* sanitize arguments */
1171 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1172 return ERROR_INVALID_ARGUMENTS;
1173
1174 /* cortex_m3 handles unaligned memory access */
1175
1176 switch (size)
1177 {
1178 case 4:
1179 retval = ahbap_read_buf_u32(swjdp, buffer, 4 * count, address);
1180 break;
1181 case 2:
1182 retval = ahbap_read_buf_u16(swjdp, buffer, 2 * count, address);
1183 break;
1184 case 1:
1185 retval = ahbap_read_buf_u8(swjdp, buffer, count, address);
1186 break;
1187 default:
1188 LOG_ERROR("BUG: we shouldn't get here");
1189 exit(-1);
1190 }
1191
1192 return retval;
1193 }
1194
1195 int cortex_m3_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1196 {
1197 /* get pointers to arch-specific information */
1198 armv7m_common_t *armv7m = target->arch_info;
1199 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1200 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1201 int retval;
1202
1203 /* sanitize arguments */
1204 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1205 return ERROR_INVALID_ARGUMENTS;
1206
1207 switch (size)
1208 {
1209 case 4:
1210 retval = ahbap_write_buf_u32(swjdp, buffer, 4 * count, address);
1211 break;
1212 case 2:
1213 retval = ahbap_write_buf_u16(swjdp, buffer, 2 * count, address);
1214 break;
1215 case 1:
1216 retval = ahbap_write_buf_u8(swjdp, buffer, count, address);
1217 break;
1218 default:
1219 LOG_ERROR("BUG: we shouldn't get here");
1220 exit(-1);
1221 }
1222
1223 return retval;
1224 }
1225
1226 int cortex_m3_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer)
1227 {
1228 return cortex_m3_write_memory(target, address, 4, count, buffer);
1229 }
1230
1231 void cortex_m3_build_reg_cache(target_t *target)
1232 {
1233 armv7m_build_reg_cache(target);
1234 }
1235
1236 int cortex_m3_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
1237 {
1238 u32 cpuid, fpcr, dwtcr, ictr;
1239 int i;
1240
1241 /* get pointers to arch-specific information */
1242 armv7m_common_t *armv7m = target->arch_info;
1243 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1244 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1245
1246 cortex_m3_build_reg_cache(target);
1247 ahbap_debugport_init(swjdp);
1248
1249 /* Read from Device Identification Registers */
1250 target_read_u32(target, CPUID, &cpuid);
1251 if (((cpuid >> 4) & 0xc3f) == 0xc23)
1252 LOG_DEBUG("CORTEX-M3 processor detected");
1253 LOG_DEBUG("cpuid: 0x%8.8x", cpuid);
1254
1255 target_read_u32(target, NVIC_ICTR, &ictr);
1256 cortex_m3->intlinesnum = (ictr & 0x1F) + 1;
1257 cortex_m3->intsetenable = calloc(cortex_m3->intlinesnum, 4);
1258 for (i = 0; i < cortex_m3->intlinesnum; i++)
1259 {
1260 target_read_u32(target, NVIC_ISE0 + 4 * i, cortex_m3->intsetenable + i);
1261 LOG_DEBUG("interrupt enable[%i] = 0x%8.8x", i, cortex_m3->intsetenable[i]);
1262 }
1263
1264 /* Setup FPB */
1265 target_read_u32(target, FP_CTRL, &fpcr);
1266 cortex_m3->auto_bp_type = 1;
1267 cortex_m3->fp_num_code = (fpcr >> 4) & 0xF;
1268 cortex_m3->fp_num_lit = (fpcr >> 8) & 0xF;
1269 cortex_m3->fp_code_available = cortex_m3->fp_num_code;
1270 cortex_m3->fp_comparator_list = calloc(cortex_m3->fp_num_code + cortex_m3->fp_num_lit, sizeof(cortex_m3_fp_comparator_t));
1271 for (i = 0; i < cortex_m3->fp_num_code + cortex_m3->fp_num_lit; i++)
1272 {
1273 cortex_m3->fp_comparator_list[i].type = (i < cortex_m3->fp_num_code) ? FPCR_CODE : FPCR_LITERAL;
1274 cortex_m3->fp_comparator_list[i].fpcr_address = FP_COMP0 + 4 * i;
1275 }
1276 LOG_DEBUG("FPB fpcr 0x%x, numcode %i, numlit %i", fpcr, cortex_m3->fp_num_code, cortex_m3->fp_num_lit);
1277
1278 /* Setup DWT */
1279 target_read_u32(target, DWT_CTRL, &dwtcr);
1280 cortex_m3->dwt_num_comp = (dwtcr >> 28) & 0xF;
1281 cortex_m3->dwt_comp_available = cortex_m3->dwt_num_comp;
1282 cortex_m3->dwt_comparator_list=calloc(cortex_m3->dwt_num_comp, sizeof(cortex_m3_dwt_comparator_t));
1283 for (i = 0; i < cortex_m3->dwt_num_comp; i++)
1284 {
1285 cortex_m3->dwt_comparator_list[i].dwt_comparator_address = DWT_COMP0 + 0x10 * i;
1286 }
1287
1288 return ERROR_OK;
1289 }
1290
1291 int cortex_m3_quit()
1292 {
1293
1294 return ERROR_OK;
1295 }
1296
1297 int cortex_m3_dcc_read(swjdp_common_t *swjdp, u8 *value, u8 *ctrl)
1298 {
1299 u16 dcrdr;
1300
1301 ahbap_read_buf_u16( swjdp, (u8*)&dcrdr, 1, DCB_DCRDR);
1302 *ctrl = (u8)dcrdr;
1303 *value = (u8)(dcrdr >> 8);
1304
1305 LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
1306
1307 /* write ack back to software dcc register
1308 * signify we have read data */
1309 if (dcrdr & (1 << 0))
1310 {
1311 dcrdr = 0;
1312 ahbap_write_buf_u16( swjdp, (u8*)&dcrdr, 1, DCB_DCRDR);
1313 }
1314
1315 return ERROR_OK;
1316 }
1317
1318 int cortex_m3_target_request_data(target_t *target, u32 size, u8 *buffer)
1319 {
1320 armv7m_common_t *armv7m = target->arch_info;
1321 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1322 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1323 u8 data;
1324 u8 ctrl;
1325 int i;
1326
1327 for (i = 0; i < (size * 4); i++)
1328 {
1329 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1330 buffer[i] = data;
1331 }
1332
1333 return ERROR_OK;
1334 }
1335
1336 int cortex_m3_handle_target_request(void *priv)
1337 {
1338 target_t *target = priv;
1339 if (!target->type->examined)
1340 return ERROR_OK;
1341 armv7m_common_t *armv7m = target->arch_info;
1342 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1343 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1344
1345 if (!target->dbg_msg_enabled)
1346 return ERROR_OK;
1347
1348 if (target->state == TARGET_RUNNING)
1349 {
1350 u8 data;
1351 u8 ctrl;
1352
1353 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1354
1355 /* check if we have data */
1356 if (ctrl & (1 << 0))
1357 {
1358 u32 request;
1359
1360 /* we assume target is quick enough */
1361 request = data;
1362 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1363 request |= (data << 8);
1364 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1365 request |= (data << 16);
1366 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1367 request |= (data << 24);
1368 target_request(target, request);
1369 }
1370 }
1371
1372 return ERROR_OK;
1373 }
1374
1375 int cortex_m3_init_arch_info(target_t *target, cortex_m3_common_t *cortex_m3, int chain_pos, char *variant)
1376 {
1377 armv7m_common_t *armv7m;
1378 armv7m = &cortex_m3->armv7m;
1379
1380 /* prepare JTAG information for the new target */
1381 cortex_m3->jtag_info.chain_pos = chain_pos;
1382 cortex_m3->jtag_info.scann_size = 4;
1383
1384 cortex_m3->swjdp_info.dp_select_value = -1;
1385 cortex_m3->swjdp_info.ap_csw_value = -1;
1386 cortex_m3->swjdp_info.ap_tar_value = -1;
1387 cortex_m3->swjdp_info.jtag_info = &cortex_m3->jtag_info;
1388
1389 /* initialize arch-specific breakpoint handling */
1390
1391 cortex_m3->common_magic = CORTEX_M3_COMMON_MAGIC;
1392 cortex_m3->arch_info = NULL;
1393
1394 /* register arch-specific functions */
1395 armv7m->examine_debug_reason = cortex_m3_examine_debug_reason;
1396
1397 armv7m->pre_debug_entry = NULL;
1398 armv7m->post_debug_entry = NULL;
1399
1400 armv7m->pre_restore_context = NULL;
1401 armv7m->post_restore_context = NULL;
1402
1403 armv7m_init_arch_info(target, armv7m);
1404 armv7m->arch_info = cortex_m3;
1405 armv7m->load_core_reg_u32 = cortex_m3_load_core_reg_u32;
1406 armv7m->store_core_reg_u32 = cortex_m3_store_core_reg_u32;
1407
1408 target_register_timer_callback(cortex_m3_handle_target_request, 1, 1, target);
1409
1410 return ERROR_OK;
1411 }
1412
1413 /* target cortex_m3 <endianess> <startup_mode> <chain_pos> <variant>*/
1414 int cortex_m3_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
1415 {
1416 int chain_pos;
1417 char *variant = NULL;
1418 cortex_m3_common_t *cortex_m3 = malloc(sizeof(cortex_m3_common_t));
1419 memset(cortex_m3, 0, sizeof(*cortex_m3));
1420
1421 if (argc < 4)
1422 {
1423 LOG_ERROR("'target cortex_m3' requires at least one additional argument");
1424 exit(-1);
1425 }
1426
1427 chain_pos = strtoul(args[3], NULL, 0);
1428
1429 if (argc >= 5)
1430 variant = args[4];
1431
1432 cortex_m3_init_arch_info(target, cortex_m3, chain_pos, variant);
1433 cortex_m3_register_commands(cmd_ctx);
1434
1435 return ERROR_OK;
1436 }
1437
1438 int cortex_m3_register_commands(struct command_context_s *cmd_ctx)
1439 {
1440 int retval;
1441
1442 retval = armv7m_register_commands(cmd_ctx);
1443
1444 return retval;
1445 }

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)