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

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)