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

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)