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

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)