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

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)