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