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

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)