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

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)