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