]> git.sur5r.net Git - openocd/blob - src/target/arm7_9_common.c
- added patch to make single-stepping more resilient
[openocd] / src / target / arm7_9_common.c
1 /***************************************************************************
2  *   Copyright (C) 2005 by Dominic Rath                                    *
3  *   Dominic.Rath@gmx.de                                                   *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "replacements.h"
25
26 #include "embeddedice.h"
27 #include "target.h"
28 #include "target_request.h"
29 #include "armv4_5.h"
30 #include "arm_jtag.h"
31 #include "jtag.h"
32 #include "log.h"
33 #include "arm7_9_common.h"
34 #include "breakpoints.h"
35
36 #include <stdlib.h>
37 #include <string.h>
38 #include <unistd.h>
39
40 #include <sys/types.h>
41 #include <sys/stat.h>
42 #include <sys/time.h>
43 #include <errno.h>
44
45 int arm7_9_debug_entry(target_t *target);
46 int arm7_9_enable_sw_bkpts(struct target_s *target);
47
48 /* command handler forward declarations */
49 int handle_arm7_9_write_xpsr_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
50 int handle_arm7_9_write_xpsr_im8_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
51 int handle_arm7_9_read_core_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
52 int handle_arm7_9_write_core_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
53 int handle_arm7_9_sw_bkpts_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
54 int handle_arm7_9_force_hw_bkpts_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
55 int handle_arm7_9_dbgrq_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
56 int handle_arm7_9_fast_memory_access_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
57 int handle_arm7_9_dcc_downloads_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
58 int handle_arm7_9_etm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
59
60 int arm7_9_reinit_embeddedice(target_t *target)
61 {
62         armv4_5_common_t *armv4_5 = target->arch_info;
63         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
64         
65         breakpoint_t *breakpoint = target->breakpoints;
66         
67         arm7_9->wp_available = 2;
68         arm7_9->wp0_used = 0;
69         arm7_9->wp1_used = 0;
70                 
71         /* mark all hardware breakpoints as unset */
72         while (breakpoint)
73         {
74                 if (breakpoint->type == BKPT_HARD)
75                 {
76                         breakpoint->set = 0;
77                 }
78                 breakpoint = breakpoint->next;
79         }
80                 
81         if (arm7_9->sw_bkpts_enabled && arm7_9->sw_bkpts_use_wp)
82         {
83                 arm7_9->sw_bkpts_enabled = 0;
84                 arm7_9_enable_sw_bkpts(target);
85         }
86         
87         arm7_9->reinit_embeddedice = 0;
88         
89         return ERROR_OK;
90 }
91
92 int arm7_9_jtag_callback(enum jtag_event event, void *priv)
93 {
94         target_t *target = priv;
95         armv4_5_common_t *armv4_5 = target->arch_info;
96         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
97         
98         /* a test-logic reset occured
99          * the EmbeddedICE registers have been reset
100          * hardware breakpoints have been cleared
101          */
102         if (event == JTAG_TRST_ASSERTED)
103         {
104                 arm7_9->reinit_embeddedice = 1;
105         }
106         
107         return ERROR_OK;
108 }
109
110 int arm7_9_get_arch_pointers(target_t *target, armv4_5_common_t **armv4_5_p, arm7_9_common_t **arm7_9_p)
111 {
112         armv4_5_common_t *armv4_5 = target->arch_info;
113         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
114         
115         if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
116         {
117                 return -1;
118         }
119         
120         if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
121         {
122                 return -1;
123         }
124         
125         *armv4_5_p = armv4_5;
126         *arm7_9_p = arm7_9;
127         
128         return ERROR_OK;
129 }
130
131 int arm7_9_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
132 {
133         armv4_5_common_t *armv4_5 = target->arch_info;
134         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
135         
136         if (target->state != TARGET_HALTED)
137         {
138                 WARNING("target not halted");
139                 return ERROR_TARGET_NOT_HALTED;
140         }
141         
142         if (arm7_9->force_hw_bkpts)
143                 breakpoint->type = BKPT_HARD;
144
145         if (breakpoint->set)
146         {
147                 WARNING("breakpoint already set");
148                 return ERROR_OK;
149         }
150
151         if (breakpoint->type == BKPT_HARD)
152         {
153                 /* either an ARM (4 byte) or Thumb (2 byte) breakpoint */
154                 u32 mask = (breakpoint->length == 4) ? 0x3u : 0x1u;
155                 if (!arm7_9->wp0_used)
156                 {
157                         embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_VALUE], breakpoint->address);
158                         embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], mask);
159                         embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffffu);
160                         embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], ~EICE_W_CTRL_nOPC & 0xff);
161                         embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], EICE_W_CTRL_ENABLE);
162
163                         jtag_execute_queue();
164                         arm7_9->wp0_used = 1;
165                         breakpoint->set = 1;
166                 }
167                 else if (!arm7_9->wp1_used)
168                 {
169                         embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_VALUE], breakpoint->address);
170                         embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK], mask);
171                         embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK], 0xffffffffu);
172                         embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK], ~EICE_W_CTRL_nOPC & 0xff);
173                         embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], EICE_W_CTRL_ENABLE);
174
175                         jtag_execute_queue();
176                         arm7_9->wp1_used = 1;
177                         breakpoint->set = 2;
178                 }
179                 else
180                 {
181                         ERROR("BUG: no hardware comparator available");
182                         return ERROR_OK;
183                 }
184         }
185         else if (breakpoint->type == BKPT_SOFT)
186         {
187                 if (breakpoint->length == 4)
188                 {
189                         u32 verify = 0xffffffff;
190                         /* keep the original instruction in target endianness */
191                         target->type->read_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr);
192                         /* write the breakpoint instruction in target endianness (arm7_9->arm_bkpt is host endian) */
193                         target_write_u32(target, breakpoint->address, arm7_9->arm_bkpt);
194                         
195                         target->type->read_memory(target, breakpoint->address, 4, 1, (u8 *)&verify);
196                         if (verify != arm7_9->arm_bkpt)
197                         {
198                                 ERROR("Unable to set 32 bit software breakpoint at address %08x", breakpoint->address);
199                                 return ERROR_OK;
200                         }
201                 }
202                 else
203                 {
204                         u16 verify = 0xffff;
205                         /* keep the original instruction in target endianness */
206                         target->type->read_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr);
207                         /* write the breakpoint instruction in target endianness (arm7_9->thumb_bkpt is host endian) */
208                         target_write_u16(target, breakpoint->address, arm7_9->thumb_bkpt);
209                         
210                         target->type->read_memory(target, breakpoint->address, 2, 1, (u8 *)&verify);
211                         if (verify != arm7_9->thumb_bkpt)
212                         {
213                                 ERROR("Unable to set thumb software breakpoint at address %08x", breakpoint->address);
214                                 return ERROR_OK;
215                         }
216                 }
217                 breakpoint->set = 1;
218         }
219
220         return ERROR_OK;
221
222 }
223
224 int arm7_9_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
225 {
226         armv4_5_common_t *armv4_5 = target->arch_info;
227         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
228         
229         if (target->state != TARGET_HALTED)
230         {
231                 WARNING("target not halted");
232                 return ERROR_TARGET_NOT_HALTED;
233         }
234
235         if (!breakpoint->set)
236         {
237                 WARNING("breakpoint not set");
238                 return ERROR_OK;
239         }
240         
241         if (breakpoint->type == BKPT_HARD)
242         {
243                 if (breakpoint->set == 1)
244                 {
245                         embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x0);
246                         jtag_execute_queue();
247                         arm7_9->wp0_used = 0;
248                 }
249                 else if (breakpoint->set == 2)
250                 {
251                         embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], 0x0);
252                         jtag_execute_queue();
253                         arm7_9->wp1_used = 0;
254                 }
255                 breakpoint->set = 0;
256         }
257         else
258         {
259                 /* restore original instruction (kept in target endianness) */
260                 if (breakpoint->length == 4)
261                 {
262                         u32 current_instr;
263                         /* check that user program as not modified breakpoint instruction */
264                         target->type->read_memory(target, breakpoint->address, 4, 1, (u8*)&current_instr);
265                         if (current_instr==arm7_9->arm_bkpt)
266                                 target->type->write_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr);
267                 }
268                 else
269                 {
270                         u16 current_instr;
271                         /* check that user program as not modified breakpoint instruction */
272                         target->type->read_memory(target, breakpoint->address, 2, 1, (u8*)&current_instr);
273                         if (current_instr==arm7_9->thumb_bkpt)
274                                 target->type->write_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr);
275                 }
276                 breakpoint->set = 0;
277         }
278
279         return ERROR_OK;
280 }
281
282 int arm7_9_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
283 {
284         armv4_5_common_t *armv4_5 = target->arch_info;
285         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
286         
287         if (target->state != TARGET_HALTED)
288         {
289                 WARNING("target not halted");
290                 return ERROR_TARGET_NOT_HALTED;
291         }
292         
293         if (arm7_9->force_hw_bkpts)
294         {
295                 DEBUG("forcing use of hardware breakpoint at address 0x%8.8x", breakpoint->address);
296                 breakpoint->type = BKPT_HARD;
297         }
298         
299         if ((breakpoint->type == BKPT_SOFT) && (arm7_9->sw_bkpts_enabled == 0))
300         {
301                 INFO("sw breakpoint requested, but software breakpoints not enabled");
302                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
303         }
304         
305         if ((breakpoint->type == BKPT_HARD) && (arm7_9->wp_available < 1))
306         {
307                 INFO("no watchpoint unit available for hardware breakpoint");
308                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
309         }
310         
311         if ((breakpoint->length != 2) && (breakpoint->length != 4))
312         {
313                 INFO("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
314                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
315         }
316         
317         if (breakpoint->type == BKPT_HARD)
318                 arm7_9->wp_available--;
319         
320         return ERROR_OK;
321 }
322
323 int arm7_9_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
324 {
325         armv4_5_common_t *armv4_5 = target->arch_info;
326         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
327         
328         if (target->state != TARGET_HALTED)
329         {
330                 WARNING("target not halted");
331                 return ERROR_TARGET_NOT_HALTED;
332         }
333         
334         if (breakpoint->set)
335         {
336                 arm7_9_unset_breakpoint(target, breakpoint);
337         }
338         
339         if (breakpoint->type == BKPT_HARD)
340                 arm7_9->wp_available++;
341         
342         return ERROR_OK;
343 }
344
345 int arm7_9_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
346 {
347         armv4_5_common_t *armv4_5 = target->arch_info;
348         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
349         int rw_mask = 1;
350         u32 mask;
351         
352         mask = watchpoint->length - 1;
353         
354         if (target->state != TARGET_HALTED)
355         {
356                 WARNING("target not halted");
357                 return ERROR_TARGET_NOT_HALTED;
358         }
359         
360         if (watchpoint->rw == WPT_ACCESS)
361                 rw_mask = 0;
362         else
363                 rw_mask = 1;
364         
365         if (!arm7_9->wp0_used)
366         {
367                 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_VALUE], watchpoint->address);
368                 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], mask);
369                 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], watchpoint->mask);
370                 if( watchpoint->mask != 0xffffffffu )
371                         embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_VALUE], watchpoint->value);
372                 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], 0xff & ~EICE_W_CTRL_nOPC & ~rw_mask);
373                 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], EICE_W_CTRL_ENABLE | EICE_W_CTRL_nOPC | (watchpoint->rw & 1));
374
375                 jtag_execute_queue();
376                 watchpoint->set = 1;
377                 arm7_9->wp0_used = 2;
378         }
379         else if (!arm7_9->wp1_used)
380         {
381                 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_VALUE], watchpoint->address);
382                 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK], mask);
383                 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK], watchpoint->mask);
384                 if( watchpoint->mask != 0xffffffffu )
385                         embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_VALUE], watchpoint->value);
386                 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK], 0xff & ~EICE_W_CTRL_nOPC & ~rw_mask);
387                 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], EICE_W_CTRL_ENABLE | EICE_W_CTRL_nOPC | (watchpoint->rw & 1));
388
389                 jtag_execute_queue();
390                 watchpoint->set = 2;
391                 arm7_9->wp1_used = 2;
392         } 
393         else
394         {
395                 ERROR("BUG: no hardware comparator available");
396                 return ERROR_OK;
397         }
398         
399         return ERROR_OK;
400 }
401
402 int arm7_9_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
403 {
404         armv4_5_common_t *armv4_5 = target->arch_info;
405         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
406         
407         if (target->state != TARGET_HALTED)
408         {
409                 WARNING("target not halted");
410                 return ERROR_TARGET_NOT_HALTED;
411         }
412         
413         if (!watchpoint->set)
414         {
415                 WARNING("breakpoint not set");
416                 return ERROR_OK;
417         }
418         
419         if (watchpoint->set == 1)
420         {
421                 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x0);
422                 jtag_execute_queue();
423                 arm7_9->wp0_used = 0;
424         }
425         else if (watchpoint->set == 2)
426         {
427                 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], 0x0);
428                 jtag_execute_queue();
429                 arm7_9->wp1_used = 0;
430         }
431         watchpoint->set = 0;
432
433         return ERROR_OK;
434 }
435
436 int arm7_9_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
437 {
438         armv4_5_common_t *armv4_5 = target->arch_info;
439         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
440         
441         if (target->state != TARGET_HALTED)
442         {
443                 WARNING("target not halted");
444                 return ERROR_TARGET_NOT_HALTED;
445         }
446         
447         if (arm7_9->wp_available < 1)
448         {
449                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
450         }
451         
452         if ((watchpoint->length != 1) && (watchpoint->length != 2) && (watchpoint->length != 4))
453         {
454                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
455         }
456         
457         arm7_9->wp_available--;
458                 
459         return ERROR_OK;
460 }
461
462 int arm7_9_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
463 {
464         armv4_5_common_t *armv4_5 = target->arch_info;
465         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
466         
467         if (target->state != TARGET_HALTED)
468         {
469                 WARNING("target not halted");
470                 return ERROR_TARGET_NOT_HALTED;
471         }
472         
473         if (watchpoint->set)
474         {
475                 arm7_9_unset_watchpoint(target, watchpoint);
476         }
477                 
478         arm7_9->wp_available++;
479         
480         return ERROR_OK;
481 }
482
483 int arm7_9_enable_sw_bkpts(struct target_s *target)
484 {
485         armv4_5_common_t *armv4_5 = target->arch_info;
486         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
487         int retval;
488         
489         if (arm7_9->sw_bkpts_enabled)
490                 return ERROR_OK;
491         
492         if (arm7_9->wp_available < 1)
493         {
494                 WARNING("can't enable sw breakpoints with no watchpoint unit available");
495                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
496         }
497         arm7_9->wp_available--;
498         
499         if (!arm7_9->wp0_used)
500         {
501                 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_VALUE], arm7_9->arm_bkpt);
502                 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0x0);
503                 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0xffffffffu);
504                 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], ~EICE_W_CTRL_nOPC & 0xff);
505                 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], EICE_W_CTRL_ENABLE);
506                 arm7_9->sw_bkpts_enabled = 1;
507                 arm7_9->wp0_used = 3;
508         }
509         else if (!arm7_9->wp1_used)
510         {
511                 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_VALUE], arm7_9->arm_bkpt);
512                 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK], 0x0);
513                 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK], 0xffffffffu);
514                 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK], ~EICE_W_CTRL_nOPC & 0xff);
515                 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], EICE_W_CTRL_ENABLE);
516                 arm7_9->sw_bkpts_enabled = 2;
517                 arm7_9->wp1_used = 3;
518         }
519         else
520         {
521                 ERROR("BUG: both watchpoints used, but wp_available >= 1");
522                 exit(-1);
523         }
524         
525         if ((retval = jtag_execute_queue()) != ERROR_OK)
526         {
527                 ERROR("error writing EmbeddedICE registers to enable sw breakpoints");
528                 exit(-1);
529         };
530         
531         return ERROR_OK;
532 }
533
534 int arm7_9_disable_sw_bkpts(struct target_s *target)
535 {
536         armv4_5_common_t *armv4_5 = target->arch_info;
537         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
538         
539         if (!arm7_9->sw_bkpts_enabled)
540                 return ERROR_OK;
541         
542         if (arm7_9->sw_bkpts_enabled == 1)
543         {
544                 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x0);
545                 arm7_9->sw_bkpts_enabled = 0;
546                 arm7_9->wp0_used = 0;
547                 arm7_9->wp_available++;
548         }
549         else if (arm7_9->sw_bkpts_enabled == 2)
550         {
551                 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], 0x0);
552                 arm7_9->sw_bkpts_enabled = 0;
553                 arm7_9->wp1_used = 0;
554                 arm7_9->wp_available++;
555         }
556
557         return ERROR_OK;
558 }
559
560 int arm7_9_execute_sys_speed(struct target_s *target)
561 {
562         int timeout;
563         int retval;
564         
565         armv4_5_common_t *armv4_5 = target->arch_info;
566         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
567         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
568         reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
569                                 
570         /* set RESTART instruction */
571         jtag_add_end_state(TAP_RTI);
572         arm_jtag_set_instr(jtag_info, 0x4, NULL);
573         
574         for (timeout=0; timeout<50; timeout++)
575         {
576                 /* read debug status register */
577                 embeddedice_read_reg(dbg_stat);
578                 if ((retval = jtag_execute_queue()) != ERROR_OK)
579                         return retval;
580                 if ((buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1))
581                                    && (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_SYSCOMP, 1)))
582                         break;
583                 usleep(100000); 
584         }
585         if (timeout == 50)
586         {
587                 ERROR("timeout waiting for SYSCOMP & DBGACK, last DBG_STATUS: %x", buf_get_u32(dbg_stat->value, 0, dbg_stat->size));
588                 return ERROR_TARGET_TIMEOUT;
589         }
590         
591         return ERROR_OK;
592 }
593
594 int arm7_9_execute_fast_sys_speed(struct target_s *target)
595 {
596         static int set=0;
597         static u8 check_value[4], check_mask[4];
598         
599         armv4_5_common_t *armv4_5 = target->arch_info;
600         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
601         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
602         reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
603                                 
604         /* set RESTART instruction */
605         jtag_add_end_state(TAP_RTI);
606         arm_jtag_set_instr(jtag_info, 0x4, NULL);
607         
608         if (!set)
609         {
610                 /* check for DBGACK and SYSCOMP set (others don't care) */
611                 
612                 /* NB! These are constants that must be available until after next jtag_execute() and
613                    we evaluate the values upon first execution in lieu of setting up these constants
614                    during early setup.
615                 */
616                 buf_set_u32(check_value, 0, 32, 0x9);
617                 buf_set_u32(check_mask, 0, 32, 0x9);
618                 set=1;
619         }
620         
621         /* read debug status register */
622         embeddedice_read_reg_w_check(dbg_stat, check_value, check_value);
623
624         return ERROR_OK;
625 }
626
627 int arm7_9_target_request_data(target_t *target, u32 size, u8 *buffer)
628 {
629         armv4_5_common_t *armv4_5 = target->arch_info;
630         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
631         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
632         u32 *data;
633         int i;
634         
635         data = malloc(size * (sizeof(u32)));
636         
637         embeddedice_receive(jtag_info, data, size);
638         
639         for (i = 0; i < size; i++)
640         {
641                 h_u32_to_le(buffer + (i * 4), data[i]);
642         }
643         
644         free(data);
645         
646         return ERROR_OK;
647 }
648
649 int arm7_9_handle_target_request(void *priv)
650 {
651         target_t *target = priv;
652         armv4_5_common_t *armv4_5 = target->arch_info;
653         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
654         arm_jtag_t *jtag_info = &arm7_9->jtag_info; 
655         reg_t *dcc_control = &arm7_9->eice_cache->reg_list[EICE_COMMS_CTRL];
656         
657         if (!target->dbg_msg_enabled)
658                 return ERROR_OK;
659                 
660         if (target->state == TARGET_RUNNING)
661         {
662                 /* read DCC control register */
663                 embeddedice_read_reg(dcc_control);
664                 jtag_execute_queue();
665                 
666                 /* check W bit */
667                 if (buf_get_u32(dcc_control->value, 1, 1) == 1)
668                 {
669                         u32 request;
670                         
671                         embeddedice_receive(jtag_info, &request, 1);
672                         target_request(target, request);
673                 }
674         }
675         
676         return ERROR_OK;
677 }
678
679 enum target_state arm7_9_poll(target_t *target)
680 {
681         int retval;
682         armv4_5_common_t *armv4_5 = target->arch_info;
683         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
684         reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
685
686         if (arm7_9->reinit_embeddedice)
687         {
688                 arm7_9_reinit_embeddedice(target);
689         }
690         
691         /* read debug status register */
692         embeddedice_read_reg(dbg_stat);
693         if ((retval = jtag_execute_queue()) != ERROR_OK)
694         {
695                 switch (retval)
696                 {
697                         case ERROR_JTAG_QUEUE_FAILED:
698                                 ERROR("JTAG queue failed while reading EmbeddedICE status register");
699                                 exit(-1);
700                                 break;
701                         default:
702                                 break;
703                 }
704         }
705         
706         if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1))
707         {
708                 DEBUG("DBGACK set, dbg_state->value: 0x%x", buf_get_u32(dbg_stat->value, 0, 32));
709                 if ((target->state == TARGET_UNKNOWN))
710                 {
711                         WARNING("DBGACK set while target was in unknown state. Reset or initialize target before resuming");
712                         target->state = TARGET_RUNNING;
713                 }
714                 if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET))
715                 {
716                         target->state = TARGET_HALTED;
717                         if ((retval = arm7_9_debug_entry(target)) != ERROR_OK)
718                                 return retval;
719                         
720                         target_call_event_callbacks(target, TARGET_EVENT_HALTED);
721                 }
722                 if (target->state == TARGET_DEBUG_RUNNING)
723                 {
724                         target->state = TARGET_HALTED;
725                         if ((retval = arm7_9_debug_entry(target)) != ERROR_OK)
726                                 return retval;
727                         
728                         target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
729                 }
730         }
731         else
732         {
733                 if (target->state != TARGET_DEBUG_RUNNING)
734                         target->state = TARGET_RUNNING;
735         }
736         
737         return target->state;
738 }
739
740 int arm7_9_assert_reset(target_t *target)
741 {
742         int retval;
743         
744         DEBUG("target->state: %s", target_state_strings[target->state]);
745         
746         if (target->state == TARGET_HALTED || target->state == TARGET_UNKNOWN)
747         {
748                 /* if the target wasn't running, there might be working areas allocated */
749                 target_free_all_working_areas(target);
750                 
751                 /* assert SRST and TRST */
752                 /* system would get ouf sync if we didn't reset test-logic, too */
753                 if ((retval = jtag_add_reset(1, 1)) != ERROR_OK)
754                 {
755                         if (retval == ERROR_JTAG_RESET_CANT_SRST)
756                         {
757                                 WARNING("can't assert srst");
758                                 return retval;
759                         }
760                         else
761                         {
762                                 ERROR("unknown error");
763                                 exit(-1);
764                         }
765                 }
766                 jtag_add_sleep(5000);
767                 if ((retval = jtag_add_reset(0, 1)) != ERROR_OK)
768                 {
769                         if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST)
770                         {
771                                 WARNING("srst resets test logic, too");
772                                 retval = jtag_add_reset(1, 1);
773                         }
774                 }
775         }
776         else
777         {
778                 if ((retval = jtag_add_reset(0, 1)) != ERROR_OK)
779                 {
780                         if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST)
781                         {
782                                 WARNING("srst resets test logic, too");
783                                 retval = jtag_add_reset(1, 1);
784                         }
785                         
786                         if (retval == ERROR_JTAG_RESET_CANT_SRST)
787                         {
788                                 WARNING("can't assert srst");
789                                 return retval;
790                         }
791                         else if (retval != ERROR_OK)
792                         {
793                                 ERROR("unknown error");
794                                 exit(-1);
795                         }
796                 }
797         }
798         
799         target->state = TARGET_RESET;
800         jtag_add_sleep(50000);
801         
802         armv4_5_invalidate_core_regs(target);
803
804         return ERROR_OK;
805
806 }
807
808 int arm7_9_deassert_reset(target_t *target)
809 {
810         DEBUG("target->state: %s", target_state_strings[target->state]);
811         
812         /* deassert reset lines */
813         jtag_add_reset(0, 0);
814         
815         return ERROR_OK;
816 }
817
818 int arm7_9_clear_halt(target_t *target)
819 {
820         armv4_5_common_t *armv4_5 = target->arch_info;
821         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
822         reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
823         
824         /* we used DBGRQ only if we didn't come out of reset */
825         if (!arm7_9->debug_entry_from_reset && arm7_9->use_dbgrq)
826         {
827                 /* program EmbeddedICE Debug Control Register to deassert DBGRQ
828                  */
829                 buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 0);     
830                 embeddedice_store_reg(dbg_ctrl);
831         }
832         else
833         {
834                 if (arm7_9->debug_entry_from_reset && arm7_9->has_vector_catch)
835                 {
836                         /* if we came out of reset, and vector catch is supported, we used
837                          * vector catch to enter debug state
838                          * restore the register in that case
839                          */
840                         embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_VEC_CATCH]);
841                 }
842                 else
843                 {
844                         /* restore registers if watchpoint unit 0 was in use
845                          */
846                         if (arm7_9->wp0_used)
847                         {
848                                 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK]);
849                                 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK]);
850                                 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK]);
851                         }
852                         /* control value always has to be restored, as it was either disabled, 
853                          * or enabled with possibly different bits
854                          */
855                         embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE]);
856                 }
857         }
858         
859         return ERROR_OK;
860 }
861
862 int arm7_9_soft_reset_halt(struct target_s *target)
863 {
864         armv4_5_common_t *armv4_5 = target->arch_info;
865         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
866         reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
867         reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
868         int i;
869         
870         if (target->state == TARGET_RUNNING)
871         {
872                 target->type->halt(target);
873         }
874         
875         while (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0)
876         {
877                 embeddedice_read_reg(dbg_stat);
878                 jtag_execute_queue();
879         }
880         target->state = TARGET_HALTED;
881         
882         /* program EmbeddedICE Debug Control Register to assert DBGACK and INTDIS
883          * ensure that DBGRQ is cleared
884          */
885         buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 1);
886         buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 0);
887         buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_INTDIS, 1, 1);
888         embeddedice_store_reg(dbg_ctrl);
889         
890         arm7_9_clear_halt(target);
891         
892         /* if the target is in Thumb state, change to ARM state */
893         if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_ITBIT, 1))
894         {
895                 u32 r0_thumb, pc_thumb;
896                 DEBUG("target entered debug from Thumb state, changing to ARM");
897                 /* Entered debug from Thumb mode */
898                 armv4_5->core_state = ARMV4_5_STATE_THUMB;
899                 arm7_9->change_to_arm(target, &r0_thumb, &pc_thumb);
900         }
901         
902         /* all register content is now invalid */
903         armv4_5_invalidate_core_regs(target);
904         
905         /* SVC, ARM state, IRQ and FIQ disabled */
906         buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8, 0xd3);
907         armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
908         armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
909         
910         /* start fetching from 0x0 */
911         buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
912         armv4_5->core_cache->reg_list[15].dirty = 1;
913         armv4_5->core_cache->reg_list[15].valid = 1;
914         
915         armv4_5->core_mode = ARMV4_5_MODE_SVC;
916         armv4_5->core_state = ARMV4_5_STATE_ARM;
917         
918         /* reset registers */
919         for (i = 0; i <= 14; i++)
920         {       
921                 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).value, 0, 32, 0xffffffff);
922                 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = 1;
923                 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).valid = 1;
924         }
925         
926         target_call_event_callbacks(target, TARGET_EVENT_HALTED);
927         
928         return ERROR_OK;
929 }
930
931 int arm7_9_prepare_reset_halt(target_t *target)
932 {
933         armv4_5_common_t *armv4_5 = target->arch_info;
934         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
935         
936         /* poll the target, and resume if it was currently halted */
937         arm7_9_poll(target);
938         if (target->state == TARGET_HALTED)
939         {
940                 arm7_9_resume(target, 1, 0x0, 0, 1);
941         }
942         
943         if (arm7_9->has_vector_catch)
944         {
945                 /* program vector catch register to catch reset vector */
946                 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_VEC_CATCH], 0x1);
947         }
948         else
949         {
950                 /* program watchpoint unit to match on reset vector address */
951                 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0x3);
952                 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0x0);
953                 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x100);
954                 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], 0xf7);
955         }
956         
957         return ERROR_OK;
958 }
959
960 int arm7_9_halt(target_t *target)
961 {
962         armv4_5_common_t *armv4_5 = target->arch_info;
963         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
964         reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
965         
966         DEBUG("target->state: %s", target_state_strings[target->state]);
967         
968         if (target->state == TARGET_HALTED)
969         {
970                 WARNING("target was already halted");
971                 return ERROR_TARGET_ALREADY_HALTED;
972         }
973         
974         if (target->state == TARGET_UNKNOWN)
975         {
976                 WARNING("target was in unknown state when halt was requested");
977         }
978         
979         if (target->state == TARGET_RESET) 
980         {
981                 if ((jtag_reset_config & RESET_SRST_PULLS_TRST) && jtag_srst)
982                 {
983                         ERROR("can't request a halt while in reset if nSRST pulls nTRST");
984                         return ERROR_TARGET_FAILURE;
985                 }
986                 else
987                 {
988                         /* we came here in a reset_halt or reset_init sequence
989                          * debug entry was already prepared in arm7_9_prepare_reset_halt()
990                          */
991                         target->debug_reason = DBG_REASON_DBGRQ;
992                         
993                         return ERROR_OK; 
994                 }
995         }
996
997         if (arm7_9->use_dbgrq)
998         {
999                 /* program EmbeddedICE Debug Control Register to assert DBGRQ
1000                  */
1001                 buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 1);     
1002                 embeddedice_store_reg(dbg_ctrl);
1003         }
1004         else
1005         {
1006                 /* program watchpoint unit to match on any address
1007                  */
1008                 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0xffffffff);
1009                 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffff);
1010                 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x100);
1011                 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], 0xf7);
1012         }
1013
1014         target->debug_reason = DBG_REASON_DBGRQ;
1015         
1016         return ERROR_OK;
1017 }
1018
1019 int arm7_9_debug_entry(target_t *target)
1020 {
1021         int i;
1022         u32 context[16];
1023         u32* context_p[16];
1024         u32 r0_thumb, pc_thumb;
1025         u32 cpsr;
1026         int retval;
1027         /* get pointers to arch-specific information */
1028         armv4_5_common_t *armv4_5 = target->arch_info;
1029         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1030         reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
1031         reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
1032
1033 #ifdef _DEBUG_ARM7_9_
1034         DEBUG("-");
1035 #endif
1036
1037         if (arm7_9->pre_debug_entry)
1038                 arm7_9->pre_debug_entry(target);
1039
1040         /* program EmbeddedICE Debug Control Register to assert DBGACK and INTDIS
1041          * ensure that DBGRQ is cleared
1042          */
1043         buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 1);
1044         buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 0);
1045         buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_INTDIS, 1, 1);
1046         embeddedice_store_reg(dbg_ctrl);
1047         
1048         arm7_9_clear_halt(target);
1049         
1050         if ((retval = jtag_execute_queue()) != ERROR_OK)
1051         {
1052                 switch (retval)
1053                 {
1054                         case ERROR_JTAG_QUEUE_FAILED:
1055                                 ERROR("JTAG queue failed while writing EmbeddedICE control register");
1056                                 exit(-1);
1057                                 break;
1058                         default:
1059                                 break;
1060                 }
1061         }
1062
1063         if ((retval = arm7_9->examine_debug_reason(target)) != ERROR_OK)
1064                 return retval;
1065
1066
1067         if (target->state != TARGET_HALTED)
1068         {
1069                 WARNING("target not halted");
1070                 return ERROR_TARGET_NOT_HALTED;
1071         }
1072         
1073         /* if the target is in Thumb state, change to ARM state */
1074         if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_ITBIT, 1))
1075         {
1076                 DEBUG("target entered debug from Thumb state");
1077                 /* Entered debug from Thumb mode */
1078                 armv4_5->core_state = ARMV4_5_STATE_THUMB;
1079                 arm7_9->change_to_arm(target, &r0_thumb, &pc_thumb);
1080                 DEBUG("r0_thumb: 0x%8.8x, pc_thumb: 0x%8.8x", r0_thumb, pc_thumb);
1081         }
1082         else
1083         {
1084                 DEBUG("target entered debug from ARM state");
1085                 /* Entered debug from ARM mode */
1086                 armv4_5->core_state = ARMV4_5_STATE_ARM;
1087         }
1088         
1089         for (i = 0; i < 16; i++)
1090                 context_p[i] = &context[i];
1091         /* save core registers (r0 - r15 of current core mode) */
1092         arm7_9->read_core_regs(target, 0xffff, context_p);
1093
1094         arm7_9->read_xpsr(target, &cpsr, 0);
1095         
1096         if ((retval = jtag_execute_queue()) != ERROR_OK)
1097                 return retval;
1098         
1099         /* if the core has been executing in Thumb state, set the T bit */
1100         if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
1101                 cpsr |= 0x20;   
1102         
1103         buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32, cpsr);
1104         armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 0;
1105         armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
1106         
1107         armv4_5->core_mode = cpsr & 0x1f;
1108         
1109         if (armv4_5_mode_to_number(armv4_5->core_mode) == -1)
1110         {
1111                 target->state = TARGET_UNKNOWN;
1112                 ERROR("cpsr contains invalid mode value - communication failure");
1113                 return ERROR_TARGET_FAILURE;
1114         }
1115
1116         DEBUG("target entered debug state in %s mode", armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)]);
1117         
1118         if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
1119         {
1120                 DEBUG("thumb state, applying fixups");
1121                 context[0] = r0_thumb;
1122                 context[15] = pc_thumb;
1123         } else if (armv4_5->core_state == ARMV4_5_STATE_ARM)
1124         {
1125                 /* adjust value stored by STM */
1126                 context[15] -= 3 * 4;
1127         }
1128
1129         if ((target->debug_reason == DBG_REASON_BREAKPOINT)
1130                         || (target->debug_reason == DBG_REASON_SINGLESTEP)
1131                         || (target->debug_reason == DBG_REASON_WATCHPOINT)
1132                         || (target->debug_reason == DBG_REASON_WPTANDBKPT)
1133                         || ((target->debug_reason == DBG_REASON_DBGRQ) && (arm7_9->use_dbgrq == 0)))
1134                 context[15] -= 3 * ((armv4_5->core_state == ARMV4_5_STATE_ARM) ? 4 : 2);
1135         else if (target->debug_reason == DBG_REASON_DBGRQ)
1136                 context[15] -= arm7_9->dbgreq_adjust_pc * ((armv4_5->core_state == ARMV4_5_STATE_ARM) ? 4 : 2);
1137         else
1138         {
1139                 ERROR("unknown debug reason: %i", target->debug_reason);
1140         }
1141
1142         
1143         for (i=0; i<=15; i++)
1144         {
1145                 DEBUG("r%i: 0x%8.8x", i, context[i]);
1146                 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).value, 0, 32, context[i]);
1147                 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = 0;
1148                 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).valid = 1;
1149         }
1150         
1151         DEBUG("entered debug state at PC 0x%x", context[15]);
1152
1153         /* exceptions other than USR & SYS have a saved program status register */
1154         if ((armv4_5_mode_to_number(armv4_5->core_mode) != ARMV4_5_MODE_USR) && (armv4_5_mode_to_number(armv4_5->core_mode) != ARMV4_5_MODE_SYS))
1155         {
1156                 u32 spsr;
1157                 arm7_9->read_xpsr(target, &spsr, 1);
1158                 jtag_execute_queue();
1159                 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).value, 0, 32, spsr);
1160                 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).dirty = 0;
1161                 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).valid = 1;
1162         }
1163
1164         /* r0 and r15 (pc) have to be restored later */
1165         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).valid;
1166         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 15).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 15).valid;
1167
1168         if ((retval = jtag->execute_queue()) != ERROR_OK)
1169                 return retval;
1170
1171         if (arm7_9->post_debug_entry)
1172                 arm7_9->post_debug_entry(target);
1173
1174         return ERROR_OK;
1175 }
1176
1177 int arm7_9_full_context(target_t *target)
1178 {
1179         int i;
1180         int retval;
1181         armv4_5_common_t *armv4_5 = target->arch_info;
1182         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1183
1184         DEBUG("-");
1185         
1186         if (target->state != TARGET_HALTED)
1187         {
1188                 WARNING("target not halted");
1189                 return ERROR_TARGET_NOT_HALTED;
1190         }
1191
1192         /* iterate through processor modes (User, FIQ, IRQ, SVC, ABT, UND)
1193          * SYS shares registers with User, so we don't touch SYS
1194          */
1195         for(i = 0; i < 6; i++)
1196         {
1197                 u32 mask = 0;
1198                 u32* reg_p[16];
1199                 int j;
1200                 int valid = 1;
1201                 
1202                 /* check if there are invalid registers in the current mode 
1203                  */
1204                 for (j = 0; j <= 16; j++)
1205                 {
1206                         if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).valid == 0)
1207                                 valid = 0;
1208                 }
1209                 
1210                 if (!valid)
1211                 {
1212                         u32 tmp_cpsr;
1213                         
1214                         /* change processor mode (and mask T bit) */
1215                         tmp_cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & 0xE0;
1216                         tmp_cpsr |= armv4_5_number_to_mode(i);
1217                         tmp_cpsr &= ~0x20;
1218                         arm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0);
1219
1220                         for (j = 0; j < 15; j++)
1221                         {
1222                                 if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).valid == 0)
1223                                 {       
1224                                         reg_p[j] = (u32*)ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).value;
1225                                         mask |= 1 << j;
1226                                         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).valid = 1;
1227                                         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).dirty = 0;
1228                                 }
1229                         }
1230                         
1231                         /* if only the PSR is invalid, mask is all zeroes */
1232                         if (mask)
1233                                 arm7_9->read_core_regs(target, mask, reg_p);
1234                         
1235                         /* check if the PSR has to be read */
1236                         if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).valid == 0)
1237                         {
1238                                 arm7_9->read_xpsr(target, (u32*)ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).value, 1);
1239                                 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).valid = 1;
1240                                 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).dirty = 0;
1241                         }
1242                 }
1243         }
1244
1245         /* restore processor mode (mask T bit) */
1246         arm7_9->write_xpsr_im8(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & ~0x20, 0, 0);
1247         
1248         if ((retval = jtag_execute_queue()) != ERROR_OK)
1249         {
1250                 ERROR("JTAG failure");
1251                 exit(-1);
1252         }
1253         return ERROR_OK;
1254 }
1255
1256 int arm7_9_restore_context(target_t *target)
1257 {
1258         armv4_5_common_t *armv4_5 = target->arch_info;
1259         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1260         reg_t *reg; 
1261         armv4_5_core_reg_t *reg_arch_info;
1262         enum armv4_5_mode current_mode = armv4_5->core_mode;
1263         int i, j;
1264         int dirty;
1265         int mode_change;
1266         
1267         DEBUG("-");
1268         
1269         if (target->state != TARGET_HALTED)
1270         {
1271                 WARNING("target not halted");
1272                 return ERROR_TARGET_NOT_HALTED;
1273         }
1274         
1275         if (arm7_9->pre_restore_context)
1276                 arm7_9->pre_restore_context(target);
1277         
1278         /* iterate through processor modes (User, FIQ, IRQ, SVC, ABT, UND)
1279          * SYS shares registers with User, so we don't touch SYS
1280          */
1281         for (i = 0; i < 6; i++)
1282         {
1283                 DEBUG("examining %s mode", armv4_5_mode_strings[i]);
1284                 dirty = 0;
1285                 mode_change = 0;
1286                 /* check if there are dirty registers in the current mode 
1287                 */
1288                 for (j = 0; j <= 16; j++)
1289                 {
1290                         reg = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j);
1291                         reg_arch_info = reg->arch_info;
1292                         if (reg->dirty == 1)
1293                         {
1294                                 if (reg->valid == 1)
1295                                 {
1296                                         dirty = 1;
1297                                         DEBUG("examining dirty reg: %s", reg->name);
1298                                         if ((reg_arch_info->mode != ARMV4_5_MODE_ANY)
1299                                                 && (reg_arch_info->mode != current_mode)
1300                                                 && !((reg_arch_info->mode == ARMV4_5_MODE_USR) && (armv4_5->core_mode == ARMV4_5_MODE_SYS)) 
1301                                                 && !((reg_arch_info->mode == ARMV4_5_MODE_SYS) && (armv4_5->core_mode == ARMV4_5_MODE_USR)))
1302                                         {
1303                                                 mode_change = 1;
1304                                                 DEBUG("require mode change");
1305                                         }
1306                                 }
1307                                 else
1308                                 {
1309                                         ERROR("BUG: dirty register '%s', but no valid data", reg->name);
1310                                         exit(-1);
1311                                 }
1312                         }
1313                 }
1314                 
1315                 if (dirty)
1316                 {
1317                         u32 mask = 0x0;
1318                         int num_regs = 0;
1319                         u32 regs[16];
1320
1321                         if (mode_change)
1322                         {
1323                                 u32 tmp_cpsr;
1324                         
1325                                 /* change processor mode (mask T bit) */
1326                                 tmp_cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & 0xE0;
1327                                 tmp_cpsr |= armv4_5_number_to_mode(i);
1328                                 tmp_cpsr &= ~0x20;
1329                                 arm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0);
1330                                 current_mode = armv4_5_number_to_mode(i);
1331                         }
1332                         
1333                         for (j = 0; j <= 14; j++)
1334                         {
1335                                 reg = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j);
1336                                 reg_arch_info = reg->arch_info;
1337                                 
1338                                 
1339                                 if (reg->dirty == 1)
1340                                 {
1341                                         regs[j] = buf_get_u32(reg->value, 0, 32);
1342                                         mask |= 1 << j;
1343                                         num_regs++;
1344                                         reg->dirty = 0;
1345                                         reg->valid = 1;
1346                                         DEBUG("writing register %i of mode %s with value 0x%8.8x", j, armv4_5_mode_strings[i], regs[j]);
1347                                 }
1348                         }
1349                         
1350                         if (mask)
1351                         {
1352                                 arm7_9->write_core_regs(target, mask, regs);
1353                         }
1354                         
1355                         reg = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16);
1356                         reg_arch_info = reg->arch_info;
1357                         if ((reg->dirty) && (reg_arch_info->mode != ARMV4_5_MODE_ANY))
1358                         {
1359                                 DEBUG("writing SPSR of mode %i with value 0x%8.8x", i, buf_get_u32(reg->value, 0, 32));
1360                                 arm7_9->write_xpsr(target, buf_get_u32(reg->value, 0, 32), 1);
1361                         }
1362                 }
1363         }
1364         
1365         if ((armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty == 0) && (armv4_5->core_mode != current_mode))
1366         {
1367                 /* restore processor mode (mask T bit) */
1368                 u32 tmp_cpsr;
1369                         
1370                 tmp_cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & 0xE0;
1371                 tmp_cpsr |= armv4_5_number_to_mode(i);
1372                 tmp_cpsr &= ~0x20;
1373                 DEBUG("writing lower 8 bit of cpsr with value 0x%2.2x", tmp_cpsr);
1374                 arm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0);
1375         }
1376         else if (armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty == 1)
1377         {
1378                 /* CPSR has been changed, full restore necessary (mask T bit) */
1379                 DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
1380                 arm7_9->write_xpsr(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32) & ~0x20, 0);
1381                 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 0;
1382                 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
1383         }
1384         
1385         /* restore PC */
1386         DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1387         arm7_9->write_pc(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1388         armv4_5->core_cache->reg_list[15].dirty = 0;
1389                         
1390         if (arm7_9->post_restore_context)
1391                 arm7_9->post_restore_context(target);
1392
1393         return ERROR_OK;
1394 }
1395
1396 int arm7_9_restart_core(struct target_s *target)
1397 {
1398         armv4_5_common_t *armv4_5 = target->arch_info;
1399         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1400         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
1401         
1402         /* set RESTART instruction */
1403         jtag_add_end_state(TAP_RTI);
1404         arm_jtag_set_instr(jtag_info, 0x4, NULL);
1405         
1406         jtag_add_runtest(1, TAP_RTI);
1407         if ((jtag_execute_queue()) != ERROR_OK)
1408         {
1409                 exit(-1);
1410         }
1411         
1412         return ERROR_OK;
1413 }
1414
1415 void arm7_9_enable_watchpoints(struct target_s *target)
1416 {
1417         watchpoint_t *watchpoint = target->watchpoints;
1418         
1419         while (watchpoint)
1420         {
1421                 if (watchpoint->set == 0)
1422                         arm7_9_set_watchpoint(target, watchpoint);
1423                 watchpoint = watchpoint->next;
1424         }
1425 }
1426
1427 void arm7_9_enable_breakpoints(struct target_s *target)
1428 {
1429         breakpoint_t *breakpoint = target->breakpoints;
1430         
1431         /* set any pending breakpoints */
1432         while (breakpoint)
1433         {
1434                 if (breakpoint->set == 0)
1435                         arm7_9_set_breakpoint(target, breakpoint);
1436                 breakpoint = breakpoint->next;
1437         }
1438 }
1439
1440 void arm7_9_disable_bkpts_and_wpts(struct target_s *target)
1441 {
1442         breakpoint_t *breakpoint = target->breakpoints;
1443         watchpoint_t *watchpoint = target->watchpoints;
1444
1445         /* set any pending breakpoints */
1446         while (breakpoint)
1447         {
1448                 if (breakpoint->set != 0)
1449                         arm7_9_unset_breakpoint(target, breakpoint);
1450                 breakpoint = breakpoint->next;
1451         }
1452         
1453         while (watchpoint)
1454         {
1455                 if (watchpoint->set != 0)
1456                         arm7_9_unset_watchpoint(target, watchpoint);
1457                 watchpoint = watchpoint->next;
1458         }
1459 }
1460
1461 int arm7_9_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution)
1462 {
1463         armv4_5_common_t *armv4_5 = target->arch_info;
1464         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1465         breakpoint_t *breakpoint = target->breakpoints;
1466         reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
1467         int err;
1468         
1469         DEBUG("-");
1470         
1471         if (target->state != TARGET_HALTED)
1472         {
1473                 WARNING("target not halted");
1474                 return ERROR_TARGET_NOT_HALTED;
1475         }
1476         
1477         if (!debug_execution)
1478         {
1479                 target_free_all_working_areas(target);
1480         }
1481         
1482         /* current = 1: continue on current pc, otherwise continue at <address> */
1483         if (!current)
1484                 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, address);
1485         
1486         /* the front-end may request us not to handle breakpoints */
1487         if (handle_breakpoints)
1488         {
1489                 if ((breakpoint = breakpoint_find(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32))))
1490                 {
1491                         DEBUG("unset breakpoint at 0x%8.8x", breakpoint->address);
1492                         arm7_9_unset_breakpoint(target, breakpoint);
1493                         
1494                         DEBUG("enable single-step");
1495                         arm7_9->enable_single_step(target);
1496                         
1497                         target->debug_reason = DBG_REASON_SINGLESTEP;
1498
1499                         arm7_9_restore_context(target);
1500                         
1501                         if (armv4_5->core_state == ARMV4_5_STATE_ARM)
1502                                 arm7_9->branch_resume(target);
1503                         else if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
1504                         {
1505                                 arm7_9->branch_resume_thumb(target);
1506                         }
1507                         else
1508                         {
1509                                 ERROR("unhandled core state");
1510                                 exit(-1);
1511                         }
1512                                 
1513                         buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 0);
1514                         embeddedice_write_reg(dbg_ctrl, buf_get_u32(dbg_ctrl->value, 0, dbg_ctrl->size));
1515                         err = arm7_9_execute_sys_speed(target);
1516                         
1517                         DEBUG("disable single-step");
1518                         arm7_9->disable_single_step(target);
1519
1520                         if (err != ERROR_OK)
1521                         {
1522                                 arm7_9_set_breakpoint(target, breakpoint);
1523                                 target->state = TARGET_UNKNOWN;
1524                                 return err;
1525                         }
1526
1527                         arm7_9_debug_entry(target);
1528                         DEBUG("new PC after step: 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1529
1530                         DEBUG("set breakpoint at 0x%8.8x", breakpoint->address);
1531                         arm7_9_set_breakpoint(target, breakpoint);
1532                 }
1533         }
1534         
1535         /* enable any pending breakpoints and watchpoints */
1536         arm7_9_enable_breakpoints(target);
1537         arm7_9_enable_watchpoints(target);
1538         
1539         arm7_9_restore_context(target);
1540         
1541         if (armv4_5->core_state == ARMV4_5_STATE_ARM)
1542         {
1543                 arm7_9->branch_resume(target);
1544         }
1545         else if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
1546         {
1547                 arm7_9->branch_resume_thumb(target);
1548         }
1549         else
1550         {
1551                 ERROR("unhandled core state");
1552                 exit(-1);
1553         }
1554         
1555         /* deassert DBGACK and INTDIS */
1556         buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 0);
1557         /* INTDIS only when we really resume, not during debug execution */
1558         if (!debug_execution)
1559                 buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_INTDIS, 1, 0);
1560         embeddedice_write_reg(dbg_ctrl, buf_get_u32(dbg_ctrl->value, 0, dbg_ctrl->size));
1561         
1562         arm7_9_restart_core(target);
1563         
1564         target->debug_reason = DBG_REASON_NOTHALTED;
1565         
1566         if (!debug_execution)
1567         {
1568                 /* registers are now invalid */
1569                 armv4_5_invalidate_core_regs(target);
1570                 target->state = TARGET_RUNNING;
1571                 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1572         }
1573         else
1574         {
1575                 target->state = TARGET_DEBUG_RUNNING;
1576                 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
1577         }
1578         
1579         DEBUG("target resumed");
1580         
1581         return ERROR_OK;
1582 }
1583
1584 void arm7_9_enable_eice_step(target_t *target)
1585 {
1586         armv4_5_common_t *armv4_5 = target->arch_info;
1587         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1588         
1589         /* setup an inverse breakpoint on the current PC
1590         * - comparator 1 matches the current address
1591         * - rangeout from comparator 1 is connected to comparator 0 rangein
1592         * - comparator 0 matches any address, as long as rangein is low */
1593         embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0xffffffff);
1594         embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffff);
1595         embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x100);
1596         embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], 0x77);
1597         embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_VALUE], buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1598         embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK], 0);
1599         embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK], 0xffffffff);
1600         embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], 0x0);
1601         embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK], 0xf7);
1602 }
1603
1604 void arm7_9_disable_eice_step(target_t *target)
1605 {
1606         armv4_5_common_t *armv4_5 = target->arch_info;
1607         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1608
1609         embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK]);
1610         embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK]);
1611         embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE]);
1612         embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK]);
1613         embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_VALUE]);
1614         embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK]);
1615         embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK]);
1616         embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK]);
1617         embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE]);
1618 }
1619
1620 int arm7_9_step(struct target_s *target, int current, u32 address, int handle_breakpoints)
1621 {
1622         armv4_5_common_t *armv4_5 = target->arch_info;
1623         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1624         breakpoint_t *breakpoint = NULL;
1625         int err;
1626
1627         if (target->state != TARGET_HALTED)
1628         {
1629                 WARNING("target not halted");
1630                 return ERROR_TARGET_NOT_HALTED;
1631         }
1632         
1633         /* current = 1: continue on current pc, otherwise continue at <address> */
1634         if (!current)
1635                 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, address);
1636         
1637         /* the front-end may request us not to handle breakpoints */
1638         if (handle_breakpoints)
1639                 if ((breakpoint = breakpoint_find(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32))))
1640                         arm7_9_unset_breakpoint(target, breakpoint);
1641         
1642         target->debug_reason = DBG_REASON_SINGLESTEP;
1643
1644         arm7_9_restore_context(target);
1645         
1646         arm7_9->enable_single_step(target);
1647         
1648         if (armv4_5->core_state == ARMV4_5_STATE_ARM)
1649         {
1650                 arm7_9->branch_resume(target);
1651         }
1652         else if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
1653         {
1654                 arm7_9->branch_resume_thumb(target);
1655         }
1656         else
1657         {
1658                 ERROR("unhandled core state");
1659                 exit(-1);
1660         }
1661         
1662         target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1663
1664         err = arm7_9_execute_sys_speed(target);
1665         arm7_9->disable_single_step(target);
1666         
1667         /* registers are now invalid */
1668         armv4_5_invalidate_core_regs(target);
1669         
1670         if (err != ERROR_OK)
1671         {
1672                 target->state = TARGET_UNKNOWN;
1673         } else {
1674                 arm7_9_debug_entry(target);
1675                 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
1676                 DEBUG("target stepped");
1677         }
1678         
1679         if (breakpoint)
1680                 arm7_9_set_breakpoint(target, breakpoint);
1681         
1682         return err;
1683
1684 }
1685
1686 int arm7_9_read_core_reg(struct target_s *target, int num, enum armv4_5_mode mode)
1687 {
1688         u32* reg_p[16];
1689         u32 value;
1690         int retval;
1691         armv4_5_common_t *armv4_5 = target->arch_info;
1692         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1693         enum armv4_5_mode reg_mode = ((armv4_5_core_reg_t*)ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).arch_info)->mode;
1694         
1695         if ((num < 0) || (num > 16))
1696                 return ERROR_INVALID_ARGUMENTS;
1697         
1698         if ((mode != ARMV4_5_MODE_ANY)
1699                         && (mode != armv4_5->core_mode)
1700                         && (reg_mode != ARMV4_5_MODE_ANY))
1701         {
1702                 u32 tmp_cpsr;
1703                         
1704                 /* change processor mode (mask T bit) */
1705                 tmp_cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & 0xE0;
1706                 tmp_cpsr |= mode;
1707                 tmp_cpsr &= ~0x20;
1708                 arm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0);
1709         }
1710         
1711         if ((num >= 0) && (num <= 15))
1712         {
1713                 /* read a normal core register */
1714                 reg_p[num] = &value;
1715                 
1716                 arm7_9->read_core_regs(target, 1 << num, reg_p);
1717         }
1718         else
1719         {
1720                 /* read a program status register
1721                  * if the register mode is MODE_ANY, we read the cpsr, otherwise a spsr
1722                  */
1723                 armv4_5_core_reg_t *arch_info = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).arch_info;
1724                 int spsr = (arch_info->mode == ARMV4_5_MODE_ANY) ? 0 : 1;
1725                 
1726                 arm7_9->read_xpsr(target, &value, spsr);
1727         }
1728         
1729         if ((retval = jtag_execute_queue()) != ERROR_OK)
1730         {
1731                 ERROR("JTAG failure");
1732                 exit(-1);
1733         }
1734                 
1735         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).valid = 1;
1736         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).dirty = 0;
1737         buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).value, 0, 32, value);
1738                 
1739         if ((mode != ARMV4_5_MODE_ANY)
1740                         && (mode != armv4_5->core_mode)
1741                         && (reg_mode != ARMV4_5_MODE_ANY))      {
1742                 /* restore processor mode (mask T bit) */
1743                 arm7_9->write_xpsr_im8(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & ~0x20, 0, 0);
1744         }
1745         
1746         return ERROR_OK;
1747         
1748 }
1749
1750 int arm7_9_write_core_reg(struct target_s *target, int num, enum armv4_5_mode mode, u32 value)
1751 {
1752         u32 reg[16];
1753         int retval;
1754         armv4_5_common_t *armv4_5 = target->arch_info;
1755         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1756         enum armv4_5_mode reg_mode = ((armv4_5_core_reg_t*)ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).arch_info)->mode;
1757
1758         if ((num < 0) || (num > 16))
1759                 return ERROR_INVALID_ARGUMENTS;
1760         
1761         if ((mode != ARMV4_5_MODE_ANY)
1762                         && (mode != armv4_5->core_mode)
1763                         && (reg_mode != ARMV4_5_MODE_ANY))      {
1764                 u32 tmp_cpsr;
1765                         
1766                 /* change processor mode (mask T bit) */
1767                 tmp_cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & 0xE0;
1768                 tmp_cpsr |= mode;
1769                 tmp_cpsr &= ~0x20;
1770                 arm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0);
1771         }
1772         
1773         if ((num >= 0) && (num <= 15))
1774         {
1775                 /* write a normal core register */
1776                 reg[num] = value;
1777                 
1778                 arm7_9->write_core_regs(target, 1 << num, reg);
1779         }
1780         else
1781         {
1782                 /* write a program status register
1783                 * if the register mode is MODE_ANY, we write the cpsr, otherwise a spsr
1784                 */
1785                 armv4_5_core_reg_t *arch_info = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).arch_info;
1786                 int spsr = (arch_info->mode == ARMV4_5_MODE_ANY) ? 0 : 1;
1787                 
1788                 /* if we're writing the CPSR, mask the T bit */
1789                 if (!spsr)
1790                         value &= ~0x20;
1791                 
1792                 arm7_9->write_xpsr(target, value, spsr);
1793         }
1794         
1795         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).valid = 1;
1796         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).dirty = 0;
1797                 
1798         if ((mode != ARMV4_5_MODE_ANY)
1799                         && (mode != armv4_5->core_mode)
1800                         && (reg_mode != ARMV4_5_MODE_ANY))      {
1801                 /* restore processor mode (mask T bit) */
1802                 arm7_9->write_xpsr_im8(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & ~0x20, 0, 0);
1803         }
1804         
1805         if ((retval = jtag_execute_queue()) != ERROR_OK)
1806         {
1807                 ERROR("JTAG failure");
1808                 exit(-1);
1809         }
1810         
1811         return ERROR_OK;
1812         
1813 }
1814
1815 int arm7_9_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1816 {
1817         armv4_5_common_t *armv4_5 = target->arch_info;
1818         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1819         
1820         u32 reg[16];
1821         int num_accesses = 0;
1822         int thisrun_accesses;
1823         int i;
1824         u32 cpsr;
1825         int retval;
1826         int last_reg = 0;
1827         
1828         DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
1829
1830         if (target->state != TARGET_HALTED)
1831         {
1832                 WARNING("target not halted");
1833                 return ERROR_TARGET_NOT_HALTED;
1834         }
1835
1836         /* sanitize arguments */
1837         if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1838                 return ERROR_INVALID_ARGUMENTS;
1839
1840         if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
1841                 return ERROR_TARGET_UNALIGNED_ACCESS;
1842         
1843         /* load the base register with the address of the first word */
1844         reg[0] = address;
1845         arm7_9->write_core_regs(target, 0x1, reg);
1846         
1847         switch (size)
1848         {
1849                 case 4:
1850                         while (num_accesses < count)
1851                         {
1852                                 u32 reg_list;
1853                                 thisrun_accesses = ((count - num_accesses) >= 14) ? 14 : (count - num_accesses);
1854                                 reg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe;
1855                                 
1856                                 if (last_reg <= thisrun_accesses)
1857                                         last_reg = thisrun_accesses;
1858                                 
1859                                 arm7_9->load_word_regs(target, reg_list);
1860                                 
1861                                 /* fast memory reads are only safe when the target is running
1862                                  * from a sufficiently high clock (32 kHz is usually too slow)
1863                                  */
1864                                 if (arm7_9->fast_memory_access)
1865                                         arm7_9_execute_fast_sys_speed(target);
1866                                 else
1867                                         arm7_9_execute_sys_speed(target);
1868                                                                         
1869                                 arm7_9->read_core_regs_target_buffer(target, reg_list, buffer, 4);
1870                                 
1871                                 /* advance buffer, count number of accesses */
1872                                 buffer += thisrun_accesses * 4;
1873                                 num_accesses += thisrun_accesses;
1874                         }       
1875                         break;
1876                 case 2:
1877                         while (num_accesses < count)
1878                         {
1879                                 u32 reg_list;
1880                                 thisrun_accesses = ((count - num_accesses) >= 14) ? 14 : (count - num_accesses);
1881                                 reg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe;
1882                                 
1883                                 for (i = 1; i <= thisrun_accesses; i++)
1884                                 {
1885                                         if (i > last_reg)
1886                                                 last_reg = i;
1887                                         arm7_9->load_hword_reg(target, i);
1888                                         /* fast memory reads are only safe when the target is running
1889                                          * from a sufficiently high clock (32 kHz is usually too slow)
1890                                          */
1891                                         if (arm7_9->fast_memory_access)
1892                                                 arm7_9_execute_fast_sys_speed(target);
1893                                         else
1894                                                 arm7_9_execute_sys_speed(target);
1895                                 }
1896                                 
1897                                 arm7_9->read_core_regs_target_buffer(target, reg_list, buffer, 2);
1898                                 
1899                                 /* advance buffer, count number of accesses */
1900                                 buffer += thisrun_accesses * 2;
1901                                 num_accesses += thisrun_accesses;
1902                         }       
1903                         break;
1904                 case 1:
1905                         while (num_accesses < count)
1906                         {
1907                                 u32 reg_list;
1908                                 thisrun_accesses = ((count - num_accesses) >= 14) ? 14 : (count - num_accesses);
1909                                 reg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe;
1910                                 
1911                                 for (i = 1; i <= thisrun_accesses; i++)
1912                                 {
1913                                         if (i > last_reg)
1914                                                 last_reg = i;
1915                                         arm7_9->load_byte_reg(target, i);
1916                                         /* fast memory reads are only safe when the target is running
1917                                          * from a sufficiently high clock (32 kHz is usually too slow)
1918                                          */
1919                                         if (arm7_9->fast_memory_access)
1920                                                 arm7_9_execute_fast_sys_speed(target);
1921                                         else
1922                                                 arm7_9_execute_sys_speed(target);
1923                                 }
1924                                 
1925                                 arm7_9->read_core_regs_target_buffer(target, reg_list, buffer, 1);
1926                                 
1927                                 /* advance buffer, count number of accesses */
1928                                 buffer += thisrun_accesses * 1;
1929                                 num_accesses += thisrun_accesses;
1930                         }       
1931                         break;
1932                 default:
1933                         ERROR("BUG: we shouldn't get here");
1934                         exit(-1);
1935                         break;
1936         }
1937         
1938         for (i=0; i<=last_reg; i++)
1939                 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).valid;
1940
1941         arm7_9->read_xpsr(target, &cpsr, 0);
1942         if ((retval = jtag_execute_queue()) != ERROR_OK)
1943         {
1944                 ERROR("JTAG error while reading cpsr");
1945                 return ERROR_TARGET_DATA_ABORT;
1946         }
1947
1948         if (((cpsr & 0x1f) == ARMV4_5_MODE_ABT) && (armv4_5->core_mode != ARMV4_5_MODE_ABT))
1949         {
1950                 WARNING("memory read caused data abort (address: 0x%8.8x, size: 0x%x, count: 0x%x)", address, size, count);
1951
1952                 arm7_9->write_xpsr_im8(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & ~0x20, 0, 0);
1953
1954                 return ERROR_TARGET_DATA_ABORT;
1955         }
1956         
1957         return ERROR_OK;
1958 }
1959
1960 int arm7_9_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1961 {
1962         armv4_5_common_t *armv4_5 = target->arch_info;
1963         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1964         reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
1965         
1966         u32 reg[16];
1967         int num_accesses = 0;
1968         int thisrun_accesses;
1969         int i;
1970         u32 cpsr;
1971         int retval;
1972         int last_reg = 0;
1973
1974 #ifdef _DEBUG_ARM7_9_
1975         DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
1976 #endif
1977
1978         if (target->state != TARGET_HALTED)
1979         {
1980                 WARNING("target not halted");
1981                 return ERROR_TARGET_NOT_HALTED;
1982         }
1983
1984         /* sanitize arguments */
1985         if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1986                 return ERROR_INVALID_ARGUMENTS;
1987
1988         if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
1989                 return ERROR_TARGET_UNALIGNED_ACCESS;
1990         
1991         /* load the base register with the address of the first word */
1992         reg[0] = address;
1993         arm7_9->write_core_regs(target, 0x1, reg);
1994         
1995         /* Clear DBGACK, to make sure memory fetches work as expected */
1996         buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 0);
1997         embeddedice_store_reg(dbg_ctrl);
1998         
1999         switch (size)
2000         {
2001                 case 4:
2002                         while (num_accesses < count)
2003                         {
2004                                 u32 reg_list;
2005                                 thisrun_accesses = ((count - num_accesses) >= 14) ? 14 : (count - num_accesses);
2006                                 reg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe;
2007                                 
2008                                 for (i = 1; i <= thisrun_accesses; i++)
2009                                 {
2010                                         if (i > last_reg)
2011                                                 last_reg = i;
2012                                         reg[i] = target_buffer_get_u32(target, buffer);
2013                                         buffer += 4;
2014                                 }
2015                                 
2016                                 arm7_9->write_core_regs(target, reg_list, reg);
2017                                 
2018                                 arm7_9->store_word_regs(target, reg_list);
2019                                 
2020                                 /* fast memory writes are only safe when the target is running
2021                                  * from a sufficiently high clock (32 kHz is usually too slow)
2022                                  */
2023                                 if (arm7_9->fast_memory_access)
2024                                         arm7_9_execute_fast_sys_speed(target);
2025                                 else
2026                                         arm7_9_execute_sys_speed(target);
2027                                 
2028                                 num_accesses += thisrun_accesses;
2029                         }       
2030                         break;
2031                 case 2:
2032                         while (num_accesses < count)
2033                         {
2034                                 u32 reg_list;
2035                                 thisrun_accesses = ((count - num_accesses) >= 14) ? 14 : (count - num_accesses);
2036                                 reg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe;
2037                                 
2038                                 for (i = 1; i <= thisrun_accesses; i++)
2039                                 {
2040                                         if (i > last_reg)
2041                                                 last_reg = i;
2042                                         reg[i] = target_buffer_get_u16(target, buffer) & 0xffff;
2043                                         buffer += 2;
2044                                 }
2045                                 
2046                                 arm7_9->write_core_regs(target, reg_list, reg);
2047                                 
2048                                 for (i = 1; i <= thisrun_accesses; i++)
2049                                 {
2050                                         arm7_9->store_hword_reg(target, i);
2051                                         
2052                                         /* fast memory writes are only safe when the target is running
2053                                          * from a sufficiently high clock (32 kHz is usually too slow)
2054                                          */
2055                                         if (arm7_9->fast_memory_access)
2056                                                 arm7_9_execute_fast_sys_speed(target);
2057                                         else
2058                                                 arm7_9_execute_sys_speed(target);
2059                                 }
2060                                 
2061                                 num_accesses += thisrun_accesses;
2062                         }       
2063                         break;
2064                 case 1:
2065                         while (num_accesses < count)
2066                         {
2067                                 u32 reg_list;
2068                                 thisrun_accesses = ((count - num_accesses) >= 14) ? 14 : (count - num_accesses);
2069                                 reg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe;
2070                                 
2071                                 for (i = 1; i <= thisrun_accesses; i++)
2072                                 {
2073                                         if (i > last_reg)
2074                                                 last_reg = i;
2075                                         reg[i] = *buffer++ & 0xff;
2076                                 }
2077                                 
2078                                 arm7_9->write_core_regs(target, reg_list, reg);
2079                                 
2080                                 for (i = 1; i <= thisrun_accesses; i++)
2081                                 {
2082                                         arm7_9->store_byte_reg(target, i);
2083                                         /* fast memory writes are only safe when the target is running
2084                                          * from a sufficiently high clock (32 kHz is usually too slow)
2085                                          */
2086                                         if (arm7_9->fast_memory_access)
2087                                                 arm7_9_execute_fast_sys_speed(target);
2088                                         else
2089                                                 arm7_9_execute_sys_speed(target);
2090                                 }
2091                                 
2092                                 num_accesses += thisrun_accesses;
2093                         }       
2094                         break;
2095                 default:
2096                         ERROR("BUG: we shouldn't get here");
2097                         exit(-1);
2098                         break;
2099         }
2100         
2101         /* Re-Set DBGACK */
2102         buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 1);
2103         embeddedice_store_reg(dbg_ctrl);
2104         
2105         for (i=0; i<=last_reg; i++)
2106                 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).valid;
2107
2108         arm7_9->read_xpsr(target, &cpsr, 0);
2109         if ((retval = jtag_execute_queue()) != ERROR_OK)
2110         {
2111                 ERROR("JTAG error while reading cpsr");
2112                 return ERROR_TARGET_DATA_ABORT;
2113         }
2114
2115         if (((cpsr & 0x1f) == ARMV4_5_MODE_ABT) && (armv4_5->core_mode != ARMV4_5_MODE_ABT))
2116         {
2117                 WARNING("memory write caused data abort (address: 0x%8.8x, size: 0x%x, count: 0x%x)", address, size, count);
2118
2119                 arm7_9->write_xpsr_im8(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & ~0x20, 0, 0);
2120
2121                 return ERROR_TARGET_DATA_ABORT;
2122         }
2123         
2124         return ERROR_OK;
2125 }
2126
2127 int arm7_9_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer)
2128 {
2129         armv4_5_common_t *armv4_5 = target->arch_info;
2130         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
2131         enum armv4_5_state core_state = armv4_5->core_state;
2132         u32 r0 = buf_get_u32(armv4_5->core_cache->reg_list[0].value, 0, 32);
2133         u32 r1 = buf_get_u32(armv4_5->core_cache->reg_list[1].value, 0, 32);
2134         u32 pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
2135         int i;
2136         
2137         u32 dcc_code[] = 
2138         {
2139                 /* MRC      TST         BNE         MRC         STR         B */
2140                 0xee101e10, 0xe3110001, 0x0afffffc, 0xee111e10, 0xe4801004, 0xeafffff9
2141         };
2142         
2143         if (!arm7_9->dcc_downloads)
2144                 return target->type->write_memory(target, address, 4, count, buffer);
2145
2146         /* regrab previously allocated working_area, or allocate a new one */
2147         if (!arm7_9->dcc_working_area)
2148         {
2149                 u8 dcc_code_buf[6 * 4];
2150                 
2151                 /* make sure we have a working area */
2152                 if (target_alloc_working_area(target, 24, &arm7_9->dcc_working_area) != ERROR_OK)
2153                 {
2154                         INFO("no working area available, falling back to memory writes");
2155                         return target->type->write_memory(target, address, 4, count, buffer);
2156                 }
2157                 
2158                 /* copy target instructions to target endianness */
2159                 for (i = 0; i < 6; i++)
2160                 {
2161                         target_buffer_set_u32(target, dcc_code_buf + i*4, dcc_code[i]);
2162                 }
2163                 
2164                 /* write DCC code to working area */
2165                 target->type->write_memory(target, arm7_9->dcc_working_area->address, 4, 6, dcc_code_buf);
2166         }
2167         
2168         buf_set_u32(armv4_5->core_cache->reg_list[0].value, 0, 32, address);
2169         armv4_5->core_cache->reg_list[0].valid = 1;
2170         armv4_5->core_cache->reg_list[0].dirty = 1;
2171         armv4_5->core_state = ARMV4_5_STATE_ARM;
2172
2173         arm7_9_resume(target, 0, arm7_9->dcc_working_area->address, 1, 1);
2174         
2175         for (i = 0; i < count; i++)
2176         {
2177                 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], target_buffer_get_u32(target, buffer));
2178                 buffer += 4;
2179         }
2180         
2181         target->type->halt(target);
2182         
2183         while (target->state != TARGET_HALTED)
2184                 target->type->poll(target);
2185         
2186         /* restore target state */
2187         buf_set_u32(armv4_5->core_cache->reg_list[0].value, 0, 32, r0);
2188         armv4_5->core_cache->reg_list[0].valid = 1;
2189         armv4_5->core_cache->reg_list[0].dirty = 1;
2190         buf_set_u32(armv4_5->core_cache->reg_list[1].value, 0, 32, r1);
2191         armv4_5->core_cache->reg_list[1].valid = 1;
2192         armv4_5->core_cache->reg_list[1].dirty = 1;
2193         buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, pc);
2194         armv4_5->core_cache->reg_list[15].valid = 1;
2195         armv4_5->core_cache->reg_list[15].dirty = 1;
2196         armv4_5->core_state = core_state;
2197         
2198         return ERROR_OK;
2199 }
2200
2201 int arm7_9_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum)
2202 {
2203         working_area_t *crc_algorithm;
2204         armv4_5_algorithm_t armv4_5_info;
2205         reg_param_t reg_params[2];
2206         int retval;
2207         
2208         u32 arm7_9_crc_code[] = {
2209                 0xE1A02000,                             /* mov          r2, r0 */
2210                 0xE3E00000,                             /* mov          r0, #0xffffffff */
2211                 0xE1A03001,                             /* mov          r3, r1 */
2212                 0xE3A04000,                             /* mov          r4, #0 */
2213                 0xEA00000B,                             /* b            ncomp */
2214                                                                 /* nbyte: */
2215                 0xE7D21004,                             /* ldrb r1, [r2, r4] */
2216                 0xE59F7030,                             /* ldr          r7, CRC32XOR */
2217                 0xE0200C01,                             /* eor          r0, r0, r1, asl 24 */
2218                 0xE3A05000,                             /* mov          r5, #0 */
2219                                                                 /* loop: */
2220                 0xE3500000,                             /* cmp          r0, #0 */
2221                 0xE1A06080,                             /* mov          r6, r0, asl #1 */
2222                 0xE2855001,                             /* add          r5, r5, #1 */
2223                 0xE1A00006,                             /* mov          r0, r6 */
2224                 0xB0260007,                             /* eorlt        r0, r6, r7 */
2225                 0xE3550008,                             /* cmp          r5, #8 */
2226                 0x1AFFFFF8,                             /* bne          loop */
2227                 0xE2844001,                             /* add          r4, r4, #1 */
2228                                                                 /* ncomp: */
2229                 0xE1540003,                             /* cmp          r4, r3 */
2230                 0x1AFFFFF1,                             /* bne          nbyte */
2231                                                                 /* end: */
2232                 0xEAFFFFFE,                             /* b            end */
2233                 0x04C11DB7                              /* CRC32XOR:    .word 0x04C11DB7 */
2234         };
2235         
2236         int i;
2237         
2238         if (target_alloc_working_area(target, sizeof(arm7_9_crc_code), &crc_algorithm) != ERROR_OK)
2239         {
2240                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2241         }
2242         
2243         /* convert flash writing code into a buffer in target endianness */
2244         for (i = 0; i < (sizeof(arm7_9_crc_code)/sizeof(u32)); i++)
2245                 target_write_u32(target, crc_algorithm->address + i*sizeof(u32), arm7_9_crc_code[i]);
2246         
2247         armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
2248         armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
2249         armv4_5_info.core_state = ARMV4_5_STATE_ARM;
2250         
2251         init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);
2252         init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
2253         
2254         buf_set_u32(reg_params[0].value, 0, 32, address);
2255         buf_set_u32(reg_params[1].value, 0, 32, count);
2256                 
2257         if ((retval = target->type->run_algorithm(target, 0, NULL, 2, reg_params,
2258                 crc_algorithm->address, crc_algorithm->address + (sizeof(arm7_9_crc_code) - 8), 20000, &armv4_5_info)) != ERROR_OK)
2259         {
2260                 ERROR("error executing arm7_9 crc algorithm");
2261                 destroy_reg_param(&reg_params[0]);
2262                 destroy_reg_param(&reg_params[1]);
2263                 target_free_working_area(target, crc_algorithm);
2264                 return retval;
2265         }
2266         
2267         *checksum = buf_get_u32(reg_params[0].value, 0, 32);
2268         
2269         destroy_reg_param(&reg_params[0]);
2270         destroy_reg_param(&reg_params[1]);
2271         
2272         target_free_working_area(target, crc_algorithm);
2273         
2274         return ERROR_OK;
2275 }
2276
2277 int arm7_9_register_commands(struct command_context_s *cmd_ctx)
2278 {
2279         command_t *arm7_9_cmd;
2280         
2281         arm7_9_cmd = register_command(cmd_ctx, NULL, "arm7_9", NULL, COMMAND_ANY, "arm7/9 specific commands");
2282
2283         register_command(cmd_ctx, arm7_9_cmd, "write_xpsr", handle_arm7_9_write_xpsr_command, COMMAND_EXEC, "write program status register <value> <not cpsr|spsr>");
2284         register_command(cmd_ctx, arm7_9_cmd, "write_xpsr_im8", handle_arm7_9_write_xpsr_im8_command, COMMAND_EXEC, "write program status register <8bit immediate> <rotate> <not cpsr|spsr>");
2285         
2286         register_command(cmd_ctx, arm7_9_cmd, "write_core_reg", handle_arm7_9_write_core_reg_command, COMMAND_EXEC, "write core register <num> <mode> <value>");        
2287         
2288         register_command(cmd_ctx, arm7_9_cmd, "sw_bkpts", handle_arm7_9_sw_bkpts_command, COMMAND_EXEC, "support for software breakpoints <enable|disable>");
2289         register_command(cmd_ctx, arm7_9_cmd, "force_hw_bkpts", handle_arm7_9_force_hw_bkpts_command, COMMAND_EXEC, "use hardware breakpoints for all breakpoints (disables sw breakpoint support) <enable|disable>");
2290         register_command(cmd_ctx, arm7_9_cmd, "dbgrq", handle_arm7_9_dbgrq_command,
2291                 COMMAND_ANY, "use EmbeddedICE dbgrq instead of breakpoint for target halt requests <enable|disable>");
2292         register_command(cmd_ctx, arm7_9_cmd, "fast_writes", handle_arm7_9_fast_memory_access_command,
2293                  COMMAND_ANY, "(deprecated, see: arm7_9 fast_memory_access)");
2294         register_command(cmd_ctx, arm7_9_cmd, "fast_memory_access", handle_arm7_9_fast_memory_access_command,
2295                  COMMAND_ANY, "use fast memory accesses instead of slower but potentially unsafe slow accesses <enable|disable>");
2296         register_command(cmd_ctx, arm7_9_cmd, "dcc_downloads", handle_arm7_9_dcc_downloads_command,
2297                 COMMAND_ANY, "use DCC downloads for larger memory writes <enable|disable>");
2298
2299         armv4_5_register_commands(cmd_ctx);
2300         
2301         etm_register_commands(cmd_ctx);
2302         
2303         return ERROR_OK;
2304 }
2305
2306 int handle_arm7_9_write_xpsr_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2307 {
2308         u32 value;
2309         int spsr;
2310         int retval;
2311         target_t *target = get_current_target(cmd_ctx);
2312         armv4_5_common_t *armv4_5;
2313         arm7_9_common_t *arm7_9;
2314
2315         if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
2316         {
2317                 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
2318                 return ERROR_OK;
2319         }
2320         
2321         if (target->state != TARGET_HALTED)
2322         {
2323                 command_print(cmd_ctx, "can't write registers while running");
2324                 return ERROR_OK;
2325         }
2326         
2327         if (argc < 2)
2328         {
2329                 command_print(cmd_ctx, "usage: write_xpsr <value> <not cpsr|spsr>");
2330                 return ERROR_OK;
2331         }
2332         
2333         value = strtoul(args[0], NULL, 0);
2334         spsr = strtol(args[1], NULL, 0);
2335         
2336         /* if we're writing the CPSR, mask the T bit */
2337         if (!spsr)
2338                 value &= ~0x20;
2339         
2340         arm7_9->write_xpsr(target, value, spsr);
2341         if ((retval = jtag_execute_queue()) != ERROR_OK)
2342         {
2343                 ERROR("JTAG error while writing to xpsr");
2344                 exit(-1);
2345         }
2346         
2347         return ERROR_OK;
2348 }
2349
2350 int handle_arm7_9_write_xpsr_im8_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2351 {
2352         u32 value;
2353         int rotate;
2354         int spsr;
2355         int retval;
2356         target_t *target = get_current_target(cmd_ctx);
2357         armv4_5_common_t *armv4_5;
2358         arm7_9_common_t *arm7_9;
2359
2360         if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
2361         {
2362                 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
2363                 return ERROR_OK;
2364         }
2365         
2366         if (target->state != TARGET_HALTED)
2367         {
2368                 command_print(cmd_ctx, "can't write registers while running");
2369                 return ERROR_OK;
2370         }
2371         
2372         if (argc < 3)
2373         {
2374                 command_print(cmd_ctx, "usage: write_xpsr_im8 <im8> <rotate> <not cpsr|spsr>");
2375                 return ERROR_OK;
2376         }
2377         
2378         value = strtoul(args[0], NULL, 0);
2379         rotate = strtol(args[1], NULL, 0);
2380         spsr = strtol(args[2], NULL, 0);
2381                 
2382         arm7_9->write_xpsr_im8(target, value, rotate, spsr);
2383         if ((retval = jtag_execute_queue()) != ERROR_OK)
2384         {
2385                 ERROR("JTAG error while writing 8-bit immediate to xpsr");
2386                 exit(-1);
2387         }
2388         
2389         return ERROR_OK;
2390 }
2391
2392 int handle_arm7_9_write_core_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2393 {
2394         u32 value;
2395         u32 mode;
2396         int num;
2397         target_t *target = get_current_target(cmd_ctx);
2398         armv4_5_common_t *armv4_5;
2399         arm7_9_common_t *arm7_9;
2400                 
2401         if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
2402         {
2403                 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
2404                 return ERROR_OK;
2405         }
2406         
2407         if (target->state != TARGET_HALTED)
2408         {
2409                 command_print(cmd_ctx, "can't write registers while running");
2410                 return ERROR_OK;
2411         }
2412         
2413         if (argc < 3)
2414         {
2415                 command_print(cmd_ctx, "usage: write_core_reg <num> <mode> <value>");
2416                 return ERROR_OK;
2417         }
2418         
2419         num = strtol(args[0], NULL, 0);
2420         mode = strtoul(args[1], NULL, 0);
2421         value = strtoul(args[2], NULL, 0);
2422         
2423         arm7_9_write_core_reg(target, num, mode, value);
2424         
2425         return ERROR_OK;
2426 }
2427
2428 int handle_arm7_9_sw_bkpts_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2429 {
2430         target_t *target = get_current_target(cmd_ctx);
2431         armv4_5_common_t *armv4_5;
2432         arm7_9_common_t *arm7_9;
2433         
2434         if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
2435         {
2436                 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
2437                 return ERROR_OK;
2438         }
2439         
2440         if (argc == 0)
2441         {
2442                 command_print(cmd_ctx, "software breakpoints %s", (arm7_9->sw_bkpts_enabled) ? "enabled" : "disabled");
2443                 return ERROR_OK;
2444         }
2445         
2446         if (strcmp("enable", args[0]) == 0)
2447         {
2448                 if (arm7_9->sw_bkpts_use_wp)
2449                 {
2450                         arm7_9_enable_sw_bkpts(target);
2451                 }
2452                 else
2453                 {
2454                         arm7_9->sw_bkpts_enabled = 1;
2455                 }
2456         }
2457         else if (strcmp("disable", args[0]) == 0)
2458         {
2459                 if (arm7_9->sw_bkpts_use_wp)
2460                 {
2461                         arm7_9_disable_sw_bkpts(target);
2462                 }
2463                 else
2464                 {
2465                         arm7_9->sw_bkpts_enabled = 0;
2466                 }
2467         }
2468         else
2469         {
2470                 command_print(cmd_ctx, "usage: arm7_9 sw_bkpts <enable|disable>");
2471         }
2472         
2473         command_print(cmd_ctx, "software breakpoints %s", (arm7_9->sw_bkpts_enabled) ? "enabled" : "disabled");
2474         
2475         return ERROR_OK;
2476 }
2477
2478 int handle_arm7_9_force_hw_bkpts_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2479 {
2480         target_t *target = get_current_target(cmd_ctx);
2481         armv4_5_common_t *armv4_5;
2482         arm7_9_common_t *arm7_9;
2483         
2484         if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
2485         {
2486                 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
2487                 return ERROR_OK;
2488         }
2489         
2490         if ((argc >= 1) && (strcmp("enable", args[0]) == 0))
2491         {
2492                 arm7_9->force_hw_bkpts = 1;
2493                 if (arm7_9->sw_bkpts_use_wp)
2494                 {
2495                         arm7_9_disable_sw_bkpts(target);
2496                 }
2497         }
2498         else if ((argc >= 1) && (strcmp("disable", args[0]) == 0))
2499         {
2500                 arm7_9->force_hw_bkpts = 0;
2501         }
2502         else
2503         {
2504                 command_print(cmd_ctx, "usage: arm7_9 force_hw_bkpts <enable|disable>");
2505         }
2506                 
2507         command_print(cmd_ctx, "force hardware breakpoints %s", (arm7_9->force_hw_bkpts) ? "enabled" : "disabled");
2508
2509         return ERROR_OK;
2510 }
2511
2512 int handle_arm7_9_dbgrq_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2513 {
2514         target_t *target = get_current_target(cmd_ctx);
2515         armv4_5_common_t *armv4_5;
2516         arm7_9_common_t *arm7_9;
2517         
2518         if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
2519         {
2520                 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
2521                 return ERROR_OK;
2522         }
2523         
2524         if (argc > 0)
2525         {
2526                 if (strcmp("enable", args[0]) == 0)
2527                 {
2528                         arm7_9->use_dbgrq = 1;
2529                 }
2530                 else if (strcmp("disable", args[0]) == 0)
2531                 {
2532                         arm7_9->use_dbgrq = 0;
2533                 }
2534                 else
2535                 {
2536                         command_print(cmd_ctx, "usage: arm7_9 dbgrq <enable|disable>");
2537                 }
2538         }
2539                 
2540         command_print(cmd_ctx, "use of EmbeddedICE dbgrq instead of breakpoint for target halt %s", (arm7_9->use_dbgrq) ? "enabled" : "disabled");
2541
2542         return ERROR_OK;
2543 }
2544
2545 int handle_arm7_9_fast_memory_access_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2546 {
2547         target_t *target = get_current_target(cmd_ctx);
2548         armv4_5_common_t *armv4_5;
2549         arm7_9_common_t *arm7_9;
2550         
2551         if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
2552         {
2553                 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
2554                 return ERROR_OK;
2555         }
2556         
2557         if (argc > 0)
2558         {
2559                 if (strcmp("enable", args[0]) == 0)
2560                 {
2561                         arm7_9->fast_memory_access = 1;
2562                 }
2563                 else if (strcmp("disable", args[0]) == 0)
2564                 {
2565                         arm7_9->fast_memory_access = 0;
2566                 }
2567                 else
2568                 {
2569                         command_print(cmd_ctx, "usage: arm7_9 fast_memory_access <enable|disable>");
2570                 }
2571         }
2572                 
2573         command_print(cmd_ctx, "fast memory access is %s", (arm7_9->fast_memory_access) ? "enabled" : "disabled");
2574
2575         return ERROR_OK;
2576 }
2577
2578 int handle_arm7_9_dcc_downloads_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2579 {
2580         target_t *target = get_current_target(cmd_ctx);
2581         armv4_5_common_t *armv4_5;
2582         arm7_9_common_t *arm7_9;
2583         
2584         if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
2585         {
2586                 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
2587                 return ERROR_OK;
2588         }
2589         
2590         if (argc > 0)
2591         {
2592                 if (strcmp("enable", args[0]) == 0)
2593                 {
2594                         arm7_9->dcc_downloads = 1;
2595                 }
2596                 else if (strcmp("disable", args[0]) == 0)
2597                 {
2598                         arm7_9->dcc_downloads = 0;
2599                 }
2600                 else
2601                 {
2602                         command_print(cmd_ctx, "usage: arm7_9 dcc_downloads <enable|disable>");
2603                 }
2604         }
2605                 
2606         command_print(cmd_ctx, "dcc downloads are %s", (arm7_9->dcc_downloads) ? "enabled" : "disabled");
2607
2608         return ERROR_OK;
2609 }
2610
2611 int arm7_9_init_arch_info(target_t *target, arm7_9_common_t *arm7_9)
2612 {
2613         armv4_5_common_t *armv4_5 = &arm7_9->armv4_5_common;
2614         
2615         arm7_9->common_magic = ARM7_9_COMMON_MAGIC;
2616         
2617         arm_jtag_setup_connection(&arm7_9->jtag_info);
2618         arm7_9->wp_available = 2;
2619         arm7_9->wp0_used = 0;
2620         arm7_9->wp1_used = 0;
2621         arm7_9->force_hw_bkpts = 0;
2622         arm7_9->use_dbgrq = 0;
2623         
2624         arm7_9->etm_ctx = NULL;
2625         arm7_9->has_single_step = 0;
2626         arm7_9->has_monitor_mode = 0;
2627         arm7_9->has_vector_catch = 0;
2628         
2629         arm7_9->reinit_embeddedice = 0;
2630         
2631         arm7_9->debug_entry_from_reset = 0;
2632         
2633         arm7_9->dcc_working_area = NULL;
2634         
2635         arm7_9->fast_memory_access = 0;
2636         arm7_9->dcc_downloads = 0;
2637
2638         jtag_register_event_callback(arm7_9_jtag_callback, target);
2639
2640         armv4_5->arch_info = arm7_9;
2641         armv4_5->read_core_reg = arm7_9_read_core_reg;
2642         armv4_5->write_core_reg = arm7_9_write_core_reg;
2643         armv4_5->full_context = arm7_9_full_context;
2644         
2645         armv4_5_init_arch_info(target, armv4_5);
2646         
2647         target_register_timer_callback(arm7_9_handle_target_request, 1, 1, target);
2648         
2649         return ERROR_OK;
2650 }