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

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)