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

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)