TAP_SD/SI are now forbidden end states.
[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 LOG_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 LOG_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 LOG_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 LOG_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 LOG_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 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%x, target->state: %s", armv7m_mode_strings[armv7m->core_mode], \
346 *(u32*)(armv7m->core_cache->reg_list[15].value), target_state_strings[target->state]);
347
348 if (armv7m->post_debug_entry)
349 armv7m->post_debug_entry(target);
350
351 return ERROR_OK;
352 }
353
354 int cortex_m3_poll(target_t *target)
355 {
356 int retval;
357 u32 prev_target_state = target->state;
358
359 /* get pointers to arch-specific information */
360 armv7m_common_t *armv7m = target->arch_info;
361 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
362 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
363
364 /* Read from Debug Halting Control and Status Register */
365 retval = ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
366 if (retval != ERROR_OK)
367 {
368 target->state = TARGET_UNKNOWN;
369 return retval;
370 }
371
372 if (cortex_m3->dcb_dhcsr & S_RESET_ST)
373 {
374 /* check if still in reset */
375 ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
376
377 if (cortex_m3->dcb_dhcsr & S_RESET_ST)
378 {
379 target->state = TARGET_RESET;
380 return ERROR_OK;
381 }
382 }
383
384 if (target->state == TARGET_RESET)
385 {
386 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
387 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%x", cortex_m3->dcb_dhcsr);
388 cortex_m3_endreset_event(target);
389 target->state = TARGET_RUNNING;
390 prev_target_state = TARGET_RUNNING;
391 }
392
393 if (cortex_m3->dcb_dhcsr & S_HALT)
394 {
395 target->state = TARGET_HALTED;
396
397 if ((prev_target_state == TARGET_RUNNING) || (prev_target_state == TARGET_RESET))
398 {
399 if ((retval = cortex_m3_debug_entry(target)) != ERROR_OK)
400 return retval;
401
402 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
403 }
404 if (prev_target_state == TARGET_DEBUG_RUNNING)
405 {
406 LOG_DEBUG(" ");
407 if ((retval = cortex_m3_debug_entry(target)) != ERROR_OK)
408 return retval;
409
410 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
411 }
412 }
413
414 /*
415 if (cortex_m3->dcb_dhcsr & S_SLEEP)
416 target->state = TARGET_SLEEP;
417 */
418
419 /* Read Debug Fault Status Register, added to figure out the lockup when running flashtest.script */
420 ahbap_read_system_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr);
421 LOG_DEBUG("dcb_dhcsr 0x%x, nvic_dfsr 0x%x, target->state: %s", cortex_m3->dcb_dhcsr, cortex_m3->nvic_dfsr, target_state_strings[target->state]);
422 return ERROR_OK;
423 }
424
425 int cortex_m3_halt(target_t *target)
426 {
427 /* get pointers to arch-specific information */
428 armv7m_common_t *armv7m = target->arch_info;
429 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
430 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
431
432 LOG_DEBUG("target->state: %s", target_state_strings[target->state]);
433
434 if (target->state == TARGET_HALTED)
435 {
436 LOG_WARNING("target was already halted");
437 return ERROR_OK;
438 }
439
440 if (target->state == TARGET_UNKNOWN)
441 {
442 LOG_WARNING("target was in unknown state when halt was requested");
443 }
444
445 if (target->state == TARGET_RESET)
446 {
447 if ((jtag_reset_config & RESET_SRST_PULLS_TRST) && jtag_srst)
448 {
449 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
450 return ERROR_TARGET_FAILURE;
451 }
452 else
453 {
454 /* we came here in a reset_halt or reset_init sequence
455 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
456 */
457 target->debug_reason = DBG_REASON_DBGRQ;
458
459 return ERROR_OK;
460 }
461 }
462
463 /* Write to Debug Halting Control and Status Register */
464 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN | C_HALT );
465
466 target->debug_reason = DBG_REASON_DBGRQ;
467
468 return ERROR_OK;
469 }
470
471 int cortex_m3_soft_reset_halt(struct target_s *target)
472 {
473 /* get pointers to arch-specific information */
474 armv7m_common_t *armv7m = target->arch_info;
475 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
476 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
477 u32 dcb_dhcsr = 0;
478 int retval, timeout = 0;
479
480 /* Check that we are using process_context, or change and print warning */
481 if (armv7m_get_context(target) != ARMV7M_PROCESS_CONTEXT)
482 {
483 LOG_DEBUG("Changing to process contex registers");
484 armv7m_use_context(target, ARMV7M_PROCESS_CONTEXT);
485 }
486
487 /* Enter debug state on reset, cf. end_reset_event() */
488 ahbap_write_system_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET );
489
490 /* Request a reset */
491 ahbap_write_system_atomic_u32(swjdp, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_VECTRESET );
492 target->state = TARGET_RESET;
493
494 /* registers are now invalid */
495 armv7m_invalidate_core_regs(target);
496
497 while (timeout < 100)
498 {
499 retval = ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &dcb_dhcsr);
500 if (retval == ERROR_OK)
501 {
502 ahbap_read_system_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr);
503 if ((dcb_dhcsr & S_HALT) && (cortex_m3->nvic_dfsr & DFSR_VCATCH))
504 {
505 LOG_DEBUG("system reset-halted, dcb_dhcsr 0x%x, nvic_dfsr 0x%x", dcb_dhcsr, cortex_m3->nvic_dfsr);
506 cortex_m3_poll(target);
507 return ERROR_OK;
508 }
509 else
510 LOG_DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%x, %i ms", dcb_dhcsr, timeout);
511 }
512 timeout++;
513 usleep(1000);
514 }
515
516 return ERROR_OK;
517 }
518
519 int cortex_m3_prepare_reset_halt(struct target_s *target)
520 {
521 armv7m_common_t *armv7m = target->arch_info;
522 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
523 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
524 u32 dcb_demcr, dcb_dhcsr;
525
526 /* Enable debug requests */
527 ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
528 if (!(cortex_m3->dcb_dhcsr & C_DEBUGEN))
529 ahbap_write_system_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN );
530
531 /* Enter debug state on reset, cf. end_reset_event() */
532 ahbap_write_system_atomic_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET );
533
534 ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &dcb_dhcsr);
535 ahbap_read_system_atomic_u32(swjdp, DCB_DEMCR, &dcb_demcr);
536 LOG_DEBUG("dcb_dhcsr 0x%x, dcb_demcr 0x%x, ", dcb_dhcsr, dcb_demcr);
537
538 return ERROR_OK;
539 }
540
541 int cortex_m3_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution)
542 {
543 /* get pointers to arch-specific information */
544 armv7m_common_t *armv7m = target->arch_info;
545 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
546 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
547 breakpoint_t *breakpoint = NULL;
548 u32 dcb_dhcsr, resume_pc;
549
550 if (target->state != TARGET_HALTED)
551 {
552 LOG_WARNING("target not halted");
553 return ERROR_TARGET_NOT_HALTED;
554 }
555
556 if (!debug_execution)
557 {
558 /* Check that we are using process_context, or change and print warning */
559 if (armv7m_get_context(target) != ARMV7M_PROCESS_CONTEXT)
560 {
561 LOG_DEBUG("Incorrect context in resume");
562 armv7m_use_context(target, ARMV7M_PROCESS_CONTEXT);
563 }
564
565 target_free_all_working_areas(target);
566 cortex_m3_enable_breakpoints(target);
567 cortex_m3_enable_watchpoints(target);
568
569 /* TODOLATER Interrupt handling/disable for debug execution, cache ... ... */
570 }
571
572 dcb_dhcsr = DBGKEY | C_DEBUGEN;
573 if (debug_execution)
574 {
575 /* Check that we are using debug_context, or change and print warning */
576 if (armv7m_get_context(target) != ARMV7M_DEBUG_CONTEXT)
577 {
578 LOG_DEBUG("Incorrect context in debug_exec resume");
579 armv7m_use_context(target, ARMV7M_DEBUG_CONTEXT);
580 }
581 /* Disable interrupts */
582 /*
583 We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
584 This is probably the same inssue as Cortex-M3 Errata 377493:
585 C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken.
586 */
587 buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_PRIMASK].value, 0, 32, 1);
588 /* Make sure we are in Thumb mode */
589 buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32,
590 buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32) | (1<<24));
591 }
592
593 /* current = 1: continue on current pc, otherwise continue at <address> */
594 if (!current)
595 {
596 buf_set_u32(armv7m->core_cache->reg_list[15].value, 0, 32, address);
597 armv7m->core_cache->reg_list[15].dirty = 1;
598 armv7m->core_cache->reg_list[15].valid = 1;
599 }
600
601 resume_pc = buf_get_u32(armv7m->core_cache->reg_list[15].value, 0, 32);
602
603 armv7m_restore_context(target);
604
605 /* the front-end may request us not to handle breakpoints */
606 if (handle_breakpoints)
607 {
608 /* Single step past breakpoint at current address */
609 if ((breakpoint = breakpoint_find(target, resume_pc)))
610 {
611 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint->address);
612 cortex_m3_unset_breakpoint(target, breakpoint);
613 cortex_m3_single_step_core(target);
614 cortex_m3_set_breakpoint(target, breakpoint);
615 }
616 }
617
618 /* Set/Clear C_MASKINTS in a separate operation */
619 if ((cortex_m3->dcb_dhcsr & C_MASKINTS) != (dcb_dhcsr & C_MASKINTS))
620 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, dcb_dhcsr | C_HALT );
621
622 /* Restart core */
623 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, dcb_dhcsr );
624 target->debug_reason = DBG_REASON_NOTHALTED;
625
626 /* registers are now invalid */
627 armv7m_invalidate_core_regs(target);
628 if (!debug_execution)
629 {
630 target->state = TARGET_RUNNING;
631 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
632 LOG_DEBUG("target resumed at 0x%x",resume_pc);
633 }
634 else
635 {
636 target->state = TARGET_DEBUG_RUNNING;
637 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
638 LOG_DEBUG("target debug resumed at 0x%x",resume_pc);
639 }
640
641 return ERROR_OK;
642 }
643
644 /* int irqstepcount=0; */
645 int cortex_m3_step(struct target_s *target, int current, u32 address, int handle_breakpoints)
646 {
647 /* get pointers to arch-specific information */
648 armv7m_common_t *armv7m = target->arch_info;
649 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
650 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
651 breakpoint_t *breakpoint = NULL;
652
653 if (target->state != TARGET_HALTED)
654 {
655 LOG_WARNING("target not halted");
656 return ERROR_TARGET_NOT_HALTED;
657 }
658
659 /* Check that we are using process_context, or change and print warning */
660 if (armv7m_get_context(target) != ARMV7M_PROCESS_CONTEXT)
661 {
662 LOG_WARNING("Incorrect context in step, must be process");
663 armv7m_use_context(target, ARMV7M_PROCESS_CONTEXT);
664 }
665
666 /* current = 1: continue on current pc, otherwise continue at <address> */
667 if (!current)
668 buf_set_u32(armv7m->core_cache->reg_list[15].value, 0, 32, address);
669
670 /* the front-end may request us not to handle breakpoints */
671 if (handle_breakpoints)
672 if ((breakpoint = breakpoint_find(target, buf_get_u32(armv7m->core_cache->reg_list[15].value, 0, 32))))
673 cortex_m3_unset_breakpoint(target, breakpoint);
674
675 target->debug_reason = DBG_REASON_SINGLESTEP;
676
677 armv7m_restore_context(target);
678
679 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
680
681 if (cortex_m3->dcb_dhcsr & C_MASKINTS)
682 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN );
683 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY| C_STEP | C_DEBUGEN);
684 ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
685
686 /* If we run in process context then registers are now invalid */
687 if (armv7m_get_context(target) == ARMV7M_PROCESS_CONTEXT)
688 armv7m_invalidate_core_regs(target);
689
690 if (breakpoint)
691 cortex_m3_set_breakpoint(target, breakpoint);
692
693 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3->dcb_dhcsr, cortex_m3->nvic_icsr);
694
695 cortex_m3_debug_entry(target);
696 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
697
698 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3->dcb_dhcsr, cortex_m3->nvic_icsr);
699 return ERROR_OK;
700 }
701
702 int cortex_m3_assert_reset(target_t *target)
703 {
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 LOG_DEBUG("target->state: %s", target_state_strings[target->state]);
709
710 if (!(jtag_reset_config & RESET_HAS_SRST))
711 {
712 LOG_ERROR("Can't assert SRST");
713 return ERROR_FAIL;
714 }
715
716 ahbap_write_system_u32(swjdp, DCB_DCRDR, 0 );
717
718 if (target->reset_mode == RESET_RUN)
719 {
720 /* Set/Clear C_MASKINTS in a separate operation */
721 if (cortex_m3->dcb_dhcsr & C_MASKINTS)
722 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN | C_HALT );
723
724 cortex_m3_clear_halt(target);
725
726 /* Enter debug state on reset, cf. end_reset_event() */
727 ahbap_write_system_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN );
728 ahbap_write_system_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR);
729 }
730
731 if (target->state == TARGET_HALTED || target->state == TARGET_UNKNOWN)
732 {
733 /* assert SRST and TRST */
734 /* system would get ouf sync if we didn't reset test-logic, too */
735 jtag_add_reset(1, 1);
736 jtag_add_sleep(5000);
737 }
738
739 if (jtag_reset_config & RESET_SRST_PULLS_TRST)
740 {
741 jtag_add_reset(1, 1);
742 } else
743 {
744 jtag_add_reset(0, 1);
745 }
746
747 target->state = TARGET_RESET;
748 jtag_add_sleep(50000);
749
750 armv7m_use_context(target, ARMV7M_PROCESS_CONTEXT);
751 armv7m_invalidate_core_regs(target);
752
753 return ERROR_OK;
754 }
755
756 int cortex_m3_deassert_reset(target_t *target)
757 {
758 LOG_DEBUG("target->state: %s", target_state_strings[target->state]);
759
760 /* deassert reset lines */
761 jtag_add_reset(0, 0);
762
763 return ERROR_OK;
764 }
765
766 void cortex_m3_unset_all_breakpoints_and_watchpoints(struct target_s *target)
767 {
768
769 }
770
771 void cortex_m3_enable_breakpoints(struct target_s *target)
772 {
773 breakpoint_t *breakpoint = target->breakpoints;
774
775 /* set any pending breakpoints */
776 while (breakpoint)
777 {
778 if (breakpoint->set == 0)
779 cortex_m3_set_breakpoint(target, breakpoint);
780 breakpoint = breakpoint->next;
781 }
782 }
783
784 int cortex_m3_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
785 {
786 int fp_num=0;
787 u32 hilo;
788
789 /* get pointers to arch-specific information */
790 armv7m_common_t *armv7m = target->arch_info;
791 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
792
793 cortex_m3_fp_comparator_t * comparator_list = cortex_m3->fp_comparator_list;
794
795 if (breakpoint->set)
796 {
797 LOG_WARNING("breakpoint already set");
798 return ERROR_OK;
799 }
800
801 if (cortex_m3->auto_bp_type)
802 {
803 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
804 }
805
806 if (breakpoint->type == BKPT_HARD)
807 {
808 while(comparator_list[fp_num].used && (fp_num < cortex_m3->fp_num_code))
809 fp_num++;
810 if (fp_num >= cortex_m3->fp_num_code)
811 {
812 LOG_DEBUG("ERROR Can not find free FP Comparator");
813 LOG_WARNING("ERROR Can not find free FP Comparator");
814 exit(-1);
815 }
816 breakpoint->set = fp_num + 1;
817 hilo = (breakpoint->address & 0x2) ? FPCR_REPLACE_BKPT_HIGH : FPCR_REPLACE_BKPT_LOW;
818 comparator_list[fp_num].used = 1;
819 comparator_list[fp_num].fpcr_value = (breakpoint->address & 0x1FFFFFFC) | hilo | 1;
820 target_write_u32(target, comparator_list[fp_num].fpcr_address, comparator_list[fp_num].fpcr_value);
821 LOG_DEBUG("fpc_num %i fpcr_value 0x%x", fp_num, comparator_list[fp_num].fpcr_value);
822 }
823 else if (breakpoint->type == BKPT_SOFT)
824 {
825 u8 code[4];
826 buf_set_u32(code, 0, 32, ARMV7M_T_BKPT(0x11));
827 target->type->read_memory(target, breakpoint->address & 0xFFFFFFFE, breakpoint->length, 1, breakpoint->orig_instr);
828 target->type->write_memory(target, breakpoint->address & 0xFFFFFFFE, breakpoint->length, 1, code);
829 breakpoint->set = 0x11; /* Any nice value but 0 */
830 }
831
832 return ERROR_OK;
833 }
834
835 int cortex_m3_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
836 {
837 /* get pointers to arch-specific information */
838 armv7m_common_t *armv7m = target->arch_info;
839 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
840 cortex_m3_fp_comparator_t * comparator_list = cortex_m3->fp_comparator_list;
841
842 if (!breakpoint->set)
843 {
844 LOG_WARNING("breakpoint not set");
845 return ERROR_OK;
846 }
847
848 if (breakpoint->type == BKPT_HARD)
849 {
850 int fp_num = breakpoint->set - 1;
851 if ((fp_num < 0) || (fp_num >= cortex_m3->fp_num_code))
852 {
853 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
854 return ERROR_OK;
855 }
856 comparator_list[fp_num].used = 0;
857 comparator_list[fp_num].fpcr_value = 0;
858 target_write_u32(target, comparator_list[fp_num].fpcr_address, comparator_list[fp_num].fpcr_value);
859 }
860 else
861 {
862 /* restore original instruction (kept in target endianness) */
863 if (breakpoint->length == 4)
864 {
865 target->type->write_memory(target, breakpoint->address & 0xFFFFFFFE, 4, 1, breakpoint->orig_instr);
866 }
867 else
868 {
869 target->type->write_memory(target, breakpoint->address & 0xFFFFFFFE, 2, 1, breakpoint->orig_instr);
870 }
871 }
872 breakpoint->set = 0;
873
874 return ERROR_OK;
875 }
876
877 int cortex_m3_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
878 {
879 /* get pointers to arch-specific information */
880 armv7m_common_t *armv7m = target->arch_info;
881 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
882
883 if (cortex_m3->auto_bp_type)
884 {
885 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
886 }
887
888 if ((breakpoint->type == BKPT_HARD) && (breakpoint->address >= 0x20000000))
889 {
890 LOG_INFO("flash patch comparator requested outside code memory region");
891 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
892 }
893
894 if ((breakpoint->type == BKPT_SOFT) && (breakpoint->address < 0x20000000))
895 {
896 LOG_INFO("soft breakpoint requested in code (flash) memory region");
897 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
898 }
899
900 if ((breakpoint->type == BKPT_HARD) && (cortex_m3->fp_code_available < 1))
901 {
902 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
903 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
904 }
905
906 if ((breakpoint->length != 2))
907 {
908 LOG_INFO("only breakpoints of two bytes length supported");
909 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
910 }
911
912 if (breakpoint->type == BKPT_HARD)
913 cortex_m3->fp_code_available--;
914 cortex_m3_set_breakpoint(target, breakpoint);
915
916 return ERROR_OK;
917 }
918
919 int cortex_m3_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
920 {
921 /* get pointers to arch-specific information */
922 armv7m_common_t *armv7m = target->arch_info;
923 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
924
925 if (target->state != TARGET_HALTED)
926 {
927 LOG_WARNING("target not halted");
928 return ERROR_TARGET_NOT_HALTED;
929 }
930
931 if (cortex_m3->auto_bp_type)
932 {
933 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
934 }
935
936 if (breakpoint->set)
937 {
938 cortex_m3_unset_breakpoint(target, breakpoint);
939 }
940
941 if (breakpoint->type == BKPT_HARD)
942 cortex_m3->fp_code_available++;
943
944 return ERROR_OK;
945 }
946
947 int cortex_m3_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
948 {
949 int dwt_num=0;
950 u32 mask, temp;
951
952 /* get pointers to arch-specific information */
953 armv7m_common_t *armv7m = target->arch_info;
954 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
955 cortex_m3_dwt_comparator_t * comparator_list = cortex_m3->dwt_comparator_list;
956
957 if (watchpoint->set)
958 {
959 LOG_WARNING("watchpoint already set");
960 return ERROR_OK;
961 }
962
963 if (watchpoint->mask == 0xffffffffu)
964 {
965 while(comparator_list[dwt_num].used && (dwt_num < cortex_m3->dwt_num_comp))
966 dwt_num++;
967 if (dwt_num >= cortex_m3->dwt_num_comp)
968 {
969 LOG_DEBUG("ERROR Can not find free DWT Comparator");
970 LOG_WARNING("ERROR Can not find free DWT Comparator");
971 return -1;
972 }
973 watchpoint->set = dwt_num + 1;
974 mask = 0;
975 temp = watchpoint->length;
976 while (temp > 1)
977 {
978 temp = temp / 2;
979 mask++;
980 }
981 comparator_list[dwt_num].used = 1;
982 comparator_list[dwt_num].comp = watchpoint->address;
983 comparator_list[dwt_num].mask = mask;
984 comparator_list[dwt_num].function = watchpoint->rw + 5;
985 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address, comparator_list[dwt_num].comp);
986 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address|0x4, comparator_list[dwt_num].mask);
987 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address|0x8, comparator_list[dwt_num].function);
988 LOG_DEBUG("dwt_num %i 0x%x 0x%x 0x%x", dwt_num, comparator_list[dwt_num].comp, comparator_list[dwt_num].mask, comparator_list[dwt_num].function);
989 }
990 else
991 {
992 LOG_WARNING("Cannot watch data values"); /* Move this test to add_watchpoint */
993 return ERROR_OK;
994 }
995
996 return ERROR_OK;
997
998 }
999
1000 int cortex_m3_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1001 {
1002 /* get pointers to arch-specific information */
1003 armv7m_common_t *armv7m = target->arch_info;
1004 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1005 cortex_m3_dwt_comparator_t * comparator_list = cortex_m3->dwt_comparator_list;
1006 int dwt_num;
1007
1008 if (!watchpoint->set)
1009 {
1010 LOG_WARNING("watchpoint not set");
1011 return ERROR_OK;
1012 }
1013
1014 dwt_num = watchpoint->set - 1;
1015
1016 if ((dwt_num < 0) || (dwt_num >= cortex_m3->dwt_num_comp))
1017 {
1018 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1019 return ERROR_OK;
1020 }
1021 comparator_list[dwt_num].used = 0;
1022 comparator_list[dwt_num].function = 0;
1023 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address|0x8, comparator_list[dwt_num].function);
1024
1025 watchpoint->set = 0;
1026
1027 return ERROR_OK;
1028 }
1029
1030 int cortex_m3_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1031 {
1032 /* get pointers to arch-specific information */
1033 armv7m_common_t *armv7m = target->arch_info;
1034 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1035
1036 if (target->state != TARGET_HALTED)
1037 {
1038 LOG_WARNING("target not halted");
1039 return ERROR_TARGET_NOT_HALTED;
1040 }
1041
1042 if (cortex_m3->dwt_comp_available < 1)
1043 {
1044 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1045 }
1046
1047 if ((watchpoint->length != 1) && (watchpoint->length != 2) && (watchpoint->length != 4))
1048 {
1049 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1050 }
1051
1052 cortex_m3->dwt_comp_available--;
1053
1054 return ERROR_OK;
1055 }
1056
1057 int cortex_m3_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1058 {
1059 /* get pointers to arch-specific information */
1060 armv7m_common_t *armv7m = target->arch_info;
1061 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1062
1063 if (target->state != TARGET_HALTED)
1064 {
1065 LOG_WARNING("target not halted");
1066 return ERROR_TARGET_NOT_HALTED;
1067 }
1068
1069 if (watchpoint->set)
1070 {
1071 cortex_m3_unset_watchpoint(target, watchpoint);
1072 }
1073
1074 cortex_m3->dwt_comp_available++;
1075
1076 return ERROR_OK;
1077 }
1078
1079 void cortex_m3_enable_watchpoints(struct target_s *target)
1080 {
1081 watchpoint_t *watchpoint = target->watchpoints;
1082
1083 /* set any pending watchpoints */
1084 while (watchpoint)
1085 {
1086 if (watchpoint->set == 0)
1087 cortex_m3_set_watchpoint(target, watchpoint);
1088 watchpoint = watchpoint->next;
1089 }
1090 }
1091
1092 int cortex_m3_load_core_reg_u32(struct target_s *target, enum armv7m_regtype type, u32 num, u32 * value)
1093 {
1094 int retval;
1095 /* get pointers to arch-specific information */
1096 armv7m_common_t *armv7m = target->arch_info;
1097 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1098 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1099
1100 if ((type == ARMV7M_REGISTER_CORE_GP) && (num <= ARMV7M_PSP))
1101 {
1102 /* read a normal core register */
1103 retval = ahbap_read_coreregister_u32(swjdp, value, num);
1104
1105 if (retval != ERROR_OK)
1106 {
1107 LOG_ERROR("JTAG failure %i",retval);
1108 return ERROR_JTAG_DEVICE_ERROR;
1109 }
1110 LOG_DEBUG("load from core reg %i value 0x%x",num,*value);
1111 }
1112 else if (type == ARMV7M_REGISTER_CORE_SP) /* Special purpose core register */
1113 {
1114 /* read other registers */
1115 u32 savedram;
1116 u32 SYSm;
1117 u32 instr;
1118 SYSm = num & 0x1F;
1119
1120 ahbap_read_system_u32(swjdp, 0x20000000, &savedram);
1121 instr = ARMV7M_T_MRS(0, SYSm);
1122 ahbap_write_system_u32(swjdp, 0x20000000, ARMV7M_T_MRS(0, SYSm));
1123 ahbap_write_coreregister_u32(swjdp, 0x20000000, 15);
1124 cortex_m3_single_step_core(target);
1125 ahbap_read_coreregister_u32(swjdp, value, 0);
1126 armv7m->core_cache->reg_list[0].dirty = armv7m->core_cache->reg_list[0].valid;
1127 armv7m->core_cache->reg_list[15].dirty = armv7m->core_cache->reg_list[15].valid;
1128 ahbap_write_system_u32(swjdp, 0x20000000, savedram);
1129 swjdp_transaction_endcheck(swjdp);
1130 LOG_DEBUG("load from special reg %i value 0x%x", SYSm, *value);
1131 }
1132 else
1133 {
1134 return ERROR_INVALID_ARGUMENTS;
1135 }
1136
1137 return ERROR_OK;
1138 }
1139
1140 int cortex_m3_store_core_reg_u32(struct target_s *target, enum armv7m_regtype type, u32 num, u32 value)
1141 {
1142 int retval;
1143
1144 /* get pointers to arch-specific information */
1145 armv7m_common_t *armv7m = target->arch_info;
1146 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1147 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1148
1149 if ((type == ARMV7M_REGISTER_CORE_GP) && (num <= ARMV7M_PSP))
1150 {
1151 retval = ahbap_write_coreregister_u32(swjdp, value, num);
1152 if (retval != ERROR_OK)
1153 {
1154 LOG_ERROR("JTAG failure %i", retval);
1155 armv7m->core_cache->reg_list[num].dirty = armv7m->core_cache->reg_list[num].valid;
1156 return ERROR_JTAG_DEVICE_ERROR;
1157 }
1158 LOG_DEBUG("write core reg %i value 0x%x", num, value);
1159 }
1160 else if (type == ARMV7M_REGISTER_CORE_SP) /* Special purpose core register */
1161 {
1162 /* write other registers */
1163 u32 savedram , tempr0;
1164 u32 SYSm;
1165 u32 instr;
1166 SYSm = num & 0x1F;
1167
1168 ahbap_read_system_u32(swjdp, 0x20000000, &savedram);
1169 instr = ARMV7M_T_MSR(SYSm, 0);
1170 ahbap_write_system_u32(swjdp, 0x20000000, ARMV7M_T_MSR(SYSm, 0));
1171 ahbap_read_coreregister_u32(swjdp, &tempr0, 0);
1172 ahbap_write_coreregister_u32(swjdp, value, 0);
1173 ahbap_write_coreregister_u32(swjdp, 0x20000000, 15);
1174 cortex_m3_single_step_core(target);
1175 ahbap_write_coreregister_u32(swjdp, tempr0, 0);
1176 armv7m->core_cache->reg_list[15].dirty = armv7m->core_cache->reg_list[15].valid;
1177 ahbap_write_system_u32(swjdp, 0x20000000, savedram);
1178 swjdp_transaction_endcheck(swjdp);
1179 LOG_DEBUG("write special reg %i value 0x%x ", SYSm, value);
1180 }
1181 else
1182 {
1183 return ERROR_INVALID_ARGUMENTS;
1184 }
1185
1186 return ERROR_OK;
1187 }
1188
1189 int cortex_m3_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1190 {
1191 /* get pointers to arch-specific information */
1192 armv7m_common_t *armv7m = target->arch_info;
1193 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1194 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1195 int retval;
1196
1197 /* sanitize arguments */
1198 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1199 return ERROR_INVALID_ARGUMENTS;
1200
1201 /* cortex_m3 handles unaligned memory access */
1202
1203 switch (size)
1204 {
1205 case 4:
1206 retval = ahbap_read_buf_u32(swjdp, buffer, 4 * count, address);
1207 break;
1208 case 2:
1209 retval = ahbap_read_buf_u16(swjdp, buffer, 2 * count, address);
1210 break;
1211 case 1:
1212 retval = ahbap_read_buf_u8(swjdp, buffer, count, address);
1213 break;
1214 default:
1215 LOG_ERROR("BUG: we shouldn't get here");
1216 exit(-1);
1217 }
1218
1219 return retval;
1220 }
1221
1222 int cortex_m3_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1223 {
1224 /* get pointers to arch-specific information */
1225 armv7m_common_t *armv7m = target->arch_info;
1226 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1227 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1228 int retval;
1229
1230 /* sanitize arguments */
1231 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1232 return ERROR_INVALID_ARGUMENTS;
1233
1234 switch (size)
1235 {
1236 case 4:
1237 retval = ahbap_write_buf_u32(swjdp, buffer, 4 * count, address);
1238 break;
1239 case 2:
1240 retval = ahbap_write_buf_u16(swjdp, buffer, 2 * count, address);
1241 break;
1242 case 1:
1243 retval = ahbap_write_buf_u8(swjdp, buffer, count, address);
1244 break;
1245 default:
1246 LOG_ERROR("BUG: we shouldn't get here");
1247 exit(-1);
1248 }
1249
1250 return retval;
1251 }
1252
1253 int cortex_m3_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer)
1254 {
1255 return cortex_m3_write_memory(target, address, 4, count, buffer);
1256 }
1257
1258 void cortex_m3_build_reg_cache(target_t *target)
1259 {
1260 armv7m_build_reg_cache(target);
1261 }
1262
1263 int cortex_m3_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
1264 {
1265 u32 cpuid, fpcr, dwtcr, ictr;
1266 int i;
1267
1268 /* get pointers to arch-specific information */
1269 armv7m_common_t *armv7m = target->arch_info;
1270 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1271 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1272
1273 cortex_m3_build_reg_cache(target);
1274 ahbap_debugport_init(swjdp);
1275
1276 /* Read from Device Identification Registers */
1277 target_read_u32(target, CPUID, &cpuid);
1278 if (((cpuid >> 4) & 0xc3f) == 0xc23)
1279 LOG_DEBUG("CORTEX-M3 processor detected");
1280 LOG_DEBUG("cpuid: 0x%8.8x", cpuid);
1281
1282 target_read_u32(target, NVIC_ICTR, &ictr);
1283 cortex_m3->intlinesnum = (ictr & 0x1F) + 1;
1284 cortex_m3->intsetenable = calloc(cortex_m3->intlinesnum, 4);
1285 for (i = 0; i < cortex_m3->intlinesnum; i++)
1286 {
1287 target_read_u32(target, NVIC_ISE0 + 4 * i, cortex_m3->intsetenable + i);
1288 LOG_DEBUG("interrupt enable[%i] = 0x%8.8x", i, cortex_m3->intsetenable[i]);
1289 }
1290
1291 /* Setup FPB */
1292 target_read_u32(target, FP_CTRL, &fpcr);
1293 cortex_m3->auto_bp_type = 1;
1294 cortex_m3->fp_num_code = (fpcr >> 4) & 0xF;
1295 cortex_m3->fp_num_lit = (fpcr >> 8) & 0xF;
1296 cortex_m3->fp_code_available = cortex_m3->fp_num_code;
1297 cortex_m3->fp_comparator_list = calloc(cortex_m3->fp_num_code + cortex_m3->fp_num_lit, sizeof(cortex_m3_fp_comparator_t));
1298 for (i = 0; i < cortex_m3->fp_num_code + cortex_m3->fp_num_lit; i++)
1299 {
1300 cortex_m3->fp_comparator_list[i].type = (i < cortex_m3->fp_num_code) ? FPCR_CODE : FPCR_LITERAL;
1301 cortex_m3->fp_comparator_list[i].fpcr_address = FP_COMP0 + 4 * i;
1302 }
1303 LOG_DEBUG("FPB fpcr 0x%x, numcode %i, numlit %i", fpcr, cortex_m3->fp_num_code, cortex_m3->fp_num_lit);
1304
1305 /* Setup DWT */
1306 target_read_u32(target, DWT_CTRL, &dwtcr);
1307 cortex_m3->dwt_num_comp = (dwtcr >> 28) & 0xF;
1308 cortex_m3->dwt_comp_available = cortex_m3->dwt_num_comp;
1309 cortex_m3->dwt_comparator_list=calloc(cortex_m3->dwt_num_comp, sizeof(cortex_m3_dwt_comparator_t));
1310 for (i = 0; i < cortex_m3->dwt_num_comp; i++)
1311 {
1312 cortex_m3->dwt_comparator_list[i].dwt_comparator_address = DWT_COMP0 + 0x10 * i;
1313 }
1314
1315 return ERROR_OK;
1316 }
1317
1318 int cortex_m3_quit()
1319 {
1320
1321 return ERROR_OK;
1322 }
1323
1324 int cortex_m3_dcc_read(swjdp_common_t *swjdp, u8 *value, u8 *ctrl)
1325 {
1326 u16 dcrdr;
1327
1328 ahbap_read_buf_u16( swjdp, (u8*)&dcrdr, 1, DCB_DCRDR);
1329 *ctrl = (u8)dcrdr;
1330 *value = (u8)(dcrdr >> 8);
1331
1332 LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
1333
1334 /* write ack back to software dcc register
1335 * signify we have read data */
1336 if (dcrdr & (1 << 0))
1337 {
1338 dcrdr = 0;
1339 ahbap_write_buf_u16( swjdp, (u8*)&dcrdr, 1, DCB_DCRDR);
1340 }
1341
1342 return ERROR_OK;
1343 }
1344
1345 int cortex_m3_target_request_data(target_t *target, u32 size, u8 *buffer)
1346 {
1347 armv7m_common_t *armv7m = target->arch_info;
1348 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1349 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1350 u8 data;
1351 u8 ctrl;
1352 int i;
1353
1354 for (i = 0; i < (size * 4); i++)
1355 {
1356 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1357 buffer[i] = data;
1358 }
1359
1360 return ERROR_OK;
1361 }
1362
1363 int cortex_m3_handle_target_request(void *priv)
1364 {
1365 target_t *target = priv;
1366 armv7m_common_t *armv7m = target->arch_info;
1367 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1368 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1369
1370 if (!target->dbg_msg_enabled)
1371 return ERROR_OK;
1372
1373 if (target->state == TARGET_RUNNING)
1374 {
1375 u8 data;
1376 u8 ctrl;
1377
1378 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1379
1380 /* check if we have data */
1381 if (ctrl & (1 << 0))
1382 {
1383 u32 request;
1384
1385 /* we assume target is quick enough */
1386 request = data;
1387 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1388 request |= (data << 8);
1389 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1390 request |= (data << 16);
1391 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1392 request |= (data << 24);
1393 target_request(target, request);
1394 }
1395 }
1396
1397 return ERROR_OK;
1398 }
1399
1400 int cortex_m3_init_arch_info(target_t *target, cortex_m3_common_t *cortex_m3, int chain_pos, char *variant)
1401 {
1402 armv7m_common_t *armv7m;
1403 armv7m = &cortex_m3->armv7m;
1404
1405 /* prepare JTAG information for the new target */
1406 cortex_m3->jtag_info.chain_pos = chain_pos;
1407 cortex_m3->jtag_info.scann_size = 4;
1408
1409 cortex_m3->swjdp_info.dp_select_value = -1;
1410 cortex_m3->swjdp_info.ap_csw_value = -1;
1411 cortex_m3->swjdp_info.ap_tar_value = -1;
1412 cortex_m3->swjdp_info.jtag_info = &cortex_m3->jtag_info;
1413
1414 /* initialize arch-specific breakpoint handling */
1415
1416 cortex_m3->common_magic = CORTEX_M3_COMMON_MAGIC;
1417 cortex_m3->arch_info = NULL;
1418
1419 /* register arch-specific functions */
1420 armv7m->examine_debug_reason = cortex_m3_examine_debug_reason;
1421
1422 armv7m->pre_debug_entry = NULL;
1423 armv7m->post_debug_entry = NULL;
1424
1425 armv7m->pre_restore_context = NULL;
1426 armv7m->post_restore_context = NULL;
1427
1428 armv7m_init_arch_info(target, armv7m);
1429 armv7m->arch_info = cortex_m3;
1430 armv7m->load_core_reg_u32 = cortex_m3_load_core_reg_u32;
1431 armv7m->store_core_reg_u32 = cortex_m3_store_core_reg_u32;
1432
1433 target_register_timer_callback(cortex_m3_handle_target_request, 1, 1, target);
1434
1435 return ERROR_OK;
1436 }
1437
1438 /* target cortex_m3 <endianess> <startup_mode> <chain_pos> <variant>*/
1439 int cortex_m3_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
1440 {
1441 int chain_pos;
1442 char *variant = NULL;
1443 cortex_m3_common_t *cortex_m3 = malloc(sizeof(cortex_m3_common_t));
1444 memset(cortex_m3, 0, sizeof(*cortex_m3));
1445
1446 if (argc < 4)
1447 {
1448 LOG_ERROR("'target cortex_m3' requires at least one additional argument");
1449 exit(-1);
1450 }
1451
1452 chain_pos = strtoul(args[3], NULL, 0);
1453
1454 if (argc >= 5)
1455 variant = args[4];
1456
1457 cortex_m3_init_arch_info(target, cortex_m3, chain_pos, variant);
1458 cortex_m3_register_commands(cmd_ctx);
1459
1460 return ERROR_OK;
1461 }
1462
1463 int cortex_m3_register_commands(struct command_context_s *cmd_ctx)
1464 {
1465 int retval;
1466
1467 retval = armv7m_register_commands(cmd_ctx);
1468
1469 return retval;
1470 }

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)