- jtag_khz/speed are now single parameter only. These are used
[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 command_context_s *cmd_ctx, 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 return ERROR_OK;
766 }
767
768 int cortex_m3_deassert_reset(target_t *target)
769 {
770 LOG_DEBUG("target->state: %s", target_state_strings[target->state]);
771
772 /* deassert reset lines */
773 jtag_add_reset(0, 0);
774
775 return ERROR_OK;
776 }
777
778 void cortex_m3_enable_breakpoints(struct target_s *target)
779 {
780 breakpoint_t *breakpoint = target->breakpoints;
781
782 /* set any pending breakpoints */
783 while (breakpoint)
784 {
785 if (breakpoint->set == 0)
786 cortex_m3_set_breakpoint(target, breakpoint);
787 breakpoint = breakpoint->next;
788 }
789 }
790
791 int cortex_m3_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
792 {
793 int fp_num=0;
794 u32 hilo;
795
796 /* get pointers to arch-specific information */
797 armv7m_common_t *armv7m = target->arch_info;
798 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
799
800 cortex_m3_fp_comparator_t * comparator_list = cortex_m3->fp_comparator_list;
801
802 if (breakpoint->set)
803 {
804 LOG_WARNING("breakpoint already set");
805 return ERROR_OK;
806 }
807
808 if (cortex_m3->auto_bp_type)
809 {
810 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
811 }
812
813 if (breakpoint->type == BKPT_HARD)
814 {
815 while(comparator_list[fp_num].used && (fp_num < cortex_m3->fp_num_code))
816 fp_num++;
817 if (fp_num >= cortex_m3->fp_num_code)
818 {
819 LOG_DEBUG("ERROR Can not find free FP Comparator");
820 LOG_WARNING("ERROR Can not find free FP Comparator");
821 exit(-1);
822 }
823 breakpoint->set = fp_num + 1;
824 hilo = (breakpoint->address & 0x2) ? FPCR_REPLACE_BKPT_HIGH : FPCR_REPLACE_BKPT_LOW;
825 comparator_list[fp_num].used = 1;
826 comparator_list[fp_num].fpcr_value = (breakpoint->address & 0x1FFFFFFC) | hilo | 1;
827 target_write_u32(target, comparator_list[fp_num].fpcr_address, comparator_list[fp_num].fpcr_value);
828 LOG_DEBUG("fpc_num %i fpcr_value 0x%x", fp_num, comparator_list[fp_num].fpcr_value);
829 }
830 else if (breakpoint->type == BKPT_SOFT)
831 {
832 u8 code[4];
833 buf_set_u32(code, 0, 32, ARMV7M_T_BKPT(0x11));
834 target->type->read_memory(target, breakpoint->address & 0xFFFFFFFE, breakpoint->length, 1, breakpoint->orig_instr);
835 target->type->write_memory(target, breakpoint->address & 0xFFFFFFFE, breakpoint->length, 1, code);
836 breakpoint->set = 0x11; /* Any nice value but 0 */
837 }
838
839 return ERROR_OK;
840 }
841
842 int cortex_m3_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
843 {
844 /* get pointers to arch-specific information */
845 armv7m_common_t *armv7m = target->arch_info;
846 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
847 cortex_m3_fp_comparator_t * comparator_list = cortex_m3->fp_comparator_list;
848
849 if (!breakpoint->set)
850 {
851 LOG_WARNING("breakpoint not set");
852 return ERROR_OK;
853 }
854
855 if (breakpoint->type == BKPT_HARD)
856 {
857 int fp_num = breakpoint->set - 1;
858 if ((fp_num < 0) || (fp_num >= cortex_m3->fp_num_code))
859 {
860 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
861 return ERROR_OK;
862 }
863 comparator_list[fp_num].used = 0;
864 comparator_list[fp_num].fpcr_value = 0;
865 target_write_u32(target, comparator_list[fp_num].fpcr_address, comparator_list[fp_num].fpcr_value);
866 }
867 else
868 {
869 /* restore original instruction (kept in target endianness) */
870 if (breakpoint->length == 4)
871 {
872 target->type->write_memory(target, breakpoint->address & 0xFFFFFFFE, 4, 1, breakpoint->orig_instr);
873 }
874 else
875 {
876 target->type->write_memory(target, breakpoint->address & 0xFFFFFFFE, 2, 1, breakpoint->orig_instr);
877 }
878 }
879 breakpoint->set = 0;
880
881 return ERROR_OK;
882 }
883
884 int cortex_m3_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
885 {
886 /* get pointers to arch-specific information */
887 armv7m_common_t *armv7m = target->arch_info;
888 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
889
890 if (cortex_m3->auto_bp_type)
891 {
892 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
893 #ifdef ARMV7_GDB_HACKS
894 if (breakpoint->length != 2) {
895 /* XXX Hack: Replace all breakpoints with length != 2 with
896 * a hardware breakpoint. */
897 breakpoint->type = BKPT_HARD;
898 breakpoint->length = 2;
899 }
900 #endif
901 }
902
903 if ((breakpoint->type == BKPT_HARD) && (breakpoint->address >= 0x20000000))
904 {
905 LOG_INFO("flash patch comparator requested outside code memory region");
906 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
907 }
908
909 if ((breakpoint->type == BKPT_SOFT) && (breakpoint->address < 0x20000000))
910 {
911 LOG_INFO("soft breakpoint requested in code (flash) memory region");
912 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
913 }
914
915 if ((breakpoint->type == BKPT_HARD) && (cortex_m3->fp_code_available < 1))
916 {
917 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
918 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
919 }
920
921 if ((breakpoint->length != 2))
922 {
923 LOG_INFO("only breakpoints of two bytes length supported");
924 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
925 }
926
927 if (breakpoint->type == BKPT_HARD)
928 cortex_m3->fp_code_available--;
929 cortex_m3_set_breakpoint(target, breakpoint);
930
931 return ERROR_OK;
932 }
933
934 int cortex_m3_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
935 {
936 /* get pointers to arch-specific information */
937 armv7m_common_t *armv7m = target->arch_info;
938 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
939
940 if (target->state != TARGET_HALTED)
941 {
942 LOG_WARNING("target not halted");
943 return ERROR_TARGET_NOT_HALTED;
944 }
945
946 if (cortex_m3->auto_bp_type)
947 {
948 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
949 }
950
951 if (breakpoint->set)
952 {
953 cortex_m3_unset_breakpoint(target, breakpoint);
954 }
955
956 if (breakpoint->type == BKPT_HARD)
957 cortex_m3->fp_code_available++;
958
959 return ERROR_OK;
960 }
961
962 int cortex_m3_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
963 {
964 int dwt_num=0;
965 u32 mask, temp;
966
967 /* get pointers to arch-specific information */
968 armv7m_common_t *armv7m = target->arch_info;
969 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
970 cortex_m3_dwt_comparator_t * comparator_list = cortex_m3->dwt_comparator_list;
971
972 if (watchpoint->set)
973 {
974 LOG_WARNING("watchpoint already set");
975 return ERROR_OK;
976 }
977
978 if (watchpoint->mask == 0xffffffffu)
979 {
980 while(comparator_list[dwt_num].used && (dwt_num < cortex_m3->dwt_num_comp))
981 dwt_num++;
982 if (dwt_num >= cortex_m3->dwt_num_comp)
983 {
984 LOG_DEBUG("ERROR Can not find free DWT Comparator");
985 LOG_WARNING("ERROR Can not find free DWT Comparator");
986 return -1;
987 }
988 watchpoint->set = dwt_num + 1;
989 mask = 0;
990 temp = watchpoint->length;
991 while (temp > 1)
992 {
993 temp = temp / 2;
994 mask++;
995 }
996 comparator_list[dwt_num].used = 1;
997 comparator_list[dwt_num].comp = watchpoint->address;
998 comparator_list[dwt_num].mask = mask;
999 comparator_list[dwt_num].function = watchpoint->rw + 5;
1000 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address, comparator_list[dwt_num].comp);
1001 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address|0x4, comparator_list[dwt_num].mask);
1002 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address|0x8, comparator_list[dwt_num].function);
1003 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);
1004 }
1005 else
1006 {
1007 LOG_WARNING("Cannot watch data values"); /* Move this test to add_watchpoint */
1008 return ERROR_OK;
1009 }
1010
1011 return ERROR_OK;
1012
1013 }
1014
1015 int cortex_m3_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1016 {
1017 /* get pointers to arch-specific information */
1018 armv7m_common_t *armv7m = target->arch_info;
1019 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1020 cortex_m3_dwt_comparator_t * comparator_list = cortex_m3->dwt_comparator_list;
1021 int dwt_num;
1022
1023 if (!watchpoint->set)
1024 {
1025 LOG_WARNING("watchpoint not set");
1026 return ERROR_OK;
1027 }
1028
1029 dwt_num = watchpoint->set - 1;
1030
1031 if ((dwt_num < 0) || (dwt_num >= cortex_m3->dwt_num_comp))
1032 {
1033 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1034 return ERROR_OK;
1035 }
1036 comparator_list[dwt_num].used = 0;
1037 comparator_list[dwt_num].function = 0;
1038 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address|0x8, comparator_list[dwt_num].function);
1039
1040 watchpoint->set = 0;
1041
1042 return ERROR_OK;
1043 }
1044
1045 int cortex_m3_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1046 {
1047 /* get pointers to arch-specific information */
1048 armv7m_common_t *armv7m = target->arch_info;
1049 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1050
1051 if (target->state != TARGET_HALTED)
1052 {
1053 LOG_WARNING("target not halted");
1054 return ERROR_TARGET_NOT_HALTED;
1055 }
1056
1057 if (cortex_m3->dwt_comp_available < 1)
1058 {
1059 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1060 }
1061
1062 if ((watchpoint->length != 1) && (watchpoint->length != 2) && (watchpoint->length != 4))
1063 {
1064 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1065 }
1066
1067 cortex_m3->dwt_comp_available--;
1068
1069 return ERROR_OK;
1070 }
1071
1072 int cortex_m3_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1073 {
1074 /* get pointers to arch-specific information */
1075 armv7m_common_t *armv7m = target->arch_info;
1076 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1077
1078 if (target->state != TARGET_HALTED)
1079 {
1080 LOG_WARNING("target not halted");
1081 return ERROR_TARGET_NOT_HALTED;
1082 }
1083
1084 if (watchpoint->set)
1085 {
1086 cortex_m3_unset_watchpoint(target, watchpoint);
1087 }
1088
1089 cortex_m3->dwt_comp_available++;
1090
1091 return ERROR_OK;
1092 }
1093
1094 void cortex_m3_enable_watchpoints(struct target_s *target)
1095 {
1096 watchpoint_t *watchpoint = target->watchpoints;
1097
1098 /* set any pending watchpoints */
1099 while (watchpoint)
1100 {
1101 if (watchpoint->set == 0)
1102 cortex_m3_set_watchpoint(target, watchpoint);
1103 watchpoint = watchpoint->next;
1104 }
1105 }
1106
1107 int cortex_m3_load_core_reg_u32(struct target_s *target, enum armv7m_regtype type, u32 num, u32 * value)
1108 {
1109 int retval;
1110 /* get pointers to arch-specific information */
1111 armv7m_common_t *armv7m = target->arch_info;
1112 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1113 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1114
1115 if ((type == ARMV7M_REGISTER_CORE_GP) && (num <= ARMV7M_PSP))
1116 {
1117 /* read a normal core register */
1118 retval = ahbap_read_coreregister_u32(swjdp, value, num);
1119
1120 if (retval != ERROR_OK)
1121 {
1122 LOG_ERROR("JTAG failure %i",retval);
1123 return ERROR_JTAG_DEVICE_ERROR;
1124 }
1125 LOG_DEBUG("load from core reg %i value 0x%x",num,*value);
1126 }
1127 else if (type == ARMV7M_REGISTER_CORE_SP) /* Special purpose core register */
1128 {
1129 /* read other registers */
1130 ahbap_read_coreregister_u32(swjdp, value, 20);
1131
1132 switch (num)
1133 {
1134 case 19:
1135 *value = buf_get_u32((u8*)value, 0, 8);
1136 break;
1137
1138 case 20:
1139 *value = buf_get_u32((u8*)value, 8, 8);
1140 break;
1141
1142 case 21:
1143 *value = buf_get_u32((u8*)value, 16, 8);
1144 break;
1145
1146 case 22:
1147 *value = buf_get_u32((u8*)value, 24, 8);
1148 break;
1149 }
1150
1151 LOG_DEBUG("load from special reg %i value 0x%x", num, *value);
1152 }
1153 else
1154 {
1155 return ERROR_INVALID_ARGUMENTS;
1156 }
1157
1158 return ERROR_OK;
1159 }
1160
1161 int cortex_m3_store_core_reg_u32(struct target_s *target, enum armv7m_regtype type, u32 num, u32 value)
1162 {
1163 int retval;
1164 u32 reg;
1165
1166 /* get pointers to arch-specific information */
1167 armv7m_common_t *armv7m = target->arch_info;
1168 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1169 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1170
1171 #ifdef ARMV7_GDB_HACKS
1172 /* If the LR register is being modified, make sure it will put us
1173 * in "thumb" mode, or an INVSTATE exception will occur. This is a
1174 * hack to deal with the fact that gdb will sometimes "forge"
1175 * return addresses, and doesn't set the LSB correctly (i.e., when
1176 * printing expressions containing function calls, it sets LR=0.) */
1177
1178 if (num == 14)
1179 value |= 0x01;
1180 #endif
1181
1182 if ((type == ARMV7M_REGISTER_CORE_GP) && (num <= ARMV7M_PSP))
1183 {
1184 retval = ahbap_write_coreregister_u32(swjdp, value, num);
1185 if (retval != ERROR_OK)
1186 {
1187 LOG_ERROR("JTAG failure %i", retval);
1188 armv7m->core_cache->reg_list[num].dirty = armv7m->core_cache->reg_list[num].valid;
1189 return ERROR_JTAG_DEVICE_ERROR;
1190 }
1191 LOG_DEBUG("write core reg %i value 0x%x", num, value);
1192 }
1193 else if (type == ARMV7M_REGISTER_CORE_SP) /* Special purpose core register */
1194 {
1195 /* write other registers */
1196
1197 ahbap_read_coreregister_u32(swjdp, &reg, 20);
1198
1199 switch (num)
1200 {
1201 case 19:
1202 buf_set_u32((u8*)&reg, 0, 8, value);
1203 break;
1204
1205 case 20:
1206 buf_set_u32((u8*)&reg, 8, 8, value);
1207 break;
1208
1209 case 21:
1210 buf_set_u32((u8*)&reg, 16, 8, value);
1211 break;
1212
1213 case 22:
1214 buf_set_u32((u8*)&reg, 24, 8, value);
1215 break;
1216 }
1217
1218 ahbap_write_coreregister_u32(swjdp, reg, 20);
1219
1220 LOG_DEBUG("write special reg %i value 0x%x ", num, value);
1221 }
1222 else
1223 {
1224 return ERROR_INVALID_ARGUMENTS;
1225 }
1226
1227 return ERROR_OK;
1228 }
1229
1230 int cortex_m3_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1231 {
1232 /* get pointers to arch-specific information */
1233 armv7m_common_t *armv7m = target->arch_info;
1234 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1235 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1236 int retval;
1237
1238 /* sanitize arguments */
1239 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1240 return ERROR_INVALID_ARGUMENTS;
1241
1242 /* cortex_m3 handles unaligned memory access */
1243
1244 switch (size)
1245 {
1246 case 4:
1247 retval = ahbap_read_buf_u32(swjdp, buffer, 4 * count, address);
1248 break;
1249 case 2:
1250 retval = ahbap_read_buf_u16(swjdp, buffer, 2 * count, address);
1251 break;
1252 case 1:
1253 retval = ahbap_read_buf_u8(swjdp, buffer, count, address);
1254 break;
1255 default:
1256 LOG_ERROR("BUG: we shouldn't get here");
1257 exit(-1);
1258 }
1259
1260 return retval;
1261 }
1262
1263 int cortex_m3_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1264 {
1265 /* get pointers to arch-specific information */
1266 armv7m_common_t *armv7m = target->arch_info;
1267 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1268 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1269 int retval;
1270
1271 /* sanitize arguments */
1272 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1273 return ERROR_INVALID_ARGUMENTS;
1274
1275 switch (size)
1276 {
1277 case 4:
1278 retval = ahbap_write_buf_u32(swjdp, buffer, 4 * count, address);
1279 break;
1280 case 2:
1281 retval = ahbap_write_buf_u16(swjdp, buffer, 2 * count, address);
1282 break;
1283 case 1:
1284 retval = ahbap_write_buf_u8(swjdp, buffer, count, address);
1285 break;
1286 default:
1287 LOG_ERROR("BUG: we shouldn't get here");
1288 exit(-1);
1289 }
1290
1291 return retval;
1292 }
1293
1294 int cortex_m3_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer)
1295 {
1296 return cortex_m3_write_memory(target, address, 4, count, buffer);
1297 }
1298
1299 void cortex_m3_build_reg_cache(target_t *target)
1300 {
1301 armv7m_build_reg_cache(target);
1302 }
1303
1304 int cortex_m3_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
1305 {
1306 cortex_m3_build_reg_cache(target);
1307 return ERROR_OK;
1308 }
1309
1310 int cortex_m3_examine(struct command_context_s *cmd_ctx, struct target_s *target)
1311 {
1312 int retval;
1313 u32 cpuid, fpcr, dwtcr, ictr;
1314 int i;
1315
1316 /* get pointers to arch-specific information */
1317 armv7m_common_t *armv7m = target->arch_info;
1318 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1319 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1320
1321 target->type->examined = 1;
1322
1323 if ((retval=ahbap_debugport_init(swjdp))!=ERROR_OK)
1324 return retval;
1325
1326 /* Read from Device Identification Registers */
1327 if ((retval=target_read_u32(target, CPUID, &cpuid))!=ERROR_OK)
1328 return retval;
1329
1330 if (((cpuid >> 4) & 0xc3f) == 0xc23)
1331 LOG_DEBUG("CORTEX-M3 processor detected");
1332 LOG_DEBUG("cpuid: 0x%8.8x", cpuid);
1333
1334 target_read_u32(target, NVIC_ICTR, &ictr);
1335 cortex_m3->intlinesnum = (ictr & 0x1F) + 1;
1336 cortex_m3->intsetenable = calloc(cortex_m3->intlinesnum, 4);
1337 for (i = 0; i < cortex_m3->intlinesnum; i++)
1338 {
1339 target_read_u32(target, NVIC_ISE0 + 4 * i, cortex_m3->intsetenable + i);
1340 LOG_DEBUG("interrupt enable[%i] = 0x%8.8x", i, cortex_m3->intsetenable[i]);
1341 }
1342
1343 /* Setup FPB */
1344 target_read_u32(target, FP_CTRL, &fpcr);
1345 cortex_m3->auto_bp_type = 1;
1346 cortex_m3->fp_num_code = (fpcr >> 4) & 0xF;
1347 cortex_m3->fp_num_lit = (fpcr >> 8) & 0xF;
1348 cortex_m3->fp_code_available = cortex_m3->fp_num_code;
1349 cortex_m3->fp_comparator_list = calloc(cortex_m3->fp_num_code + cortex_m3->fp_num_lit, sizeof(cortex_m3_fp_comparator_t));
1350 for (i = 0; i < cortex_m3->fp_num_code + cortex_m3->fp_num_lit; i++)
1351 {
1352 cortex_m3->fp_comparator_list[i].type = (i < cortex_m3->fp_num_code) ? FPCR_CODE : FPCR_LITERAL;
1353 cortex_m3->fp_comparator_list[i].fpcr_address = FP_COMP0 + 4 * i;
1354 }
1355 LOG_DEBUG("FPB fpcr 0x%x, numcode %i, numlit %i", fpcr, cortex_m3->fp_num_code, cortex_m3->fp_num_lit);
1356
1357 /* Setup DWT */
1358 target_read_u32(target, DWT_CTRL, &dwtcr);
1359 cortex_m3->dwt_num_comp = (dwtcr >> 28) & 0xF;
1360 cortex_m3->dwt_comp_available = cortex_m3->dwt_num_comp;
1361 cortex_m3->dwt_comparator_list=calloc(cortex_m3->dwt_num_comp, sizeof(cortex_m3_dwt_comparator_t));
1362 for (i = 0; i < cortex_m3->dwt_num_comp; i++)
1363 {
1364 cortex_m3->dwt_comparator_list[i].dwt_comparator_address = DWT_COMP0 + 0x10 * i;
1365 }
1366
1367 return ERROR_OK;
1368 }
1369
1370 int cortex_m3_quit()
1371 {
1372
1373 return ERROR_OK;
1374 }
1375
1376 int cortex_m3_dcc_read(swjdp_common_t *swjdp, u8 *value, u8 *ctrl)
1377 {
1378 u16 dcrdr;
1379
1380 ahbap_read_buf_u16( swjdp, (u8*)&dcrdr, 1, DCB_DCRDR);
1381 *ctrl = (u8)dcrdr;
1382 *value = (u8)(dcrdr >> 8);
1383
1384 LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
1385
1386 /* write ack back to software dcc register
1387 * signify we have read data */
1388 if (dcrdr & (1 << 0))
1389 {
1390 dcrdr = 0;
1391 ahbap_write_buf_u16( swjdp, (u8*)&dcrdr, 1, DCB_DCRDR);
1392 }
1393
1394 return ERROR_OK;
1395 }
1396
1397 int cortex_m3_target_request_data(target_t *target, u32 size, u8 *buffer)
1398 {
1399 armv7m_common_t *armv7m = target->arch_info;
1400 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1401 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1402 u8 data;
1403 u8 ctrl;
1404 int i;
1405
1406 for (i = 0; i < (size * 4); i++)
1407 {
1408 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1409 buffer[i] = data;
1410 }
1411
1412 return ERROR_OK;
1413 }
1414
1415 int cortex_m3_handle_target_request(void *priv)
1416 {
1417 target_t *target = priv;
1418 if (!target->type->examined)
1419 return ERROR_OK;
1420 armv7m_common_t *armv7m = target->arch_info;
1421 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1422 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1423
1424 if (!target->dbg_msg_enabled)
1425 return ERROR_OK;
1426
1427 if (target->state == TARGET_RUNNING)
1428 {
1429 u8 data;
1430 u8 ctrl;
1431
1432 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1433
1434 /* check if we have data */
1435 if (ctrl & (1 << 0))
1436 {
1437 u32 request;
1438
1439 /* we assume target is quick enough */
1440 request = data;
1441 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1442 request |= (data << 8);
1443 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1444 request |= (data << 16);
1445 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1446 request |= (data << 24);
1447 target_request(target, request);
1448 }
1449 }
1450
1451 return ERROR_OK;
1452 }
1453
1454 int cortex_m3_init_arch_info(target_t *target, cortex_m3_common_t *cortex_m3, int chain_pos, char *variant)
1455 {
1456 armv7m_common_t *armv7m;
1457 armv7m = &cortex_m3->armv7m;
1458
1459 /* prepare JTAG information for the new target */
1460 cortex_m3->jtag_info.chain_pos = chain_pos;
1461 cortex_m3->jtag_info.scann_size = 4;
1462
1463 cortex_m3->swjdp_info.dp_select_value = -1;
1464 cortex_m3->swjdp_info.ap_csw_value = -1;
1465 cortex_m3->swjdp_info.ap_tar_value = -1;
1466 cortex_m3->swjdp_info.jtag_info = &cortex_m3->jtag_info;
1467
1468 /* initialize arch-specific breakpoint handling */
1469
1470 cortex_m3->common_magic = CORTEX_M3_COMMON_MAGIC;
1471 cortex_m3->arch_info = NULL;
1472
1473 /* register arch-specific functions */
1474 armv7m->examine_debug_reason = cortex_m3_examine_debug_reason;
1475
1476 armv7m->pre_debug_entry = NULL;
1477 armv7m->post_debug_entry = NULL;
1478
1479 armv7m->pre_restore_context = NULL;
1480 armv7m->post_restore_context = NULL;
1481
1482 if (variant)
1483 {
1484 cortex_m3->variant = strdup(variant);
1485 }
1486 else
1487 {
1488 cortex_m3->variant = strdup("");
1489 }
1490
1491 armv7m_init_arch_info(target, armv7m);
1492 armv7m->arch_info = cortex_m3;
1493 armv7m->load_core_reg_u32 = cortex_m3_load_core_reg_u32;
1494 armv7m->store_core_reg_u32 = cortex_m3_store_core_reg_u32;
1495
1496 target_register_timer_callback(cortex_m3_handle_target_request, 1, 1, target);
1497
1498 return ERROR_OK;
1499 }
1500
1501 /* target cortex_m3 <endianess> <startup_mode> <chain_pos> <variant>*/
1502 int cortex_m3_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
1503 {
1504 int chain_pos;
1505 char *variant = NULL;
1506 cortex_m3_common_t *cortex_m3 = malloc(sizeof(cortex_m3_common_t));
1507 memset(cortex_m3, 0, sizeof(*cortex_m3));
1508
1509 if (argc < 4)
1510 {
1511 LOG_ERROR("'target cortex_m3' requires at least one additional argument");
1512 exit(-1);
1513 }
1514
1515 chain_pos = strtoul(args[3], NULL, 0);
1516
1517 if (argc >= 5)
1518 variant = args[4];
1519
1520 cortex_m3_init_arch_info(target, cortex_m3, chain_pos, variant);
1521
1522 return ERROR_OK;
1523 }
1524
1525 int cortex_m3_register_commands(struct command_context_s *cmd_ctx)
1526 {
1527 int retval;
1528
1529 retval = armv7m_register_commands(cmd_ctx);
1530
1531 return retval;
1532 }

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)