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