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