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

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)