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

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)