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

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)