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

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)