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

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)