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

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)