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

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)