Laurentiu Cocanu - memory read/write and exit() error path fixes
[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 /* We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
567 * This is probably the same inssue as Cortex-M3 Errata 377493:
568 * C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken. */
569 buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_PRIMASK].value, 0, 32, 1);
570 /* Make sure we are in Thumb mode */
571 buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32,
572 buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32) | (1<<24));
573 }
574
575 /* current = 1: continue on current pc, otherwise continue at <address> */
576 if (!current)
577 {
578 buf_set_u32(armv7m->core_cache->reg_list[15].value, 0, 32, address);
579 armv7m->core_cache->reg_list[15].dirty = 1;
580 armv7m->core_cache->reg_list[15].valid = 1;
581 }
582
583 resume_pc = buf_get_u32(armv7m->core_cache->reg_list[15].value, 0, 32);
584
585 armv7m_restore_context(target);
586
587 /* the front-end may request us not to handle breakpoints */
588 if (handle_breakpoints)
589 {
590 /* Single step past breakpoint at current address */
591 if ((breakpoint = breakpoint_find(target, resume_pc)))
592 {
593 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint->address);
594 cortex_m3_unset_breakpoint(target, breakpoint);
595 cortex_m3_single_step_core(target);
596 cortex_m3_set_breakpoint(target, breakpoint);
597 }
598 }
599
600 /* Set/Clear C_MASKINTS in a separate operation */
601 if ((cortex_m3->dcb_dhcsr & C_MASKINTS) != (dcb_dhcsr & C_MASKINTS))
602 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, dcb_dhcsr | C_HALT );
603
604 /* Restart core */
605 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, dcb_dhcsr );
606 target->debug_reason = DBG_REASON_NOTHALTED;
607
608 /* registers are now invalid */
609 armv7m_invalidate_core_regs(target);
610 if (!debug_execution)
611 {
612 target->state = TARGET_RUNNING;
613 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
614 LOG_DEBUG("target resumed at 0x%x",resume_pc);
615 }
616 else
617 {
618 target->state = TARGET_DEBUG_RUNNING;
619 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
620 LOG_DEBUG("target debug resumed at 0x%x",resume_pc);
621 }
622
623 return ERROR_OK;
624 }
625
626 /* int irqstepcount=0; */
627 int cortex_m3_step(struct target_s *target, int current, u32 address, int handle_breakpoints)
628 {
629 /* get pointers to arch-specific information */
630 armv7m_common_t *armv7m = target->arch_info;
631 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
632 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
633 breakpoint_t *breakpoint = NULL;
634
635 if (target->state != TARGET_HALTED)
636 {
637 LOG_WARNING("target not halted");
638 return ERROR_TARGET_NOT_HALTED;
639 }
640
641 /* current = 1: continue on current pc, otherwise continue at <address> */
642 if (!current)
643 buf_set_u32(armv7m->core_cache->reg_list[15].value, 0, 32, address);
644
645 /* the front-end may request us not to handle breakpoints */
646 if (handle_breakpoints)
647 if ((breakpoint = breakpoint_find(target, buf_get_u32(armv7m->core_cache->reg_list[15].value, 0, 32))))
648 cortex_m3_unset_breakpoint(target, breakpoint);
649
650 target->debug_reason = DBG_REASON_SINGLESTEP;
651
652 armv7m_restore_context(target);
653
654 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
655
656 if (cortex_m3->dcb_dhcsr & C_MASKINTS)
657 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN );
658 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY| C_STEP | C_DEBUGEN);
659 ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
660
661 /* registers are now invalid */
662 armv7m_invalidate_core_regs(target);
663
664 if (breakpoint)
665 cortex_m3_set_breakpoint(target, breakpoint);
666
667 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3->dcb_dhcsr, cortex_m3->nvic_icsr);
668
669 cortex_m3_debug_entry(target);
670 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
671
672 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3->dcb_dhcsr, cortex_m3->nvic_icsr);
673 return ERROR_OK;
674 }
675
676 int cortex_m3_assert_reset(target_t *target)
677 {
678 armv7m_common_t *armv7m = target->arch_info;
679 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
680 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
681 int assert_srst = 1;
682
683 LOG_DEBUG("target->state: %s",
684 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name );
685
686 if (!(jtag_reset_config & RESET_HAS_SRST))
687 {
688 LOG_ERROR("Can't assert SRST");
689 return ERROR_FAIL;
690 }
691
692 /* Enable debug requests */
693 ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
694 if (!(cortex_m3->dcb_dhcsr & C_DEBUGEN))
695 ahbap_write_system_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN );
696
697 ahbap_write_system_u32(swjdp, DCB_DCRDR, 0 );
698
699 if (!target->reset_halt)
700 {
701 /* Set/Clear C_MASKINTS in a separate operation */
702 if (cortex_m3->dcb_dhcsr & C_MASKINTS)
703 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN | C_HALT );
704
705 cortex_m3_clear_halt(target);
706
707 /* Enter debug state on reset, cf. end_reset_event() */
708 ahbap_write_system_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR);
709 }
710 else
711 {
712 /* Enter debug state on reset, cf. end_reset_event() */
713 ahbap_write_system_atomic_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET );
714 }
715
716 /* following hack is to handle luminary reset
717 * when srst is asserted the luminary device seesm to also clear the debug registers
718 * which does not match the armv7 debug TRM */
719
720 if (strcmp(cortex_m3->variant, "lm3s") == 0)
721 {
722 /* get revision of lm3s target, only early silicon has this issue
723 * Fury Rev B, DustDevil Rev B, Tempest all ok */
724
725 u32 did0;
726
727 if (target_read_u32(target, 0x400fe000, &did0) == ERROR_OK)
728 {
729 switch ((did0 >> 16) & 0xff)
730 {
731 case 0:
732 /* all Sandstorm suffer issue */
733 assert_srst = 0;
734 break;
735
736 case 1:
737 case 3:
738 /* only Fury/DustDevil rev A suffer reset problems */
739 if (((did0 >> 8) & 0xff) == 0)
740 assert_srst = 0;
741 break;
742 }
743 }
744 }
745
746 if (assert_srst)
747 {
748 /* default to asserting srst */
749 if (jtag_reset_config & RESET_SRST_PULLS_TRST)
750 {
751 jtag_add_reset(1, 1);
752 }
753 else
754 {
755 jtag_add_reset(0, 1);
756 }
757 }
758 else
759 {
760 /* this causes the luminary device to reset using the watchdog */
761 ahbap_write_system_atomic_u32(swjdp, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_SYSRESETREQ );
762 LOG_DEBUG("Using Luminary Reset: SYSRESETREQ");
763
764 {
765 /* I do not know why this is necessary, but it fixes strange effects
766 * (step/resume cause a NMI after reset) on LM3S6918 -- Michael Schwingen */
767 u32 tmp;
768 ahbap_read_system_atomic_u32(swjdp, NVIC_AIRCR, &tmp );
769 }
770 }
771
772 target->state = TARGET_RESET;
773 jtag_add_sleep(50000);
774
775 armv7m_invalidate_core_regs(target);
776
777 if (target->reset_halt)
778 {
779 int retval;
780 if ((retval = target_halt(target))!=ERROR_OK)
781 return retval;
782 }
783
784 return ERROR_OK;
785 }
786
787 int cortex_m3_deassert_reset(target_t *target)
788 {
789 LOG_DEBUG("target->state: %s",
790 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
791
792 /* deassert reset lines */
793 jtag_add_reset(0, 0);
794
795 return ERROR_OK;
796 }
797
798 void cortex_m3_enable_breakpoints(struct target_s *target)
799 {
800 breakpoint_t *breakpoint = target->breakpoints;
801
802 /* set any pending breakpoints */
803 while (breakpoint)
804 {
805 if (breakpoint->set == 0)
806 cortex_m3_set_breakpoint(target, breakpoint);
807 breakpoint = breakpoint->next;
808 }
809 }
810
811 int cortex_m3_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
812 {
813 int retval;
814 int fp_num=0;
815 u32 hilo;
816
817 /* get pointers to arch-specific information */
818 armv7m_common_t *armv7m = target->arch_info;
819 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
820
821 cortex_m3_fp_comparator_t * comparator_list = cortex_m3->fp_comparator_list;
822
823 if (breakpoint->set)
824 {
825 LOG_WARNING("breakpoint already set");
826 return ERROR_OK;
827 }
828
829 if (cortex_m3->auto_bp_type)
830 {
831 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
832 }
833
834 if (breakpoint->type == BKPT_HARD)
835 {
836 while(comparator_list[fp_num].used && (fp_num < cortex_m3->fp_num_code))
837 fp_num++;
838 if (fp_num >= cortex_m3->fp_num_code)
839 {
840 LOG_DEBUG("ERROR Can not find free FP Comparator");
841 LOG_WARNING("ERROR Can not find free FP Comparator");
842 exit(-1);
843 }
844 breakpoint->set = fp_num + 1;
845 hilo = (breakpoint->address & 0x2) ? FPCR_REPLACE_BKPT_HIGH : FPCR_REPLACE_BKPT_LOW;
846 comparator_list[fp_num].used = 1;
847 comparator_list[fp_num].fpcr_value = (breakpoint->address & 0x1FFFFFFC) | hilo | 1;
848 target_write_u32(target, comparator_list[fp_num].fpcr_address, comparator_list[fp_num].fpcr_value);
849 LOG_DEBUG("fpc_num %i fpcr_value 0x%x", fp_num, comparator_list[fp_num].fpcr_value);
850 }
851 else if (breakpoint->type == BKPT_SOFT)
852 {
853 u8 code[4];
854 buf_set_u32(code, 0, 32, ARMV7M_T_BKPT(0x11));
855 if((retval = target->type->read_memory(target, breakpoint->address & 0xFFFFFFFE, breakpoint->length, 1, breakpoint->orig_instr)) != ERROR_OK)
856 {
857 return retval;
858 }
859 if((retval = target->type->write_memory(target, breakpoint->address & 0xFFFFFFFE, breakpoint->length, 1, code)) != ERROR_OK)
860 {
861 return retval;
862 }
863 breakpoint->set = 0x11; /* Any nice value but 0 */
864 }
865
866 return ERROR_OK;
867 }
868
869 int cortex_m3_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
870 {
871 int retval;
872 /* get pointers to arch-specific information */
873 armv7m_common_t *armv7m = target->arch_info;
874 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
875 cortex_m3_fp_comparator_t * comparator_list = cortex_m3->fp_comparator_list;
876
877 if (!breakpoint->set)
878 {
879 LOG_WARNING("breakpoint not set");
880 return ERROR_OK;
881 }
882
883 if (breakpoint->type == BKPT_HARD)
884 {
885 int fp_num = breakpoint->set - 1;
886 if ((fp_num < 0) || (fp_num >= cortex_m3->fp_num_code))
887 {
888 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
889 return ERROR_OK;
890 }
891 comparator_list[fp_num].used = 0;
892 comparator_list[fp_num].fpcr_value = 0;
893 target_write_u32(target, comparator_list[fp_num].fpcr_address, comparator_list[fp_num].fpcr_value);
894 }
895 else
896 {
897 /* restore original instruction (kept in target endianness) */
898 if (breakpoint->length == 4)
899 {
900 if((retval = target->type->write_memory(target, breakpoint->address & 0xFFFFFFFE, 4, 1, breakpoint->orig_instr)) != ERROR_OK)
901 {
902 return retval;
903 }
904 }
905 else
906 {
907 if((retval = target->type->write_memory(target, breakpoint->address & 0xFFFFFFFE, 2, 1, breakpoint->orig_instr)) != ERROR_OK)
908 {
909 return retval;
910 }
911 }
912 }
913 breakpoint->set = 0;
914
915 return ERROR_OK;
916 }
917
918 int cortex_m3_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
919 {
920 /* get pointers to arch-specific information */
921 armv7m_common_t *armv7m = target->arch_info;
922 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
923
924 if (cortex_m3->auto_bp_type)
925 {
926 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
927 #ifdef ARMV7_GDB_HACKS
928 if (breakpoint->length != 2) {
929 /* XXX Hack: Replace all breakpoints with length != 2 with
930 * a hardware breakpoint. */
931 breakpoint->type = BKPT_HARD;
932 breakpoint->length = 2;
933 }
934 #endif
935 }
936
937 if ((breakpoint->type == BKPT_HARD) && (breakpoint->address >= 0x20000000))
938 {
939 LOG_INFO("flash patch comparator requested outside code memory region");
940 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
941 }
942
943 if ((breakpoint->type == BKPT_SOFT) && (breakpoint->address < 0x20000000))
944 {
945 LOG_INFO("soft breakpoint requested in code (flash) memory region");
946 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
947 }
948
949 if ((breakpoint->type == BKPT_HARD) && (cortex_m3->fp_code_available < 1))
950 {
951 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
952 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
953 }
954
955 if ((breakpoint->length != 2))
956 {
957 LOG_INFO("only breakpoints of two bytes length supported");
958 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
959 }
960
961 if (breakpoint->type == BKPT_HARD)
962 cortex_m3->fp_code_available--;
963 cortex_m3_set_breakpoint(target, breakpoint);
964
965 return ERROR_OK;
966 }
967
968 int cortex_m3_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
969 {
970 /* get pointers to arch-specific information */
971 armv7m_common_t *armv7m = target->arch_info;
972 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
973
974 if (target->state != TARGET_HALTED)
975 {
976 LOG_WARNING("target not halted");
977 return ERROR_TARGET_NOT_HALTED;
978 }
979
980 if (cortex_m3->auto_bp_type)
981 {
982 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
983 }
984
985 if (breakpoint->set)
986 {
987 cortex_m3_unset_breakpoint(target, breakpoint);
988 }
989
990 if (breakpoint->type == BKPT_HARD)
991 cortex_m3->fp_code_available++;
992
993 return ERROR_OK;
994 }
995
996 int cortex_m3_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
997 {
998 int dwt_num=0;
999 u32 mask, temp;
1000
1001 /* get pointers to arch-specific information */
1002 armv7m_common_t *armv7m = target->arch_info;
1003 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1004 cortex_m3_dwt_comparator_t * comparator_list = cortex_m3->dwt_comparator_list;
1005
1006 if (watchpoint->set)
1007 {
1008 LOG_WARNING("watchpoint already set");
1009 return ERROR_OK;
1010 }
1011
1012 if (watchpoint->mask == 0xffffffffu)
1013 {
1014 while(comparator_list[dwt_num].used && (dwt_num < cortex_m3->dwt_num_comp))
1015 dwt_num++;
1016 if (dwt_num >= cortex_m3->dwt_num_comp)
1017 {
1018 LOG_DEBUG("ERROR Can not find free DWT Comparator");
1019 LOG_WARNING("ERROR Can not find free DWT Comparator");
1020 return -1;
1021 }
1022 watchpoint->set = dwt_num + 1;
1023 mask = 0;
1024 temp = watchpoint->length;
1025 while (temp > 1)
1026 {
1027 temp = temp / 2;
1028 mask++;
1029 }
1030 comparator_list[dwt_num].used = 1;
1031 comparator_list[dwt_num].comp = watchpoint->address;
1032 comparator_list[dwt_num].mask = mask;
1033 comparator_list[dwt_num].function = watchpoint->rw + 5;
1034 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address, comparator_list[dwt_num].comp);
1035 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address|0x4, comparator_list[dwt_num].mask);
1036 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address|0x8, comparator_list[dwt_num].function);
1037 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);
1038 }
1039 else
1040 {
1041 LOG_WARNING("Cannot watch data values"); /* Move this test to add_watchpoint */
1042 return ERROR_OK;
1043 }
1044
1045 return ERROR_OK;
1046
1047 }
1048
1049 int cortex_m3_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1050 {
1051 /* get pointers to arch-specific information */
1052 armv7m_common_t *armv7m = target->arch_info;
1053 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1054 cortex_m3_dwt_comparator_t * comparator_list = cortex_m3->dwt_comparator_list;
1055 int dwt_num;
1056
1057 if (!watchpoint->set)
1058 {
1059 LOG_WARNING("watchpoint not set");
1060 return ERROR_OK;
1061 }
1062
1063 dwt_num = watchpoint->set - 1;
1064
1065 if ((dwt_num < 0) || (dwt_num >= cortex_m3->dwt_num_comp))
1066 {
1067 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1068 return ERROR_OK;
1069 }
1070 comparator_list[dwt_num].used = 0;
1071 comparator_list[dwt_num].function = 0;
1072 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address|0x8, comparator_list[dwt_num].function);
1073
1074 watchpoint->set = 0;
1075
1076 return ERROR_OK;
1077 }
1078
1079 int cortex_m3_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1080 {
1081 /* get pointers to arch-specific information */
1082 armv7m_common_t *armv7m = target->arch_info;
1083 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1084
1085 if (target->state != TARGET_HALTED)
1086 {
1087 LOG_WARNING("target not halted");
1088 return ERROR_TARGET_NOT_HALTED;
1089 }
1090
1091 if (cortex_m3->dwt_comp_available < 1)
1092 {
1093 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1094 }
1095
1096 if ((watchpoint->length != 1) && (watchpoint->length != 2) && (watchpoint->length != 4))
1097 {
1098 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1099 }
1100
1101 cortex_m3->dwt_comp_available--;
1102
1103 return ERROR_OK;
1104 }
1105
1106 int cortex_m3_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1107 {
1108 /* get pointers to arch-specific information */
1109 armv7m_common_t *armv7m = target->arch_info;
1110 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1111
1112 if (target->state != TARGET_HALTED)
1113 {
1114 LOG_WARNING("target not halted");
1115 return ERROR_TARGET_NOT_HALTED;
1116 }
1117
1118 if (watchpoint->set)
1119 {
1120 cortex_m3_unset_watchpoint(target, watchpoint);
1121 }
1122
1123 cortex_m3->dwt_comp_available++;
1124
1125 return ERROR_OK;
1126 }
1127
1128 void cortex_m3_enable_watchpoints(struct target_s *target)
1129 {
1130 watchpoint_t *watchpoint = target->watchpoints;
1131
1132 /* set any pending watchpoints */
1133 while (watchpoint)
1134 {
1135 if (watchpoint->set == 0)
1136 cortex_m3_set_watchpoint(target, watchpoint);
1137 watchpoint = watchpoint->next;
1138 }
1139 }
1140
1141 int cortex_m3_load_core_reg_u32(struct target_s *target, enum armv7m_regtype type, u32 num, u32 * value)
1142 {
1143 int retval;
1144 /* get pointers to arch-specific information */
1145 armv7m_common_t *armv7m = target->arch_info;
1146 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1147 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1148
1149 if ((type == ARMV7M_REGISTER_CORE_GP) && (num <= ARMV7M_PSP))
1150 {
1151 /* read a normal core register */
1152 retval = ahbap_read_coreregister_u32(swjdp, value, num);
1153
1154 if (retval != ERROR_OK)
1155 {
1156 LOG_ERROR("JTAG failure %i",retval);
1157 return ERROR_JTAG_DEVICE_ERROR;
1158 }
1159 LOG_DEBUG("load from core reg %i value 0x%x",num,*value);
1160 }
1161 else if (type == ARMV7M_REGISTER_CORE_SP) /* Special purpose core register */
1162 {
1163 /* read other registers */
1164 ahbap_read_coreregister_u32(swjdp, value, 20);
1165
1166 switch (num)
1167 {
1168 case 19:
1169 *value = buf_get_u32((u8*)value, 0, 8);
1170 break;
1171
1172 case 20:
1173 *value = buf_get_u32((u8*)value, 8, 8);
1174 break;
1175
1176 case 21:
1177 *value = buf_get_u32((u8*)value, 16, 8);
1178 break;
1179
1180 case 22:
1181 *value = buf_get_u32((u8*)value, 24, 8);
1182 break;
1183 }
1184
1185 LOG_DEBUG("load from special reg %i value 0x%x", num, *value);
1186 }
1187 else
1188 {
1189 return ERROR_INVALID_ARGUMENTS;
1190 }
1191
1192 return ERROR_OK;
1193 }
1194
1195 int cortex_m3_store_core_reg_u32(struct target_s *target, enum armv7m_regtype type, u32 num, u32 value)
1196 {
1197 int retval;
1198 u32 reg;
1199
1200 /* get pointers to arch-specific information */
1201 armv7m_common_t *armv7m = target->arch_info;
1202 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1203 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1204
1205 #ifdef ARMV7_GDB_HACKS
1206 /* If the LR register is being modified, make sure it will put us
1207 * in "thumb" mode, or an INVSTATE exception will occur. This is a
1208 * hack to deal with the fact that gdb will sometimes "forge"
1209 * return addresses, and doesn't set the LSB correctly (i.e., when
1210 * printing expressions containing function calls, it sets LR=0.) */
1211
1212 if (num == 14)
1213 value |= 0x01;
1214 #endif
1215
1216 if ((type == ARMV7M_REGISTER_CORE_GP) && (num <= ARMV7M_PSP))
1217 {
1218 retval = ahbap_write_coreregister_u32(swjdp, value, num);
1219 if (retval != ERROR_OK)
1220 {
1221 LOG_ERROR("JTAG failure %i", retval);
1222 armv7m->core_cache->reg_list[num].dirty = armv7m->core_cache->reg_list[num].valid;
1223 return ERROR_JTAG_DEVICE_ERROR;
1224 }
1225 LOG_DEBUG("write core reg %i value 0x%x", num, value);
1226 }
1227 else if (type == ARMV7M_REGISTER_CORE_SP) /* Special purpose core register */
1228 {
1229 /* write other registers */
1230
1231 ahbap_read_coreregister_u32(swjdp, &reg, 20);
1232
1233 switch (num)
1234 {
1235 case 19:
1236 buf_set_u32((u8*)&reg, 0, 8, value);
1237 break;
1238
1239 case 20:
1240 buf_set_u32((u8*)&reg, 8, 8, value);
1241 break;
1242
1243 case 21:
1244 buf_set_u32((u8*)&reg, 16, 8, value);
1245 break;
1246
1247 case 22:
1248 buf_set_u32((u8*)&reg, 24, 8, value);
1249 break;
1250 }
1251
1252 ahbap_write_coreregister_u32(swjdp, reg, 20);
1253
1254 LOG_DEBUG("write special reg %i value 0x%x ", num, value);
1255 }
1256 else
1257 {
1258 return ERROR_INVALID_ARGUMENTS;
1259 }
1260
1261 return ERROR_OK;
1262 }
1263
1264 int cortex_m3_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1265 {
1266 /* get pointers to arch-specific information */
1267 armv7m_common_t *armv7m = target->arch_info;
1268 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1269 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1270 int retval;
1271
1272 /* sanitize arguments */
1273 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1274 return ERROR_INVALID_ARGUMENTS;
1275
1276 /* cortex_m3 handles unaligned memory access */
1277
1278 switch (size)
1279 {
1280 case 4:
1281 retval = ahbap_read_buf_u32(swjdp, buffer, 4 * count, address);
1282 break;
1283 case 2:
1284 retval = ahbap_read_buf_u16(swjdp, buffer, 2 * count, address);
1285 break;
1286 case 1:
1287 retval = ahbap_read_buf_u8(swjdp, buffer, count, address);
1288 break;
1289 default:
1290 LOG_ERROR("BUG: we shouldn't get here");
1291 exit(-1);
1292 }
1293
1294 return retval;
1295 }
1296
1297 int cortex_m3_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1298 {
1299 /* get pointers to arch-specific information */
1300 armv7m_common_t *armv7m = target->arch_info;
1301 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1302 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1303 int retval;
1304
1305 /* sanitize arguments */
1306 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1307 return ERROR_INVALID_ARGUMENTS;
1308
1309 switch (size)
1310 {
1311 case 4:
1312 retval = ahbap_write_buf_u32(swjdp, buffer, 4 * count, address);
1313 break;
1314 case 2:
1315 retval = ahbap_write_buf_u16(swjdp, buffer, 2 * count, address);
1316 break;
1317 case 1:
1318 retval = ahbap_write_buf_u8(swjdp, buffer, count, address);
1319 break;
1320 default:
1321 LOG_ERROR("BUG: we shouldn't get here");
1322 exit(-1);
1323 }
1324
1325 return retval;
1326 }
1327
1328 int cortex_m3_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer)
1329 {
1330 return cortex_m3_write_memory(target, address, 4, count, buffer);
1331 }
1332
1333 void cortex_m3_build_reg_cache(target_t *target)
1334 {
1335 armv7m_build_reg_cache(target);
1336 }
1337
1338 int cortex_m3_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
1339 {
1340 cortex_m3_build_reg_cache(target);
1341 return ERROR_OK;
1342 }
1343
1344 int cortex_m3_examine(struct target_s *target)
1345 {
1346 int retval;
1347 u32 cpuid, fpcr, dwtcr, ictr;
1348 int i;
1349
1350 /* get pointers to arch-specific information */
1351 armv7m_common_t *armv7m = target->arch_info;
1352 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1353 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1354
1355 target->type->examined = 1;
1356
1357 if ((retval=ahbap_debugport_init(swjdp))!=ERROR_OK)
1358 return retval;
1359
1360 /* Read from Device Identification Registers */
1361 if ((retval=target_read_u32(target, CPUID, &cpuid))!=ERROR_OK)
1362 return retval;
1363
1364 if (((cpuid >> 4) & 0xc3f) == 0xc23)
1365 LOG_DEBUG("CORTEX-M3 processor detected");
1366 LOG_DEBUG("cpuid: 0x%8.8x", cpuid);
1367
1368 target_read_u32(target, NVIC_ICTR, &ictr);
1369 cortex_m3->intlinesnum = (ictr & 0x1F) + 1;
1370 cortex_m3->intsetenable = calloc(cortex_m3->intlinesnum, 4);
1371 for (i = 0; i < cortex_m3->intlinesnum; i++)
1372 {
1373 target_read_u32(target, NVIC_ISE0 + 4 * i, cortex_m3->intsetenable + i);
1374 LOG_DEBUG("interrupt enable[%i] = 0x%8.8x", i, cortex_m3->intsetenable[i]);
1375 }
1376
1377 /* Setup FPB */
1378 target_read_u32(target, FP_CTRL, &fpcr);
1379 cortex_m3->auto_bp_type = 1;
1380 cortex_m3->fp_num_code = (fpcr >> 4) & 0xF;
1381 cortex_m3->fp_num_lit = (fpcr >> 8) & 0xF;
1382 cortex_m3->fp_code_available = cortex_m3->fp_num_code;
1383 cortex_m3->fp_comparator_list = calloc(cortex_m3->fp_num_code + cortex_m3->fp_num_lit, sizeof(cortex_m3_fp_comparator_t));
1384 for (i = 0; i < cortex_m3->fp_num_code + cortex_m3->fp_num_lit; i++)
1385 {
1386 cortex_m3->fp_comparator_list[i].type = (i < cortex_m3->fp_num_code) ? FPCR_CODE : FPCR_LITERAL;
1387 cortex_m3->fp_comparator_list[i].fpcr_address = FP_COMP0 + 4 * i;
1388 }
1389 LOG_DEBUG("FPB fpcr 0x%x, numcode %i, numlit %i", fpcr, cortex_m3->fp_num_code, cortex_m3->fp_num_lit);
1390
1391 /* Setup DWT */
1392 target_read_u32(target, DWT_CTRL, &dwtcr);
1393 cortex_m3->dwt_num_comp = (dwtcr >> 28) & 0xF;
1394 cortex_m3->dwt_comp_available = cortex_m3->dwt_num_comp;
1395 cortex_m3->dwt_comparator_list=calloc(cortex_m3->dwt_num_comp, sizeof(cortex_m3_dwt_comparator_t));
1396 for (i = 0; i < cortex_m3->dwt_num_comp; i++)
1397 {
1398 cortex_m3->dwt_comparator_list[i].dwt_comparator_address = DWT_COMP0 + 0x10 * i;
1399 }
1400
1401 return ERROR_OK;
1402 }
1403
1404 int cortex_m3_quit(void)
1405 {
1406
1407 return ERROR_OK;
1408 }
1409
1410 int cortex_m3_dcc_read(swjdp_common_t *swjdp, u8 *value, u8 *ctrl)
1411 {
1412 u16 dcrdr;
1413
1414 ahbap_read_buf_u16( swjdp, (u8*)&dcrdr, 1, DCB_DCRDR);
1415 *ctrl = (u8)dcrdr;
1416 *value = (u8)(dcrdr >> 8);
1417
1418 LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
1419
1420 /* write ack back to software dcc register
1421 * signify we have read data */
1422 if (dcrdr & (1 << 0))
1423 {
1424 dcrdr = 0;
1425 ahbap_write_buf_u16( swjdp, (u8*)&dcrdr, 1, DCB_DCRDR);
1426 }
1427
1428 return ERROR_OK;
1429 }
1430
1431 int cortex_m3_target_request_data(target_t *target, u32 size, u8 *buffer)
1432 {
1433 armv7m_common_t *armv7m = target->arch_info;
1434 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1435 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1436 u8 data;
1437 u8 ctrl;
1438 int i;
1439
1440 for (i = 0; i < (size * 4); i++)
1441 {
1442 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1443 buffer[i] = data;
1444 }
1445
1446 return ERROR_OK;
1447 }
1448
1449 int cortex_m3_handle_target_request(void *priv)
1450 {
1451 target_t *target = priv;
1452 if (!target->type->examined)
1453 return ERROR_OK;
1454 armv7m_common_t *armv7m = target->arch_info;
1455 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1456 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1457
1458 if (!target->dbg_msg_enabled)
1459 return ERROR_OK;
1460
1461 if (target->state == TARGET_RUNNING)
1462 {
1463 u8 data;
1464 u8 ctrl;
1465
1466 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1467
1468 /* check if we have data */
1469 if (ctrl & (1 << 0))
1470 {
1471 u32 request;
1472
1473 /* we assume target is quick enough */
1474 request = data;
1475 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1476 request |= (data << 8);
1477 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1478 request |= (data << 16);
1479 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1480 request |= (data << 24);
1481 target_request(target, request);
1482 }
1483 }
1484
1485 return ERROR_OK;
1486 }
1487
1488 int cortex_m3_init_arch_info(target_t *target, cortex_m3_common_t *cortex_m3, int chain_pos, const char *variant)
1489 {
1490 armv7m_common_t *armv7m;
1491 armv7m = &cortex_m3->armv7m;
1492
1493 /* prepare JTAG information for the new target */
1494 cortex_m3->jtag_info.chain_pos = chain_pos;
1495 cortex_m3->jtag_info.scann_size = 4;
1496
1497 cortex_m3->swjdp_info.dp_select_value = -1;
1498 cortex_m3->swjdp_info.ap_csw_value = -1;
1499 cortex_m3->swjdp_info.ap_tar_value = -1;
1500 cortex_m3->swjdp_info.jtag_info = &cortex_m3->jtag_info;
1501
1502 /* initialize arch-specific breakpoint handling */
1503
1504 cortex_m3->common_magic = CORTEX_M3_COMMON_MAGIC;
1505 cortex_m3->arch_info = NULL;
1506
1507 /* register arch-specific functions */
1508 armv7m->examine_debug_reason = cortex_m3_examine_debug_reason;
1509
1510 armv7m->pre_debug_entry = NULL;
1511 armv7m->post_debug_entry = NULL;
1512
1513 armv7m->pre_restore_context = NULL;
1514 armv7m->post_restore_context = NULL;
1515
1516 if (variant)
1517 {
1518 cortex_m3->variant = strdup(variant);
1519 }
1520 else
1521 {
1522 cortex_m3->variant = strdup("");
1523 }
1524
1525 armv7m_init_arch_info(target, armv7m);
1526 armv7m->arch_info = cortex_m3;
1527 armv7m->load_core_reg_u32 = cortex_m3_load_core_reg_u32;
1528 armv7m->store_core_reg_u32 = cortex_m3_store_core_reg_u32;
1529
1530 target_register_timer_callback(cortex_m3_handle_target_request, 1, 1, target);
1531
1532 return ERROR_OK;
1533 }
1534
1535 int cortex_m3_target_create(struct target_s *target, Jim_Interp *interp)
1536 {
1537 cortex_m3_common_t *cortex_m3 = calloc(1,sizeof(cortex_m3_common_t));
1538
1539 cortex_m3_init_arch_info(target, cortex_m3, target->chain_position, target->variant);
1540
1541 return ERROR_OK;
1542 }
1543
1544 int cortex_m3_register_commands(struct command_context_s *cmd_ctx)
1545 {
1546 int retval;
1547
1548 retval = armv7m_register_commands(cmd_ctx);
1549
1550 return retval;
1551 }

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)