- armv7m control register now set as dirty when switching context
[openocd.git] / src / target / cortex_m3.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2006 by Magnus Lundin *
6 * lundin@mlu.mine.nu *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "replacements.h"
28
29 #include "cortex_m3.h"
30 #include "armv7m.h"
31
32 #include "register.h"
33 #include "target.h"
34 #include "target_request.h"
35 #include "log.h"
36 #include "jtag.h"
37 #include "arm_jtag.h"
38
39 #include <stdlib.h>
40 #include <string.h>
41
42 /* cli handling */
43 int cortex_m3_register_commands(struct command_context_s *cmd_ctx);
44
45 /* forward declarations */
46 void cortex_m3_unset_all_breakpoints_and_watchpoints(struct target_s *target);
47 void cortex_m3_enable_breakpoints(struct target_s *target);
48 void cortex_m3_enable_watchpoints(struct target_s *target);
49 void cortex_m3_disable_bkpts_and_wpts(struct target_s *target);
50 int cortex_m3_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
51 int cortex_m3_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
52 int cortex_m3_quit();
53 int cortex_m3_load_core_reg_u32(target_t *target, enum armv7m_regtype type, u32 num, u32 *value);
54 int cortex_m3_store_core_reg_u32(target_t *target, enum armv7m_regtype type, u32 num, u32 value);
55 int cortex_m3_target_request_data(target_t *target, u32 size, u8 *buffer);
56
57 target_type_t cortexm3_target =
58 {
59 .name = "cortex_m3",
60
61 .poll = cortex_m3_poll,
62 .arch_state = armv7m_arch_state,
63
64 .target_request_data = cortex_m3_target_request_data,
65
66 .halt = cortex_m3_halt,
67 .resume = cortex_m3_resume,
68 .step = cortex_m3_step,
69
70 .assert_reset = cortex_m3_assert_reset,
71 .deassert_reset = cortex_m3_deassert_reset,
72 .soft_reset_halt = cortex_m3_soft_reset_halt,
73 .prepare_reset_halt = cortex_m3_prepare_reset_halt,
74
75 .get_gdb_reg_list = armv7m_get_gdb_reg_list,
76
77 .read_memory = cortex_m3_read_memory,
78 .write_memory = cortex_m3_write_memory,
79 .bulk_write_memory = cortex_m3_bulk_write_memory,
80 .checksum_memory = armv7m_checksum_memory,
81
82 .run_algorithm = armv7m_run_algorithm,
83
84 .add_breakpoint = cortex_m3_add_breakpoint,
85 .remove_breakpoint = cortex_m3_remove_breakpoint,
86 .add_watchpoint = cortex_m3_add_watchpoint,
87 .remove_watchpoint = cortex_m3_remove_watchpoint,
88
89 .register_commands = cortex_m3_register_commands,
90 .target_command = cortex_m3_target_command,
91 .init_target = cortex_m3_init_target,
92 .quit = cortex_m3_quit
93 };
94
95 int cortex_m3_clear_halt(target_t *target)
96 {
97 /* get pointers to arch-specific information */
98 armv7m_common_t *armv7m = target->arch_info;
99 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
100 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
101
102 /* Read Debug Fault Status Register */
103 ahbap_read_system_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr);
104 /* Write Debug Fault Status Register to enable processing to resume ?? Try with and without this !! */
105 ahbap_write_system_atomic_u32(swjdp, NVIC_DFSR, cortex_m3->nvic_dfsr);
106 DEBUG(" NVIC_DFSR 0x%x", cortex_m3->nvic_dfsr);
107
108 return ERROR_OK;
109 }
110
111 int cortex_m3_single_step_core(target_t *target)
112 {
113 /* get pointers to arch-specific information */
114 armv7m_common_t *armv7m = target->arch_info;
115 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
116 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
117
118 if (!(cortex_m3->dcb_dhcsr & C_MASKINTS))
119 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_MASKINTS | C_HALT | C_DEBUGEN );
120 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_MASKINTS | C_STEP | C_DEBUGEN );
121 cortex_m3->dcb_dhcsr |= C_MASKINTS;
122 DEBUG(" ");
123 cortex_m3_clear_halt(target);
124
125 return ERROR_OK;
126 }
127
128 int cortex_m3_exec_opcode(target_t *target,u32 opcode, int len /* MODE, r0_invalue, &r0_outvalue */ )
129 {
130 /* get pointers to arch-specific information */
131 armv7m_common_t *armv7m = target->arch_info;
132 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
133 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
134 u32 savedram;
135 int retvalue;
136
137 ahbap_read_system_u32(swjdp, 0x20000000, &savedram);
138 ahbap_write_system_u32(swjdp, 0x20000000, opcode);
139 ahbap_write_coreregister_u32(swjdp, 0x20000000, 15);
140 cortex_m3_single_step_core(target);
141 armv7m->core_cache->reg_list[15].dirty = armv7m->core_cache->reg_list[15].valid;
142 retvalue = ahbap_write_system_atomic_u32(swjdp, 0x20000000, savedram);
143
144 return retvalue;
145 }
146
147 #if 0
148 /* Enable interrupts */
149 int cortex_m3_cpsie(target_t *target, u32 IF)
150 {
151 return cortex_m3_exec_opcode(target, ARMV7M_T_CPSIE(IF), 2);
152 }
153
154 /* Disable interrupts */
155 int cortex_m3_cpsid(target_t *target, u32 IF)
156 {
157 return cortex_m3_exec_opcode(target, ARMV7M_T_CPSID(IF), 2);
158 }
159 #endif
160
161 int cortex_m3_endreset_event(target_t *target)
162 {
163 int i;
164 u32 dcb_demcr;
165
166 /* get pointers to arch-specific information */
167 armv7m_common_t *armv7m = target->arch_info;
168 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
169 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
170 cortex_m3_fp_comparator_t *fp_list = cortex_m3->fp_comparator_list;
171 cortex_m3_dwt_comparator_t *dwt_list = cortex_m3->dwt_comparator_list;
172
173 ahbap_read_system_atomic_u32(swjdp, DCB_DEMCR, &dcb_demcr);
174 DEBUG("DCB_DEMCR = 0x%8.8x",dcb_demcr);
175
176 ahbap_write_system_u32(swjdp, DCB_DCRDR, 0 );
177
178 /* Enable debug requests */
179 ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
180 if (!(cortex_m3->dcb_dhcsr & C_DEBUGEN))
181 ahbap_write_system_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN );
182 /* Enable trace and dwt */
183 ahbap_write_system_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR );
184 /* Monitor bus faults */
185 ahbap_write_system_u32(swjdp, NVIC_SHCSR, SHCSR_BUSFAULTENA );
186
187 /* Enable FPB */
188 target_write_u32(target, FP_CTRL, 3);
189
190 /* Restore FPB registers */
191 for (i = 0; i < cortex_m3->fp_num_code + cortex_m3->fp_num_lit; i++)
192 {
193 target_write_u32(target, fp_list[i].fpcr_address, fp_list[i].fpcr_value);
194 }
195
196 /* Restore DWT registers */
197 for (i = 0; i < cortex_m3->dwt_num_comp; i++)
198 {
199 target_write_u32(target, dwt_list[i].dwt_comparator_address, dwt_list[i].comp);
200 target_write_u32(target, dwt_list[i].dwt_comparator_address | 0x4, dwt_list[i].mask);
201 target_write_u32(target, dwt_list[i].dwt_comparator_address | 0x8, dwt_list[i].function);
202 }
203 swjdp_transaction_endcheck(swjdp);
204
205 /* Make sure working_areas are all free */
206 target_free_all_working_areas(target);
207
208 /* We are in process context */
209 armv7m_use_context(target, ARMV7M_PROCESS_CONTEXT);
210 armv7m_invalidate_core_regs(target);
211 return ERROR_OK;
212 }
213
214 int cortex_m3_examine_debug_reason(target_t *target)
215 {
216 /* get pointers to arch-specific information */
217 armv7m_common_t *armv7m = target->arch_info;
218 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
219
220 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
221 /* only check the debug reason if we don't know it already */
222
223 if ((target->debug_reason != DBG_REASON_DBGRQ)
224 && (target->debug_reason != DBG_REASON_SINGLESTEP))
225 {
226 /* INCOMPLETE */
227
228 if (cortex_m3->nvic_dfsr & DFSR_BKPT)
229 {
230 target->debug_reason = DBG_REASON_BREAKPOINT;
231 if (cortex_m3->nvic_dfsr & DFSR_DWTTRAP)
232 target->debug_reason = DBG_REASON_WPTANDBKPT;
233 }
234 else if (cortex_m3->nvic_dfsr & DFSR_DWTTRAP)
235 target->debug_reason = DBG_REASON_WATCHPOINT;
236 }
237
238 return ERROR_OK;
239 }
240
241 int cortex_m3_examine_exception_reason(target_t *target)
242 {
243 u32 shcsr, except_sr, cfsr = -1, except_ar = -1;
244
245 /* get pointers to arch-specific information */
246 armv7m_common_t *armv7m = target->arch_info;
247 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
248 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
249
250 ahbap_read_system_u32(swjdp, NVIC_SHCSR, &shcsr);
251 switch (armv7m->exception_number)
252 {
253 case 2: /* NMI */
254 break;
255 case 3: /* Hard Fault */
256 ahbap_read_system_atomic_u32(swjdp, NVIC_HFSR, &except_sr);
257 if (except_sr & 0x40000000)
258 {
259 ahbap_read_system_u32(swjdp, NVIC_CFSR, &cfsr);
260 }
261 break;
262 case 4: /* Memory Management */
263 ahbap_read_system_u32(swjdp, NVIC_CFSR, &except_sr);
264 ahbap_read_system_u32(swjdp, NVIC_MMFAR, &except_ar);
265 break;
266 case 5: /* Bus Fault */
267 ahbap_read_system_u32(swjdp, NVIC_CFSR, &except_sr);
268 ahbap_read_system_u32(swjdp, NVIC_BFAR, &except_ar);
269 break;
270 case 6: /* Usage Fault */
271 ahbap_read_system_u32(swjdp, NVIC_CFSR, &except_sr);
272 break;
273 case 11: /* SVCall */
274 break;
275 case 12: /* Debug Monitor */
276 ahbap_read_system_u32(swjdp, NVIC_DFSR, &except_sr);
277 break;
278 case 14: /* PendSV */
279 break;
280 case 15: /* SysTick */
281 break;
282 default:
283 except_sr = 0;
284 break;
285 }
286 swjdp_transaction_endcheck(swjdp);
287 DEBUG("%s SHCSR 0x%x, SR 0x%x, CFSR 0x%x, AR 0x%x", armv7m_exception_string(armv7m->exception_number), \
288 shcsr, except_sr, cfsr, except_ar);
289 return ERROR_OK;
290 }
291
292 int cortex_m3_debug_entry(target_t *target)
293 {
294 int i;
295 u32 xPSR;
296 int retval;
297
298 /* get pointers to arch-specific information */
299 armv7m_common_t *armv7m = target->arch_info;
300 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
301 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
302
303 DEBUG(" ");
304 if (armv7m->pre_debug_entry)
305 armv7m->pre_debug_entry(target);
306
307 cortex_m3_clear_halt(target);
308 ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
309
310 if ((retval = armv7m->examine_debug_reason(target)) != ERROR_OK)
311 return retval;
312
313 /* Examine target state and mode */
314 /* First load register acessible through core debug port*/
315 for (i = 0; i < ARMV7M_PRIMASK; i++)
316 {
317 if (!armv7m->core_cache->reg_list[i].valid)
318 armv7m->read_core_reg(target, i);
319 }
320
321 xPSR = buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32);
322
323 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
324 if (xPSR & 0xf00)
325 {
326 armv7m->core_cache->reg_list[ARMV7M_xPSR].dirty = armv7m->core_cache->reg_list[ARMV7M_xPSR].valid;
327 cortex_m3_store_core_reg_u32(target, ARMV7M_REGISTER_CORE_GP, 16, xPSR &~ 0xff);
328 }
329
330 /* Now we can load SP core registers */
331 for (i = ARMV7M_PRIMASK; i < ARMV7NUMCOREREGS; i++)
332 {
333 if (!armv7m->core_cache->reg_list[i].valid)
334 armv7m->read_core_reg(target, i);
335 }
336
337 /* Are we in an exception handler */
338 armv7m->core_mode = (xPSR & 0x1FF) ? ARMV7M_MODE_HANDLER : ARMV7M_MODE_THREAD;
339 armv7m->exception_number = xPSR & 0x1FF;
340 if (armv7m->exception_number)
341 {
342 cortex_m3_examine_exception_reason(target);
343 }
344
345 DEBUG("entered debug state 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 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 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 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 DEBUG("target->state: %s", target_state_strings[target->state]);
433
434 if (target->state == TARGET_HALTED)
435 {
436 WARNING("target was already halted");
437 return ERROR_OK;
438 }
439
440 if (target->state == TARGET_UNKNOWN)
441 {
442 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 int retval;
705 armv7m_common_t *armv7m = target->arch_info;
706 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
707 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
708
709 DEBUG("target->state: %s", target_state_strings[target->state]);
710
711 ahbap_write_system_u32(swjdp, DCB_DCRDR, 0 );
712
713 if (target->reset_mode == RESET_RUN)
714 {
715 /* Set/Clear C_MASKINTS in a separate operation */
716 if (cortex_m3->dcb_dhcsr & C_MASKINTS)
717 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN | C_HALT );
718
719 cortex_m3_clear_halt(target);
720
721 /* Enter debug state on reset, cf. end_reset_event() */
722 ahbap_write_system_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN );
723 ahbap_write_system_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR);
724 }
725
726 if (target->state == TARGET_HALTED || target->state == TARGET_UNKNOWN)
727 {
728 /* assert SRST and TRST */
729 /* system would get ouf sync if we didn't reset test-logic, too */
730 if ((retval = jtag_add_reset(1, 1)) != ERROR_OK)
731 {
732 if (retval == ERROR_JTAG_RESET_CANT_SRST)
733 {
734 WARNING("can't assert srst");
735 return retval;
736 }
737 else
738 {
739 ERROR("unknown error");
740 exit(-1);
741 }
742 }
743 jtag_add_sleep(5000);
744 if ((retval = jtag_add_reset(0, 1)) != ERROR_OK)
745 {
746 if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST)
747 {
748 WARNING("srst resets test logic, too");
749 retval = jtag_add_reset(1, 1);
750 }
751 }
752 }
753 else
754 {
755 if ((retval = jtag_add_reset(0, 1)) != ERROR_OK)
756 {
757 if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST)
758 {
759 WARNING("srst resets test logic, too");
760 retval = jtag_add_reset(1, 1);
761 }
762
763 if (retval == ERROR_JTAG_RESET_CANT_SRST)
764 {
765 WARNING("can't assert srsrt");
766 return retval;
767 }
768 else if (retval != ERROR_OK)
769 {
770 ERROR("unknown error");
771 exit(-1);
772 }
773 }
774 }
775
776 target->state = TARGET_RESET;
777 jtag_add_sleep(50000);
778
779 armv7m_use_context(target, ARMV7M_PROCESS_CONTEXT);
780 armv7m_invalidate_core_regs(target);
781
782 return ERROR_OK;
783 }
784
785 int cortex_m3_deassert_reset(target_t *target)
786 {
787 DEBUG("target->state: %s", target_state_strings[target->state]);
788
789 /* deassert reset lines */
790 jtag_add_reset(0, 0);
791
792 return ERROR_OK;
793 }
794
795 void cortex_m3_unset_all_breakpoints_and_watchpoints(struct target_s *target)
796 {
797
798 }
799
800 void cortex_m3_enable_breakpoints(struct target_s *target)
801 {
802 breakpoint_t *breakpoint = target->breakpoints;
803
804 /* set any pending breakpoints */
805 while (breakpoint)
806 {
807 if (breakpoint->set == 0)
808 cortex_m3_set_breakpoint(target, breakpoint);
809 breakpoint = breakpoint->next;
810 }
811 }
812
813 int cortex_m3_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
814 {
815 int fp_num=0;
816 u32 hilo;
817
818 /* get pointers to arch-specific information */
819 armv7m_common_t *armv7m = target->arch_info;
820 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
821
822 cortex_m3_fp_comparator_t * comparator_list = cortex_m3->fp_comparator_list;
823
824 if (breakpoint->set)
825 {
826 WARNING("breakpoint already set");
827 return ERROR_OK;
828 }
829
830 if (cortex_m3->auto_bp_type)
831 {
832 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
833 }
834
835 if (breakpoint->type == BKPT_HARD)
836 {
837 while(comparator_list[fp_num].used && (fp_num < cortex_m3->fp_num_code))
838 fp_num++;
839 if (fp_num >= cortex_m3->fp_num_code)
840 {
841 DEBUG("ERROR Can not find free FP Comparator");
842 WARNING("ERROR Can not find free FP Comparator");
843 exit(-1);
844 }
845 breakpoint->set = fp_num + 1;
846 hilo = (breakpoint->address & 0x2) ? FPCR_REPLACE_BKPT_HIGH : FPCR_REPLACE_BKPT_LOW;
847 comparator_list[fp_num].used = 1;
848 comparator_list[fp_num].fpcr_value = (breakpoint->address & 0x1FFFFFFC) | hilo | 1;
849 target_write_u32(target, comparator_list[fp_num].fpcr_address, comparator_list[fp_num].fpcr_value);
850 DEBUG("fpc_num %i fpcr_value 0x%x", fp_num, comparator_list[fp_num].fpcr_value);
851 }
852 else if (breakpoint->type == BKPT_SOFT)
853 {
854 u8 code[4];
855 buf_set_u32(code, 0, 32, ARMV7M_T_BKPT(0x11));
856 target->type->read_memory(target, breakpoint->address & 0xFFFFFFFE, breakpoint->length, 1, breakpoint->orig_instr);
857 target->type->write_memory(target, breakpoint->address & 0xFFFFFFFE, breakpoint->length, 1, code);
858 breakpoint->set = 0x11; /* Any nice value but 0 */
859 }
860
861 return ERROR_OK;
862 }
863
864 int cortex_m3_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
865 {
866 /* get pointers to arch-specific information */
867 armv7m_common_t *armv7m = target->arch_info;
868 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
869 cortex_m3_fp_comparator_t * comparator_list = cortex_m3->fp_comparator_list;
870
871 if (!breakpoint->set)
872 {
873 WARNING("breakpoint not set");
874 return ERROR_OK;
875 }
876
877 if (breakpoint->type == BKPT_HARD)
878 {
879 int fp_num = breakpoint->set - 1;
880 if ((fp_num < 0) || (fp_num >= cortex_m3->fp_num_code))
881 {
882 DEBUG("Invalid FP Comparator number in breakpoint");
883 return ERROR_OK;
884 }
885 comparator_list[fp_num].used = 0;
886 comparator_list[fp_num].fpcr_value = 0;
887 target_write_u32(target, comparator_list[fp_num].fpcr_address, comparator_list[fp_num].fpcr_value);
888 }
889 else
890 {
891 /* restore original instruction (kept in target endianness) */
892 if (breakpoint->length == 4)
893 {
894 target->type->write_memory(target, breakpoint->address & 0xFFFFFFFE, 4, 1, breakpoint->orig_instr);
895 }
896 else
897 {
898 target->type->write_memory(target, breakpoint->address & 0xFFFFFFFE, 2, 1, breakpoint->orig_instr);
899 }
900 }
901 breakpoint->set = 0;
902
903 return ERROR_OK;
904 }
905
906 int cortex_m3_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
907 {
908 /* get pointers to arch-specific information */
909 armv7m_common_t *armv7m = target->arch_info;
910 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
911
912 if (cortex_m3->auto_bp_type)
913 {
914 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
915 }
916
917 if ((breakpoint->type == BKPT_HARD) && (breakpoint->address >= 0x20000000))
918 {
919 INFO("flash patch comparator requested outside code memory region");
920 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
921 }
922
923 if ((breakpoint->type == BKPT_SOFT) && (breakpoint->address < 0x20000000))
924 {
925 INFO("soft breakpoint requested in code (flash) memory region");
926 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
927 }
928
929 if ((breakpoint->type == BKPT_HARD) && (cortex_m3->fp_code_available < 1))
930 {
931 INFO("no flash patch comparator unit available for hardware breakpoint");
932 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
933 }
934
935 if ((breakpoint->length != 2))
936 {
937 INFO("only breakpoints of two bytes length supported");
938 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
939 }
940
941 if (breakpoint->type == BKPT_HARD)
942 cortex_m3->fp_code_available--;
943 cortex_m3_set_breakpoint(target, breakpoint);
944
945 return ERROR_OK;
946 }
947
948 int cortex_m3_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
949 {
950 /* get pointers to arch-specific information */
951 armv7m_common_t *armv7m = target->arch_info;
952 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
953
954 if (target->state != TARGET_HALTED)
955 {
956 WARNING("target not halted");
957 return ERROR_TARGET_NOT_HALTED;
958 }
959
960 if (cortex_m3->auto_bp_type)
961 {
962 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
963 }
964
965 if (breakpoint->set)
966 {
967 cortex_m3_unset_breakpoint(target, breakpoint);
968 }
969
970 if (breakpoint->type == BKPT_HARD)
971 cortex_m3->fp_code_available++;
972
973 return ERROR_OK;
974 }
975
976 int cortex_m3_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
977 {
978 int dwt_num=0;
979 u32 mask, temp;
980
981 /* get pointers to arch-specific information */
982 armv7m_common_t *armv7m = target->arch_info;
983 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
984 cortex_m3_dwt_comparator_t * comparator_list = cortex_m3->dwt_comparator_list;
985
986 if (watchpoint->set)
987 {
988 WARNING("watchpoint already set");
989 return ERROR_OK;
990 }
991
992 if (watchpoint->mask == 0xffffffffu)
993 {
994 while(comparator_list[dwt_num].used && (dwt_num < cortex_m3->dwt_num_comp))
995 dwt_num++;
996 if (dwt_num >= cortex_m3->dwt_num_comp)
997 {
998 DEBUG("ERROR Can not find free DWT Comparator");
999 WARNING("ERROR Can not find free DWT Comparator");
1000 return -1;
1001 }
1002 watchpoint->set = dwt_num + 1;
1003 mask = 0;
1004 temp = watchpoint->length;
1005 while (temp > 1)
1006 {
1007 temp = temp / 2;
1008 mask++;
1009 }
1010 comparator_list[dwt_num].used = 1;
1011 comparator_list[dwt_num].comp = watchpoint->address;
1012 comparator_list[dwt_num].mask = mask;
1013 comparator_list[dwt_num].function = watchpoint->rw + 5;
1014 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address, comparator_list[dwt_num].comp);
1015 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address|0x4, comparator_list[dwt_num].mask);
1016 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address|0x8, comparator_list[dwt_num].function);
1017 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);
1018 }
1019 else
1020 {
1021 WARNING("Cannot watch data values"); /* Move this test to add_watchpoint */
1022 return ERROR_OK;
1023 }
1024
1025 return ERROR_OK;
1026
1027 }
1028
1029 int cortex_m3_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1030 {
1031 /* get pointers to arch-specific information */
1032 armv7m_common_t *armv7m = target->arch_info;
1033 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1034 cortex_m3_dwt_comparator_t * comparator_list = cortex_m3->dwt_comparator_list;
1035 int dwt_num;
1036
1037 if (!watchpoint->set)
1038 {
1039 WARNING("watchpoint not set");
1040 return ERROR_OK;
1041 }
1042
1043 dwt_num = watchpoint->set - 1;
1044
1045 if ((dwt_num < 0) || (dwt_num >= cortex_m3->dwt_num_comp))
1046 {
1047 DEBUG("Invalid DWT Comparator number in watchpoint");
1048 return ERROR_OK;
1049 }
1050 comparator_list[dwt_num].used = 0;
1051 comparator_list[dwt_num].function = 0;
1052 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address|0x8, comparator_list[dwt_num].function);
1053
1054 watchpoint->set = 0;
1055
1056 return ERROR_OK;
1057 }
1058
1059 int cortex_m3_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1060 {
1061 /* get pointers to arch-specific information */
1062 armv7m_common_t *armv7m = target->arch_info;
1063 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1064
1065 if (target->state != TARGET_HALTED)
1066 {
1067 WARNING("target not halted");
1068 return ERROR_TARGET_NOT_HALTED;
1069 }
1070
1071 if (cortex_m3->dwt_comp_available < 1)
1072 {
1073 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1074 }
1075
1076 if ((watchpoint->length != 1) && (watchpoint->length != 2) && (watchpoint->length != 4))
1077 {
1078 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1079 }
1080
1081 cortex_m3->dwt_comp_available--;
1082
1083 return ERROR_OK;
1084 }
1085
1086 int cortex_m3_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1087 {
1088 /* get pointers to arch-specific information */
1089 armv7m_common_t *armv7m = target->arch_info;
1090 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1091
1092 if (target->state != TARGET_HALTED)
1093 {
1094 WARNING("target not halted");
1095 return ERROR_TARGET_NOT_HALTED;
1096 }
1097
1098 if (watchpoint->set)
1099 {
1100 cortex_m3_unset_watchpoint(target, watchpoint);
1101 }
1102
1103 cortex_m3->dwt_comp_available++;
1104
1105 return ERROR_OK;
1106 }
1107
1108 void cortex_m3_enable_watchpoints(struct target_s *target)
1109 {
1110 watchpoint_t *watchpoint = target->watchpoints;
1111
1112 /* set any pending watchpoints */
1113 while (watchpoint)
1114 {
1115 if (watchpoint->set == 0)
1116 cortex_m3_set_watchpoint(target, watchpoint);
1117 watchpoint = watchpoint->next;
1118 }
1119 }
1120
1121 int cortex_m3_load_core_reg_u32(struct target_s *target, enum armv7m_regtype type, u32 num, u32 * value)
1122 {
1123 int retval;
1124 /* get pointers to arch-specific information */
1125 armv7m_common_t *armv7m = target->arch_info;
1126 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1127 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1128
1129 if ((type == ARMV7M_REGISTER_CORE_GP) && (num <= ARMV7M_PSP))
1130 {
1131 /* read a normal core register */
1132 retval = ahbap_read_coreregister_u32(swjdp, value, num);
1133
1134 if (retval != ERROR_OK)
1135 {
1136 ERROR("JTAG failure %i",retval);
1137 return ERROR_JTAG_DEVICE_ERROR;
1138 }
1139 /* DEBUG("load from core reg %i value 0x%x",num,*value); */
1140 }
1141 else if (type == ARMV7M_REGISTER_CORE_SP) /* Special purpose core register */
1142 {
1143 /* read other registers */
1144 /* cortex_m3_MRS(struct target_s *target, int num, u32* value) */
1145 u32 savedram;
1146 u32 SYSm;
1147 u32 instr;
1148 SYSm = num & 0x1F;
1149 ahbap_read_system_u32(swjdp, 0x20000000, &savedram);
1150 instr = ARMV7M_T_MRS(0, SYSm);
1151 ahbap_write_system_u32(swjdp, 0x20000000, ARMV7M_T_MRS(0, SYSm));
1152 ahbap_write_coreregister_u32(swjdp, 0x20000000, 15);
1153 cortex_m3_single_step_core(target);
1154 ahbap_read_coreregister_u32(swjdp, value, 0);
1155 armv7m->core_cache->reg_list[0].dirty = armv7m->core_cache->reg_list[0].valid;
1156 armv7m->core_cache->reg_list[15].dirty = armv7m->core_cache->reg_list[15].valid;
1157 ahbap_write_system_u32(swjdp, 0x20000000, savedram);
1158 swjdp_transaction_endcheck(swjdp);
1159 DEBUG("load from special reg %i value 0x%x", SYSm, *value);
1160 }
1161 else return ERROR_INVALID_ARGUMENTS;
1162
1163 return ERROR_OK;
1164 }
1165
1166 int cortex_m3_store_core_reg_u32(struct target_s *target, enum armv7m_regtype type, u32 num, u32 value)
1167 {
1168 int retval;
1169
1170 /* get pointers to arch-specific information */
1171 armv7m_common_t *armv7m = target->arch_info;
1172 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1173 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1174
1175 if ((type == ARMV7M_REGISTER_CORE_GP) && (num <= ARMV7M_PSP))
1176 {
1177 retval = ahbap_write_coreregister_u32(swjdp, value, num);
1178 if (retval != ERROR_OK)
1179 {
1180 ERROR("JTAG failure %i", retval);
1181 armv7m->core_cache->reg_list[num].dirty = armv7m->core_cache->reg_list[num].valid;
1182 return ERROR_JTAG_DEVICE_ERROR;
1183 }
1184 DEBUG("write core reg %i value 0x%x", num, value);
1185 }
1186 else if (type == ARMV7M_REGISTER_CORE_SP) /* Special purpose core register */
1187 {
1188 /* write other registers */
1189 u32 savedram , tempr0;
1190 u32 SYSm;
1191 u32 instr;
1192 SYSm = num & 0x1F;
1193 ahbap_read_system_u32(swjdp, 0x20000000, &savedram);
1194 instr = ARMV7M_T_MSR(SYSm, 0);
1195 ahbap_write_system_u32(swjdp, 0x20000000, ARMV7M_T_MSR(SYSm, 0));
1196 ahbap_read_coreregister_u32(swjdp, &tempr0, 0);
1197 ahbap_write_coreregister_u32(swjdp, value, 0);
1198 ahbap_write_coreregister_u32(swjdp, 0x20000000, 15);
1199 cortex_m3_single_step_core(target);
1200 ahbap_write_coreregister_u32(swjdp, tempr0, 0);
1201 armv7m->core_cache->reg_list[15].dirty = armv7m->core_cache->reg_list[15].valid;
1202 ahbap_write_system_u32(swjdp, 0x20000000, savedram);
1203 swjdp_transaction_endcheck(swjdp);
1204 DEBUG("write special reg %i value 0x%x ", SYSm, value);
1205 }
1206 else return ERROR_INVALID_ARGUMENTS;
1207
1208 return ERROR_OK;
1209 }
1210
1211 int cortex_m3_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1212 {
1213 /* get pointers to arch-specific information */
1214 armv7m_common_t *armv7m = target->arch_info;
1215 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1216 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1217 int retval;
1218
1219 /* sanitize arguments */
1220 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1221 return ERROR_INVALID_ARGUMENTS;
1222
1223 /* cortex_m3 handles unaligned memory access */
1224
1225 switch (size)
1226 {
1227 case 4:
1228 retval = ahbap_read_buf_u32(swjdp, buffer, 4 * count, address);
1229 break;
1230 case 2:
1231 retval = ahbap_read_buf_u16(swjdp, buffer, 2 * count, address);
1232 break;
1233 case 1:
1234 retval = ahbap_read_buf_u8(swjdp, buffer, count, address);
1235 break;
1236 default:
1237 ERROR("BUG: we shouldn't get here");
1238 exit(-1);
1239 }
1240
1241 return retval;
1242 }
1243
1244 int cortex_m3_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1245 {
1246 /* get pointers to arch-specific information */
1247 armv7m_common_t *armv7m = target->arch_info;
1248 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1249 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1250 int retval;
1251
1252 /* sanitize arguments */
1253 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1254 return ERROR_INVALID_ARGUMENTS;
1255
1256 switch (size)
1257 {
1258 case 4:
1259 retval = ahbap_write_buf_u32(swjdp, buffer, 4 * count, address);
1260 break;
1261 case 2:
1262 retval = ahbap_write_buf_u16(swjdp, buffer, 2 * count, address);
1263 break;
1264 case 1:
1265 retval = ahbap_write_buf_u8(swjdp, buffer, count, address);
1266 break;
1267 default:
1268 ERROR("BUG: we shouldn't get here");
1269 exit(-1);
1270 }
1271
1272 return retval;
1273 }
1274
1275 int cortex_m3_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer)
1276 {
1277 return cortex_m3_write_memory(target, address, 4, count, buffer);
1278 }
1279
1280 void cortex_m3_build_reg_cache(target_t *target)
1281 {
1282 armv7m_build_reg_cache(target);
1283 }
1284
1285 int cortex_m3_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
1286 {
1287 u32 cpuid, fpcr, dwtcr, ictr;
1288 int i;
1289
1290 /* get pointers to arch-specific information */
1291 armv7m_common_t *armv7m = target->arch_info;
1292 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1293 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1294
1295 cortex_m3_build_reg_cache(target);
1296 ahbap_debugport_init(swjdp);
1297
1298 /* Read from Device Identification Registers */
1299 target_read_u32(target, CPUID, &cpuid);
1300 if (((cpuid >> 4) & 0xc3f) == 0xc23)
1301 DEBUG("CORTEX-M3 processor detected");
1302 DEBUG("cpuid: 0x%8.8x", cpuid);
1303
1304 target_read_u32(target, NVIC_ICTR, &ictr);
1305 cortex_m3->intlinesnum = (ictr & 0x1F) + 1;
1306 cortex_m3->intsetenable = calloc(cortex_m3->intlinesnum, 4);
1307 for (i = 0; i < cortex_m3->intlinesnum; i++)
1308 {
1309 target_read_u32(target, NVIC_ISE0 + 4 * i, cortex_m3->intsetenable + i);
1310 DEBUG("interrupt enable[%i] = 0x%8.8x", i, cortex_m3->intsetenable[i]);
1311 }
1312
1313 /* Setup FPB */
1314 target_read_u32(target, FP_CTRL, &fpcr);
1315 cortex_m3->auto_bp_type = 1;
1316 cortex_m3->fp_num_code = (fpcr >> 4) & 0xF;
1317 cortex_m3->fp_num_lit = (fpcr >> 8) & 0xF;
1318 cortex_m3->fp_code_available = cortex_m3->fp_num_code;
1319 cortex_m3->fp_comparator_list = calloc(cortex_m3->fp_num_code + cortex_m3->fp_num_lit, sizeof(cortex_m3_fp_comparator_t));
1320 for (i = 0; i < cortex_m3->fp_num_code + cortex_m3->fp_num_lit; i++)
1321 {
1322 cortex_m3->fp_comparator_list[i].type = (i < cortex_m3->fp_num_code) ? FPCR_CODE : FPCR_LITERAL;
1323 cortex_m3->fp_comparator_list[i].fpcr_address = FP_COMP0 + 4 * i;
1324 }
1325 DEBUG("FPB fpcr 0x%x, numcode %i, numlit %i", fpcr, cortex_m3->fp_num_code, cortex_m3->fp_num_lit);
1326
1327 /* Setup DWT */
1328 target_read_u32(target, DWT_CTRL, &dwtcr);
1329 cortex_m3->dwt_num_comp = (dwtcr >> 28) & 0xF;
1330 cortex_m3->dwt_comp_available = cortex_m3->dwt_num_comp;
1331 cortex_m3->dwt_comparator_list=calloc(cortex_m3->dwt_num_comp, sizeof(cortex_m3_dwt_comparator_t));
1332 for (i = 0; i < cortex_m3->dwt_num_comp; i++)
1333 {
1334 cortex_m3->dwt_comparator_list[i].dwt_comparator_address = DWT_COMP0 + 0x10 * i;
1335 }
1336
1337 return ERROR_OK;
1338 }
1339
1340 int cortex_m3_quit()
1341 {
1342
1343 return ERROR_OK;
1344 }
1345
1346 int cortex_m3_dcc_read(swjdp_common_t *swjdp, u8 *value, u8 *ctrl)
1347 {
1348 u16 dcrdr;
1349
1350 ahbap_read_buf_u16( swjdp, (u8*)&dcrdr, 1, DCB_DCRDR);
1351 *ctrl = (u8)dcrdr;
1352 *value = (u8)(dcrdr >> 8);
1353
1354 DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
1355
1356 /* write ack back to software dcc register
1357 * signify we have read data */
1358 if (dcrdr & (1 << 0))
1359 {
1360 dcrdr = 0;
1361 ahbap_write_buf_u16( swjdp, (u8*)&dcrdr, 1, DCB_DCRDR);
1362 }
1363
1364 return ERROR_OK;
1365 }
1366
1367 int cortex_m3_target_request_data(target_t *target, u32 size, u8 *buffer)
1368 {
1369 armv7m_common_t *armv7m = target->arch_info;
1370 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1371 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1372 u8 data;
1373 u8 ctrl;
1374 int i;
1375
1376 for (i = 0; i < (size * 4); i++)
1377 {
1378 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1379 buffer[i] = data;
1380 }
1381
1382 return ERROR_OK;
1383 }
1384
1385 int cortex_m3_handle_target_request(void *priv)
1386 {
1387 target_t *target = priv;
1388 armv7m_common_t *armv7m = target->arch_info;
1389 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1390 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1391
1392 if (!target->dbg_msg_enabled)
1393 return ERROR_OK;
1394
1395 if (target->state == TARGET_RUNNING)
1396 {
1397 u8 data;
1398 u8 ctrl;
1399
1400 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1401
1402 /* check if we have data */
1403 if (ctrl & (1 << 0))
1404 {
1405 u32 request;
1406
1407 /* we assume target is quick enough */
1408 request = data;
1409 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1410 request |= (data << 8);
1411 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1412 request |= (data << 16);
1413 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1414 request |= (data << 24);
1415 target_request(target, request);
1416 }
1417 }
1418
1419 return ERROR_OK;
1420 }
1421
1422 int cortex_m3_init_arch_info(target_t *target, cortex_m3_common_t *cortex_m3, int chain_pos, char *variant)
1423 {
1424 armv7m_common_t *armv7m;
1425 armv7m = &cortex_m3->armv7m;
1426
1427 /* prepare JTAG information for the new target */
1428 cortex_m3->jtag_info.chain_pos = chain_pos;
1429 cortex_m3->jtag_info.scann_size = 4;
1430
1431 cortex_m3->swjdp_info.dp_select_value = -1;
1432 cortex_m3->swjdp_info.ap_csw_value = -1;
1433 cortex_m3->swjdp_info.ap_tar_value = -1;
1434 cortex_m3->swjdp_info.jtag_info = &cortex_m3->jtag_info;
1435
1436 /* initialize arch-specific breakpoint handling */
1437
1438 cortex_m3->common_magic = CORTEX_M3_COMMON_MAGIC;
1439 cortex_m3->arch_info = NULL;
1440
1441 /* register arch-specific functions */
1442 armv7m->examine_debug_reason = cortex_m3_examine_debug_reason;
1443
1444 armv7m->pre_debug_entry = NULL;
1445 armv7m->post_debug_entry = NULL;
1446
1447 armv7m->pre_restore_context = NULL;
1448 armv7m->post_restore_context = NULL;
1449
1450 armv7m_init_arch_info(target, armv7m);
1451 armv7m->arch_info = cortex_m3;
1452 armv7m->load_core_reg_u32 = cortex_m3_load_core_reg_u32;
1453 armv7m->store_core_reg_u32 = cortex_m3_store_core_reg_u32;
1454
1455 target_register_timer_callback(cortex_m3_handle_target_request, 1, 1, target);
1456
1457 return ERROR_OK;
1458 }
1459
1460 /* target cortex_m3 <endianess> <startup_mode> <chain_pos> <variant>*/
1461 int cortex_m3_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
1462 {
1463 int chain_pos;
1464 char *variant = NULL;
1465 cortex_m3_common_t *cortex_m3 = malloc(sizeof(cortex_m3_common_t));
1466 memset(cortex_m3, 0, sizeof(*cortex_m3));
1467
1468 if (argc < 4)
1469 {
1470 ERROR("'target cortex_m3' requires at least one additional argument");
1471 exit(-1);
1472 }
1473
1474 chain_pos = strtoul(args[3], NULL, 0);
1475
1476 if (argc >= 5)
1477 variant = args[4];
1478
1479 cortex_m3_init_arch_info(target, cortex_m3, chain_pos, variant);
1480 cortex_m3_register_commands(cmd_ctx);
1481
1482 return ERROR_OK;
1483 }
1484
1485 int cortex_m3_register_commands(struct command_context_s *cmd_ctx)
1486 {
1487 int retval;
1488
1489 retval = armv7m_register_commands(cmd_ctx);
1490
1491 return retval;
1492 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)