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

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)