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

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)