]> git.sur5r.net Git - openocd/blob - src/target/arm7_9_common.c
Edgar Grimberg sharpened the str912 target script.
[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         if (target->state == TARGET_HALTED || target->state == TARGET_UNKNOWN)
747         {
748                 /* if the target wasn't running, there might be working areas allocated */
749                 target_free_all_working_areas(target);
750                 
751                 /* assert SRST and TRST */
752                 /* system would get ouf sync if we didn't reset test-logic, too */
753                 jtag_add_reset(1, 1);
754                 
755                 jtag_add_sleep(5000);
756                 
757         }
758         
759         if (jtag_reset_config & RESET_SRST_PULLS_TRST)
760         {
761                 jtag_add_reset(1, 1);
762         } else
763         {
764                 jtag_add_reset(0, 1);
765         }
766         
767         target->state = TARGET_RESET;
768         jtag_add_sleep(50000);
769         
770         armv4_5_invalidate_core_regs(target);
771
772         return ERROR_OK;
773
774 }
775
776 int arm7_9_deassert_reset(target_t *target)
777 {
778         LOG_DEBUG("target->state: %s", target_state_strings[target->state]);
779         
780         /* deassert reset lines */
781         jtag_add_reset(0, 0);
782         
783         return ERROR_OK;
784 }
785
786 int arm7_9_clear_halt(target_t *target)
787 {
788         armv4_5_common_t *armv4_5 = target->arch_info;
789         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
790         reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
791         
792         /* we used DBGRQ only if we didn't come out of reset */
793         if (!arm7_9->debug_entry_from_reset && arm7_9->use_dbgrq)
794         {
795                 /* program EmbeddedICE Debug Control Register to deassert DBGRQ
796                  */
797                 buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 0);     
798                 embeddedice_store_reg(dbg_ctrl);
799         }
800         else
801         {
802                 if (arm7_9->debug_entry_from_reset && arm7_9->has_vector_catch)
803                 {
804                         /* if we came out of reset, and vector catch is supported, we used
805                          * vector catch to enter debug state
806                          * restore the register in that case
807                          */
808                         embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_VEC_CATCH]);
809                 }
810                 else
811                 {
812                         /* restore registers if watchpoint unit 0 was in use
813                          */
814                         if (arm7_9->wp0_used)
815                         {
816                                 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK]);
817                                 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK]);
818                                 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK]);
819                         }
820                         /* control value always has to be restored, as it was either disabled, 
821                          * or enabled with possibly different bits
822                          */
823                         embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE]);
824                 }
825         }
826         
827         return ERROR_OK;
828 }
829
830 int arm7_9_soft_reset_halt(struct target_s *target)
831 {
832         armv4_5_common_t *armv4_5 = target->arch_info;
833         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
834         reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
835         reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
836         int i;
837         int retval;
838         
839         if ((retval=target->type->halt(target))!=ERROR_OK)
840                 return retval;
841         
842         for (i=0; i<10; i++)
843         {
844                 if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) != 0)
845                         break;
846                 embeddedice_read_reg(dbg_stat);
847                 if ((retval=jtag_execute_queue())!=ERROR_OK)
848                         return retval;
849                 /* do not eat all CPU, time out after 1 se*/
850                 usleep(100*1000);
851                 
852         }
853         if (i==10)
854         {
855                 LOG_ERROR("Failed to halt CPU after 1 sec");
856                 return ERROR_TARGET_TIMEOUT;
857         }
858         target->state = TARGET_HALTED;
859         
860         /* program EmbeddedICE Debug Control Register to assert DBGACK and INTDIS
861          * ensure that DBGRQ is cleared
862          */
863         buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 1);
864         buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 0);
865         buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_INTDIS, 1, 1);
866         embeddedice_store_reg(dbg_ctrl);
867         
868         arm7_9_clear_halt(target);
869         
870         /* if the target is in Thumb state, change to ARM state */
871         if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_ITBIT, 1))
872         {
873                 u32 r0_thumb, pc_thumb;
874                 LOG_DEBUG("target entered debug from Thumb state, changing to ARM");
875                 /* Entered debug from Thumb mode */
876                 armv4_5->core_state = ARMV4_5_STATE_THUMB;
877                 arm7_9->change_to_arm(target, &r0_thumb, &pc_thumb);
878         }
879         
880         /* all register content is now invalid */
881         armv4_5_invalidate_core_regs(target);
882         
883         /* SVC, ARM state, IRQ and FIQ disabled */
884         buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8, 0xd3);
885         armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
886         armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
887         
888         /* start fetching from 0x0 */
889         buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
890         armv4_5->core_cache->reg_list[15].dirty = 1;
891         armv4_5->core_cache->reg_list[15].valid = 1;
892         
893         armv4_5->core_mode = ARMV4_5_MODE_SVC;
894         armv4_5->core_state = ARMV4_5_STATE_ARM;
895         
896         /* reset registers */
897         for (i = 0; i <= 14; i++)
898         {       
899                 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).value, 0, 32, 0xffffffff);
900                 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = 1;
901                 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).valid = 1;
902         }
903         
904         target_call_event_callbacks(target, TARGET_EVENT_HALTED);
905         
906         return ERROR_OK;
907 }
908
909 int arm7_9_prepare_reset_halt(target_t *target)
910 {
911         armv4_5_common_t *armv4_5 = target->arch_info;
912         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
913         
914         /* poll the target, and resume if it was currently halted */
915         arm7_9_poll(target);
916         if (target->state == TARGET_HALTED)
917         {
918                 arm7_9_resume(target, 1, 0x0, 0, 1);
919         }
920         
921         if (arm7_9->has_vector_catch)
922         {
923                 /* program vector catch register to catch reset vector */
924                 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_VEC_CATCH], 0x1);
925         }
926         else
927         {
928                 /* program watchpoint unit to match on reset vector address */
929                 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0x3);
930                 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0x0);
931                 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x100);
932                 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], 0xf7);
933         }
934         
935         return ERROR_OK;
936 }
937
938 int arm7_9_halt(target_t *target)
939 {
940         armv4_5_common_t *armv4_5 = target->arch_info;
941         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
942         reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
943         
944         LOG_DEBUG("target->state: %s", target_state_strings[target->state]);
945         
946         if (target->state == TARGET_HALTED)
947         {
948                 LOG_WARNING("target was already halted");
949                 return ERROR_OK;
950         }
951         
952         if (target->state == TARGET_UNKNOWN)
953         {
954                 LOG_WARNING("target was in unknown state when halt was requested");
955         }
956         
957         if (target->state == TARGET_RESET) 
958         {
959                 if ((jtag_reset_config & RESET_SRST_PULLS_TRST) && jtag_srst)
960                 {
961                         LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
962                         return ERROR_TARGET_FAILURE;
963                 }
964                 else
965                 {
966                         /* we came here in a reset_halt or reset_init sequence
967                          * debug entry was already prepared in arm7_9_prepare_reset_halt()
968                          */
969                         target->debug_reason = DBG_REASON_DBGRQ;
970                         
971                         return ERROR_OK; 
972                 }
973         }
974
975         if (arm7_9->use_dbgrq)
976         {
977                 /* program EmbeddedICE Debug Control Register to assert DBGRQ
978                  */
979                 buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 1);     
980                 embeddedice_store_reg(dbg_ctrl);
981         }
982         else
983         {
984                 /* program watchpoint unit to match on any address
985                  */
986                 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0xffffffff);
987                 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffff);
988                 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x100);
989                 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], 0xf7);
990         }
991
992         target->debug_reason = DBG_REASON_DBGRQ;
993         
994         return ERROR_OK;
995 }
996
997 int arm7_9_debug_entry(target_t *target)
998 {
999         int i;
1000         u32 context[16];
1001         u32* context_p[16];
1002         u32 r0_thumb, pc_thumb;
1003         u32 cpsr;
1004         int retval;
1005         /* get pointers to arch-specific information */
1006         armv4_5_common_t *armv4_5 = target->arch_info;
1007         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1008         reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
1009         reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
1010
1011 #ifdef _DEBUG_ARM7_9_
1012         LOG_DEBUG("-");
1013 #endif
1014
1015         if (arm7_9->pre_debug_entry)
1016                 arm7_9->pre_debug_entry(target);
1017
1018         /* program EmbeddedICE Debug Control Register to assert DBGACK and INTDIS
1019          * ensure that DBGRQ is cleared
1020          */
1021         buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 1);
1022         buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 0);
1023         buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_INTDIS, 1, 1);
1024         embeddedice_store_reg(dbg_ctrl);
1025         
1026         arm7_9_clear_halt(target);
1027         
1028         if ((retval = jtag_execute_queue()) != ERROR_OK)
1029         {
1030                 switch (retval)
1031                 {
1032                         case ERROR_JTAG_QUEUE_FAILED:
1033                                 LOG_ERROR("JTAG queue failed while writing EmbeddedICE control register");
1034                                 exit(-1);
1035                                 break;
1036                         default:
1037                                 break;
1038                 }
1039         }
1040
1041         if ((retval = arm7_9->examine_debug_reason(target)) != ERROR_OK)
1042                 return retval;
1043
1044
1045         if (target->state != TARGET_HALTED)
1046         {
1047                 LOG_WARNING("target not halted");
1048                 return ERROR_TARGET_NOT_HALTED;
1049         }
1050         
1051         /* if the target is in Thumb state, change to ARM state */
1052         if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_ITBIT, 1))
1053         {
1054                 LOG_DEBUG("target entered debug from Thumb state");
1055                 /* Entered debug from Thumb mode */
1056                 armv4_5->core_state = ARMV4_5_STATE_THUMB;
1057                 arm7_9->change_to_arm(target, &r0_thumb, &pc_thumb);
1058                 LOG_DEBUG("r0_thumb: 0x%8.8x, pc_thumb: 0x%8.8x", r0_thumb, pc_thumb);
1059         }
1060         else
1061         {
1062                 LOG_DEBUG("target entered debug from ARM state");
1063                 /* Entered debug from ARM mode */
1064                 armv4_5->core_state = ARMV4_5_STATE_ARM;
1065         }
1066         
1067         for (i = 0; i < 16; i++)
1068                 context_p[i] = &context[i];
1069         /* save core registers (r0 - r15 of current core mode) */
1070         arm7_9->read_core_regs(target, 0xffff, context_p);
1071
1072         arm7_9->read_xpsr(target, &cpsr, 0);
1073         
1074         if ((retval = jtag_execute_queue()) != ERROR_OK)
1075                 return retval;
1076         
1077         /* if the core has been executing in Thumb state, set the T bit */
1078         if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
1079                 cpsr |= 0x20;   
1080         
1081         buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32, cpsr);
1082         armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 0;
1083         armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
1084         
1085         armv4_5->core_mode = cpsr & 0x1f;
1086         
1087         if (armv4_5_mode_to_number(armv4_5->core_mode) == -1)
1088         {
1089                 target->state = TARGET_UNKNOWN;
1090                 LOG_ERROR("cpsr contains invalid mode value - communication failure");
1091                 return ERROR_TARGET_FAILURE;
1092         }
1093
1094         LOG_DEBUG("target entered debug state in %s mode", armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)]);
1095         
1096         if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
1097         {
1098                 LOG_DEBUG("thumb state, applying fixups");
1099                 context[0] = r0_thumb;
1100                 context[15] = pc_thumb;
1101         } else if (armv4_5->core_state == ARMV4_5_STATE_ARM)
1102         {
1103                 /* adjust value stored by STM */
1104                 context[15] -= 3 * 4;
1105         }
1106
1107         if ((target->debug_reason == DBG_REASON_BREAKPOINT)
1108                         || (target->debug_reason == DBG_REASON_SINGLESTEP)
1109                         || (target->debug_reason == DBG_REASON_WATCHPOINT)
1110                         || (target->debug_reason == DBG_REASON_WPTANDBKPT)
1111                         || ((target->debug_reason == DBG_REASON_DBGRQ) && (arm7_9->use_dbgrq == 0)))
1112                 context[15] -= 3 * ((armv4_5->core_state == ARMV4_5_STATE_ARM) ? 4 : 2);
1113         else if (target->debug_reason == DBG_REASON_DBGRQ)
1114                 context[15] -= arm7_9->dbgreq_adjust_pc * ((armv4_5->core_state == ARMV4_5_STATE_ARM) ? 4 : 2);
1115         else
1116         {
1117                 LOG_ERROR("unknown debug reason: %i", target->debug_reason);
1118         }
1119
1120         
1121         for (i=0; i<=15; i++)
1122         {
1123                 LOG_DEBUG("r%i: 0x%8.8x", i, context[i]);
1124                 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).value, 0, 32, context[i]);
1125                 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = 0;
1126                 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).valid = 1;
1127         }
1128         
1129         LOG_DEBUG("entered debug state at PC 0x%x", context[15]);
1130
1131         /* exceptions other than USR & SYS have a saved program status register */
1132         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))
1133         {
1134                 u32 spsr;
1135                 arm7_9->read_xpsr(target, &spsr, 1);
1136                 jtag_execute_queue();
1137                 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).value, 0, 32, spsr);
1138                 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).dirty = 0;
1139                 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).valid = 1;
1140         }
1141
1142         /* r0 and r15 (pc) have to be restored later */
1143         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;
1144         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;
1145
1146         if ((retval = jtag_execute_queue()) != ERROR_OK)
1147                 return retval;
1148
1149         if (arm7_9->post_debug_entry)
1150                 arm7_9->post_debug_entry(target);
1151
1152         return ERROR_OK;
1153 }
1154
1155 int arm7_9_full_context(target_t *target)
1156 {
1157         int i;
1158         int retval;
1159         armv4_5_common_t *armv4_5 = target->arch_info;
1160         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1161
1162         LOG_DEBUG("-");
1163         
1164         if (target->state != TARGET_HALTED)
1165         {
1166                 LOG_WARNING("target not halted");
1167                 return ERROR_TARGET_NOT_HALTED;
1168         }
1169
1170         /* iterate through processor modes (User, FIQ, IRQ, SVC, ABT, UND)
1171          * SYS shares registers with User, so we don't touch SYS
1172          */
1173         for(i = 0; i < 6; i++)
1174         {
1175                 u32 mask = 0;
1176                 u32* reg_p[16];
1177                 int j;
1178                 int valid = 1;
1179                 
1180                 /* check if there are invalid registers in the current mode 
1181                  */
1182                 for (j = 0; j <= 16; j++)
1183                 {
1184                         if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).valid == 0)
1185                                 valid = 0;
1186                 }
1187                 
1188                 if (!valid)
1189                 {
1190                         u32 tmp_cpsr;
1191                         
1192                         /* change processor mode (and mask T bit) */
1193                         tmp_cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & 0xE0;
1194                         tmp_cpsr |= armv4_5_number_to_mode(i);
1195                         tmp_cpsr &= ~0x20;
1196                         arm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0);
1197
1198                         for (j = 0; j < 15; j++)
1199                         {
1200                                 if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).valid == 0)
1201                                 {       
1202                                         reg_p[j] = (u32*)ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).value;
1203                                         mask |= 1 << j;
1204                                         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).valid = 1;
1205                                         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).dirty = 0;
1206                                 }
1207                         }
1208                         
1209                         /* if only the PSR is invalid, mask is all zeroes */
1210                         if (mask)
1211                                 arm7_9->read_core_regs(target, mask, reg_p);
1212                         
1213                         /* check if the PSR has to be read */
1214                         if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).valid == 0)
1215                         {
1216                                 arm7_9->read_xpsr(target, (u32*)ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).value, 1);
1217                                 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).valid = 1;
1218                                 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).dirty = 0;
1219                         }
1220                 }
1221         }
1222
1223         /* restore processor mode (mask T bit) */
1224         arm7_9->write_xpsr_im8(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & ~0x20, 0, 0);
1225         
1226         if ((retval = jtag_execute_queue()) != ERROR_OK)
1227         {
1228                 return retval;
1229         }
1230         return ERROR_OK;
1231 }
1232
1233 int arm7_9_restore_context(target_t *target)
1234 {
1235         armv4_5_common_t *armv4_5 = target->arch_info;
1236         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1237         reg_t *reg; 
1238         armv4_5_core_reg_t *reg_arch_info;
1239         enum armv4_5_mode current_mode = armv4_5->core_mode;
1240         int i, j;
1241         int dirty;
1242         int mode_change;
1243         
1244         LOG_DEBUG("-");
1245         
1246         if (target->state != TARGET_HALTED)
1247         {
1248                 LOG_WARNING("target not halted");
1249                 return ERROR_TARGET_NOT_HALTED;
1250         }
1251         
1252         if (arm7_9->pre_restore_context)
1253                 arm7_9->pre_restore_context(target);
1254         
1255         /* iterate through processor modes (User, FIQ, IRQ, SVC, ABT, UND)
1256          * SYS shares registers with User, so we don't touch SYS
1257          */
1258         for (i = 0; i < 6; i++)
1259         {
1260                 LOG_DEBUG("examining %s mode", armv4_5_mode_strings[i]);
1261                 dirty = 0;
1262                 mode_change = 0;
1263                 /* check if there are dirty registers in the current mode 
1264                 */
1265                 for (j = 0; j <= 16; j++)
1266                 {
1267                         reg = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j);
1268                         reg_arch_info = reg->arch_info;
1269                         if (reg->dirty == 1)
1270                         {
1271                                 if (reg->valid == 1)
1272                                 {
1273                                         dirty = 1;
1274                                         LOG_DEBUG("examining dirty reg: %s", reg->name);
1275                                         if ((reg_arch_info->mode != ARMV4_5_MODE_ANY)
1276                                                 && (reg_arch_info->mode != current_mode)
1277                                                 && !((reg_arch_info->mode == ARMV4_5_MODE_USR) && (armv4_5->core_mode == ARMV4_5_MODE_SYS)) 
1278                                                 && !((reg_arch_info->mode == ARMV4_5_MODE_SYS) && (armv4_5->core_mode == ARMV4_5_MODE_USR)))
1279                                         {
1280                                                 mode_change = 1;
1281                                                 LOG_DEBUG("require mode change");
1282                                         }
1283                                 }
1284                                 else
1285                                 {
1286                                         LOG_ERROR("BUG: dirty register '%s', but no valid data", reg->name);
1287                                 }
1288                         }
1289                 }
1290                 
1291                 if (dirty)
1292                 {
1293                         u32 mask = 0x0;
1294                         int num_regs = 0;
1295                         u32 regs[16];
1296
1297                         if (mode_change)
1298                         {
1299                                 u32 tmp_cpsr;
1300                         
1301                                 /* change processor mode (mask T bit) */
1302                                 tmp_cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & 0xE0;
1303                                 tmp_cpsr |= armv4_5_number_to_mode(i);
1304                                 tmp_cpsr &= ~0x20;
1305                                 arm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0);
1306                                 current_mode = armv4_5_number_to_mode(i);
1307                         }
1308                         
1309                         for (j = 0; j <= 14; j++)
1310                         {
1311                                 reg = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j);
1312                                 reg_arch_info = reg->arch_info;
1313                                 
1314                                 
1315                                 if (reg->dirty == 1)
1316                                 {
1317                                         regs[j] = buf_get_u32(reg->value, 0, 32);
1318                                         mask |= 1 << j;
1319                                         num_regs++;
1320                                         reg->dirty = 0;
1321                                         reg->valid = 1;
1322                                         LOG_DEBUG("writing register %i of mode %s with value 0x%8.8x", j, armv4_5_mode_strings[i], regs[j]);
1323                                 }
1324                         }
1325                         
1326                         if (mask)
1327                         {
1328                                 arm7_9->write_core_regs(target, mask, regs);
1329                         }
1330                         
1331                         reg = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16);
1332                         reg_arch_info = reg->arch_info;
1333                         if ((reg->dirty) && (reg_arch_info->mode != ARMV4_5_MODE_ANY))
1334                         {
1335                                 LOG_DEBUG("writing SPSR of mode %i with value 0x%8.8x", i, buf_get_u32(reg->value, 0, 32));
1336                                 arm7_9->write_xpsr(target, buf_get_u32(reg->value, 0, 32), 1);
1337                         }
1338                 }
1339         }
1340         
1341         if ((armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty == 0) && (armv4_5->core_mode != current_mode))
1342         {
1343                 /* restore processor mode (mask T bit) */
1344                 u32 tmp_cpsr;
1345                         
1346                 tmp_cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & 0xE0;
1347                 tmp_cpsr |= armv4_5_number_to_mode(i);
1348                 tmp_cpsr &= ~0x20;
1349                 LOG_DEBUG("writing lower 8 bit of cpsr with value 0x%2.2x", tmp_cpsr);
1350                 arm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0);
1351         }
1352         else if (armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty == 1)
1353         {
1354                 /* CPSR has been changed, full restore necessary (mask T bit) */
1355                 LOG_DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
1356                 arm7_9->write_xpsr(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32) & ~0x20, 0);
1357                 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 0;
1358                 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
1359         }
1360         
1361         /* restore PC */
1362         LOG_DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1363         arm7_9->write_pc(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1364         armv4_5->core_cache->reg_list[15].dirty = 0;
1365                         
1366         if (arm7_9->post_restore_context)
1367                 arm7_9->post_restore_context(target);
1368
1369         return ERROR_OK;
1370 }
1371
1372 int arm7_9_restart_core(struct target_s *target)
1373 {
1374         armv4_5_common_t *armv4_5 = target->arch_info;
1375         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1376         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
1377         
1378         /* set RESTART instruction */
1379         jtag_add_end_state(TAP_RTI);
1380         arm_jtag_set_instr(jtag_info, 0x4, NULL);
1381         
1382         jtag_add_runtest(1, TAP_RTI);
1383         return jtag_execute_queue();
1384 }
1385
1386 void arm7_9_enable_watchpoints(struct target_s *target)
1387 {
1388         watchpoint_t *watchpoint = target->watchpoints;
1389         
1390         while (watchpoint)
1391         {
1392                 if (watchpoint->set == 0)
1393                         arm7_9_set_watchpoint(target, watchpoint);
1394                 watchpoint = watchpoint->next;
1395         }
1396 }
1397
1398 void arm7_9_enable_breakpoints(struct target_s *target)
1399 {
1400         breakpoint_t *breakpoint = target->breakpoints;
1401         
1402         /* set any pending breakpoints */
1403         while (breakpoint)
1404         {
1405                 if (breakpoint->set == 0)
1406                         arm7_9_set_breakpoint(target, breakpoint);
1407                 breakpoint = breakpoint->next;
1408         }
1409 }
1410
1411 void arm7_9_disable_bkpts_and_wpts(struct target_s *target)
1412 {
1413         breakpoint_t *breakpoint = target->breakpoints;
1414         watchpoint_t *watchpoint = target->watchpoints;
1415
1416         /* set any pending breakpoints */
1417         while (breakpoint)
1418         {
1419                 if (breakpoint->set != 0)
1420                         arm7_9_unset_breakpoint(target, breakpoint);
1421                 breakpoint = breakpoint->next;
1422         }
1423         
1424         while (watchpoint)
1425         {
1426                 if (watchpoint->set != 0)
1427                         arm7_9_unset_watchpoint(target, watchpoint);
1428                 watchpoint = watchpoint->next;
1429         }
1430 }
1431
1432 int arm7_9_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution)
1433 {
1434         armv4_5_common_t *armv4_5 = target->arch_info;
1435         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1436         breakpoint_t *breakpoint = target->breakpoints;
1437         reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
1438         int err;
1439         
1440         LOG_DEBUG("-");
1441         
1442         if (target->state != TARGET_HALTED)
1443         {
1444                 LOG_WARNING("target not halted");
1445                 return ERROR_TARGET_NOT_HALTED;
1446         }
1447         
1448         if (!debug_execution)
1449         {
1450                 target_free_all_working_areas(target);
1451         }
1452         
1453         /* current = 1: continue on current pc, otherwise continue at <address> */
1454         if (!current)
1455                 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, address);
1456         
1457         /* the front-end may request us not to handle breakpoints */
1458         if (handle_breakpoints)
1459         {
1460                 if ((breakpoint = breakpoint_find(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32))))
1461                 {
1462                         LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint->address);
1463                         arm7_9_unset_breakpoint(target, breakpoint);
1464                         
1465                         LOG_DEBUG("enable single-step");
1466                         arm7_9->enable_single_step(target);
1467                         
1468                         target->debug_reason = DBG_REASON_SINGLESTEP;
1469
1470                         arm7_9_restore_context(target);
1471                         
1472                         if (armv4_5->core_state == ARMV4_5_STATE_ARM)
1473                                 arm7_9->branch_resume(target);
1474                         else if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
1475                         {
1476                                 arm7_9->branch_resume_thumb(target);
1477                         }
1478                         else
1479                         {
1480                                 LOG_ERROR("unhandled core state");
1481                                 return ERROR_FAIL;
1482                         }
1483                                 
1484                         buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 0);
1485                         embeddedice_write_reg(dbg_ctrl, buf_get_u32(dbg_ctrl->value, 0, dbg_ctrl->size));
1486                         err = arm7_9_execute_sys_speed(target);
1487                         
1488                         LOG_DEBUG("disable single-step");
1489                         arm7_9->disable_single_step(target);
1490
1491                         if (err != ERROR_OK)
1492                         {
1493                                 arm7_9_set_breakpoint(target, breakpoint);
1494                                 target->state = TARGET_UNKNOWN;
1495                                 return err;
1496                         }
1497
1498                         arm7_9_debug_entry(target);
1499                         LOG_DEBUG("new PC after step: 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1500
1501                         LOG_DEBUG("set breakpoint at 0x%8.8x", breakpoint->address);
1502                         arm7_9_set_breakpoint(target, breakpoint);
1503                 }
1504         }
1505         
1506         /* enable any pending breakpoints and watchpoints */
1507         arm7_9_enable_breakpoints(target);
1508         arm7_9_enable_watchpoints(target);
1509         
1510         arm7_9_restore_context(target);
1511         
1512         if (armv4_5->core_state == ARMV4_5_STATE_ARM)
1513         {
1514                 arm7_9->branch_resume(target);
1515         }
1516         else if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
1517         {
1518                 arm7_9->branch_resume_thumb(target);
1519         }
1520         else
1521         {
1522                 LOG_ERROR("unhandled core state");
1523                 return ERROR_FAIL;
1524         }
1525         
1526         /* deassert DBGACK and INTDIS */
1527         buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 0);
1528         /* INTDIS only when we really resume, not during debug execution */
1529         if (!debug_execution)
1530                 buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_INTDIS, 1, 0);
1531         embeddedice_write_reg(dbg_ctrl, buf_get_u32(dbg_ctrl->value, 0, dbg_ctrl->size));
1532         
1533         arm7_9_restart_core(target);
1534         
1535         target->debug_reason = DBG_REASON_NOTHALTED;
1536         
1537         if (!debug_execution)
1538         {
1539                 /* registers are now invalid */
1540                 armv4_5_invalidate_core_regs(target);
1541                 target->state = TARGET_RUNNING;
1542                 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1543         }
1544         else
1545         {
1546                 target->state = TARGET_DEBUG_RUNNING;
1547                 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
1548         }
1549         
1550         LOG_DEBUG("target resumed");
1551         
1552         return ERROR_OK;
1553 }
1554
1555 void arm7_9_enable_eice_step(target_t *target)
1556 {
1557         armv4_5_common_t *armv4_5 = target->arch_info;
1558         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1559         
1560         /* setup an inverse breakpoint on the current PC
1561         * - comparator 1 matches the current address
1562         * - rangeout from comparator 1 is connected to comparator 0 rangein
1563         * - comparator 0 matches any address, as long as rangein is low */
1564         embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0xffffffff);
1565         embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffff);
1566         embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x100);
1567         embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], 0x77);
1568         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));
1569         embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK], 0);
1570         embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK], 0xffffffff);
1571         embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], 0x0);
1572         embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK], 0xf7);
1573 }
1574
1575 void arm7_9_disable_eice_step(target_t *target)
1576 {
1577         armv4_5_common_t *armv4_5 = target->arch_info;
1578         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1579
1580         embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK]);
1581         embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK]);
1582         embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE]);
1583         embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK]);
1584         embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_VALUE]);
1585         embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK]);
1586         embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK]);
1587         embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK]);
1588         embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE]);
1589 }
1590
1591 int arm7_9_step(struct target_s *target, int current, u32 address, int handle_breakpoints)
1592 {
1593         armv4_5_common_t *armv4_5 = target->arch_info;
1594         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1595         breakpoint_t *breakpoint = NULL;
1596         int err;
1597
1598         if (target->state != TARGET_HALTED)
1599         {
1600                 LOG_WARNING("target not halted");
1601                 return ERROR_TARGET_NOT_HALTED;
1602         }
1603         
1604         /* current = 1: continue on current pc, otherwise continue at <address> */
1605         if (!current)
1606                 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, address);
1607         
1608         /* the front-end may request us not to handle breakpoints */
1609         if (handle_breakpoints)
1610                 if ((breakpoint = breakpoint_find(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32))))
1611                         arm7_9_unset_breakpoint(target, breakpoint);
1612         
1613         target->debug_reason = DBG_REASON_SINGLESTEP;
1614
1615         arm7_9_restore_context(target);
1616         
1617         arm7_9->enable_single_step(target);
1618         
1619         if (armv4_5->core_state == ARMV4_5_STATE_ARM)
1620         {
1621                 arm7_9->branch_resume(target);
1622         }
1623         else if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
1624         {
1625                 arm7_9->branch_resume_thumb(target);
1626         }
1627         else
1628         {
1629                 LOG_ERROR("unhandled core state");
1630                 return ERROR_FAIL;
1631         }
1632         
1633         target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1634
1635         err = arm7_9_execute_sys_speed(target);
1636         arm7_9->disable_single_step(target);
1637         
1638         /* registers are now invalid */
1639         armv4_5_invalidate_core_regs(target);
1640         
1641         if (err != ERROR_OK)
1642         {
1643                 target->state = TARGET_UNKNOWN;
1644         } else {
1645                 arm7_9_debug_entry(target);
1646                 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
1647                 LOG_DEBUG("target stepped");
1648         }
1649         
1650         if (breakpoint)
1651                 arm7_9_set_breakpoint(target, breakpoint);
1652         
1653         return err;
1654
1655 }
1656
1657 int arm7_9_read_core_reg(struct target_s *target, int num, enum armv4_5_mode mode)
1658 {
1659         u32* reg_p[16];
1660         u32 value;
1661         int retval;
1662         armv4_5_common_t *armv4_5 = target->arch_info;
1663         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1664         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;
1665         
1666         if ((num < 0) || (num > 16))
1667                 return ERROR_INVALID_ARGUMENTS;
1668         
1669         if ((mode != ARMV4_5_MODE_ANY)
1670                         && (mode != armv4_5->core_mode)
1671                         && (reg_mode != ARMV4_5_MODE_ANY))
1672         {
1673                 u32 tmp_cpsr;
1674                         
1675                 /* change processor mode (mask T bit) */
1676                 tmp_cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & 0xE0;
1677                 tmp_cpsr |= mode;
1678                 tmp_cpsr &= ~0x20;
1679                 arm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0);
1680         }
1681         
1682         if ((num >= 0) && (num <= 15))
1683         {
1684                 /* read a normal core register */
1685                 reg_p[num] = &value;
1686                 
1687                 arm7_9->read_core_regs(target, 1 << num, reg_p);
1688         }
1689         else
1690         {
1691                 /* read a program status register
1692                  * if the register mode is MODE_ANY, we read the cpsr, otherwise a spsr
1693                  */
1694                 armv4_5_core_reg_t *arch_info = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).arch_info;
1695                 int spsr = (arch_info->mode == ARMV4_5_MODE_ANY) ? 0 : 1;
1696                 
1697                 arm7_9->read_xpsr(target, &value, spsr);
1698         }
1699         
1700         if ((retval = jtag_execute_queue()) != ERROR_OK)
1701         {
1702                 return retval;
1703         }
1704                 
1705         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).valid = 1;
1706         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).dirty = 0;
1707         buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).value, 0, 32, value);
1708                 
1709         if ((mode != ARMV4_5_MODE_ANY)
1710                         && (mode != armv4_5->core_mode)
1711                         && (reg_mode != ARMV4_5_MODE_ANY))      {
1712                 /* restore processor mode (mask T bit) */
1713                 arm7_9->write_xpsr_im8(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & ~0x20, 0, 0);
1714         }
1715         
1716         return ERROR_OK;
1717         
1718 }
1719
1720 int arm7_9_write_core_reg(struct target_s *target, int num, enum armv4_5_mode mode, u32 value)
1721 {
1722         u32 reg[16];
1723         armv4_5_common_t *armv4_5 = target->arch_info;
1724         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1725         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;
1726
1727         if ((num < 0) || (num > 16))
1728                 return ERROR_INVALID_ARGUMENTS;
1729         
1730         if ((mode != ARMV4_5_MODE_ANY)
1731                         && (mode != armv4_5->core_mode)
1732                         && (reg_mode != ARMV4_5_MODE_ANY))      {
1733                 u32 tmp_cpsr;
1734                         
1735                 /* change processor mode (mask T bit) */
1736                 tmp_cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & 0xE0;
1737                 tmp_cpsr |= mode;
1738                 tmp_cpsr &= ~0x20;
1739                 arm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0);
1740         }
1741         
1742         if ((num >= 0) && (num <= 15))
1743         {
1744                 /* write a normal core register */
1745                 reg[num] = value;
1746                 
1747                 arm7_9->write_core_regs(target, 1 << num, reg);
1748         }
1749         else
1750         {
1751                 /* write a program status register
1752                 * if the register mode is MODE_ANY, we write the cpsr, otherwise a spsr
1753                 */
1754                 armv4_5_core_reg_t *arch_info = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).arch_info;
1755                 int spsr = (arch_info->mode == ARMV4_5_MODE_ANY) ? 0 : 1;
1756                 
1757                 /* if we're writing the CPSR, mask the T bit */
1758                 if (!spsr)
1759                         value &= ~0x20;
1760                 
1761                 arm7_9->write_xpsr(target, value, spsr);
1762         }
1763         
1764         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).valid = 1;
1765         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).dirty = 0;
1766                 
1767         if ((mode != ARMV4_5_MODE_ANY)
1768                         && (mode != armv4_5->core_mode)
1769                         && (reg_mode != ARMV4_5_MODE_ANY))      {
1770                 /* restore processor mode (mask T bit) */
1771                 arm7_9->write_xpsr_im8(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & ~0x20, 0, 0);
1772         }
1773         
1774         return jtag_execute_queue();
1775 }
1776
1777 int arm7_9_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1778 {
1779         armv4_5_common_t *armv4_5 = target->arch_info;
1780         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1781         
1782         u32 reg[16];
1783         int num_accesses = 0;
1784         int thisrun_accesses;
1785         int i;
1786         u32 cpsr;
1787         int retval;
1788         int last_reg = 0;
1789         
1790         LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
1791
1792         if (target->state != TARGET_HALTED)
1793         {
1794                 LOG_WARNING("target not halted");
1795                 return ERROR_TARGET_NOT_HALTED;
1796         }
1797
1798         /* sanitize arguments */
1799         if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1800                 return ERROR_INVALID_ARGUMENTS;
1801
1802         if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
1803                 return ERROR_TARGET_UNALIGNED_ACCESS;
1804         
1805         /* load the base register with the address of the first word */
1806         reg[0] = address;
1807         arm7_9->write_core_regs(target, 0x1, reg);
1808         
1809         switch (size)
1810         {
1811                 case 4:
1812                         while (num_accesses < count)
1813                         {
1814                                 u32 reg_list;
1815                                 thisrun_accesses = ((count - num_accesses) >= 14) ? 14 : (count - num_accesses);
1816                                 reg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe;
1817                                 
1818                                 if (last_reg <= thisrun_accesses)
1819                                         last_reg = thisrun_accesses;
1820                                 
1821                                 arm7_9->load_word_regs(target, reg_list);
1822                                 
1823                                 /* fast memory reads are only safe when the target is running
1824                                  * from a sufficiently high clock (32 kHz is usually too slow)
1825                                  */
1826                                 if (arm7_9->fast_memory_access)
1827                                         arm7_9_execute_fast_sys_speed(target);
1828                                 else
1829                                         arm7_9_execute_sys_speed(target);
1830                                                                         
1831                                 arm7_9->read_core_regs_target_buffer(target, reg_list, buffer, 4);
1832                                 
1833                                 /* advance buffer, count number of accesses */
1834                                 buffer += thisrun_accesses * 4;
1835                                 num_accesses += thisrun_accesses;
1836                         }       
1837                         break;
1838                 case 2:
1839                         while (num_accesses < count)
1840                         {
1841                                 u32 reg_list;
1842                                 thisrun_accesses = ((count - num_accesses) >= 14) ? 14 : (count - num_accesses);
1843                                 reg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe;
1844                                 
1845                                 for (i = 1; i <= thisrun_accesses; i++)
1846                                 {
1847                                         if (i > last_reg)
1848                                                 last_reg = i;
1849                                         arm7_9->load_hword_reg(target, i);
1850                                         /* fast memory reads are only safe when the target is running
1851                                          * from a sufficiently high clock (32 kHz is usually too slow)
1852                                          */
1853                                         if (arm7_9->fast_memory_access)
1854                                                 arm7_9_execute_fast_sys_speed(target);
1855                                         else
1856                                                 arm7_9_execute_sys_speed(target);
1857                                 }
1858                                 
1859                                 arm7_9->read_core_regs_target_buffer(target, reg_list, buffer, 2);
1860                                 
1861                                 /* advance buffer, count number of accesses */
1862                                 buffer += thisrun_accesses * 2;
1863                                 num_accesses += thisrun_accesses;
1864                         }       
1865                         break;
1866                 case 1:
1867                         while (num_accesses < count)
1868                         {
1869                                 u32 reg_list;
1870                                 thisrun_accesses = ((count - num_accesses) >= 14) ? 14 : (count - num_accesses);
1871                                 reg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe;
1872                                 
1873                                 for (i = 1; i <= thisrun_accesses; i++)
1874                                 {
1875                                         if (i > last_reg)
1876                                                 last_reg = i;
1877                                         arm7_9->load_byte_reg(target, i);
1878                                         /* fast memory reads are only safe when the target is running
1879                                          * from a sufficiently high clock (32 kHz is usually too slow)
1880                                          */
1881                                         if (arm7_9->fast_memory_access)
1882                                                 arm7_9_execute_fast_sys_speed(target);
1883                                         else
1884                                                 arm7_9_execute_sys_speed(target);
1885                                 }
1886                                 
1887                                 arm7_9->read_core_regs_target_buffer(target, reg_list, buffer, 1);
1888                                 
1889                                 /* advance buffer, count number of accesses */
1890                                 buffer += thisrun_accesses * 1;
1891                                 num_accesses += thisrun_accesses;
1892                         }       
1893                         break;
1894                 default:
1895                         LOG_ERROR("BUG: we shouldn't get here");
1896                         exit(-1);
1897                         break;
1898         }
1899         
1900         for (i=0; i<=last_reg; i++)
1901                 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;
1902
1903         arm7_9->read_xpsr(target, &cpsr, 0);
1904         if ((retval = jtag_execute_queue()) != ERROR_OK)
1905         {
1906                 LOG_ERROR("JTAG error while reading cpsr");
1907                 return ERROR_TARGET_DATA_ABORT;
1908         }
1909
1910         if (((cpsr & 0x1f) == ARMV4_5_MODE_ABT) && (armv4_5->core_mode != ARMV4_5_MODE_ABT))
1911         {
1912                 LOG_WARNING("memory read caused data abort (address: 0x%8.8x, size: 0x%x, count: 0x%x)", address, size, count);
1913
1914                 arm7_9->write_xpsr_im8(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & ~0x20, 0, 0);
1915
1916                 return ERROR_TARGET_DATA_ABORT;
1917         }
1918         
1919         return ERROR_OK;
1920 }
1921
1922 int arm7_9_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1923 {
1924         armv4_5_common_t *armv4_5 = target->arch_info;
1925         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1926         reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
1927         
1928         u32 reg[16];
1929         int num_accesses = 0;
1930         int thisrun_accesses;
1931         int i;
1932         u32 cpsr;
1933         int retval;
1934         int last_reg = 0;
1935
1936 #ifdef _DEBUG_ARM7_9_
1937         LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
1938 #endif
1939
1940         if (target->state != TARGET_HALTED)
1941         {
1942                 LOG_WARNING("target not halted");
1943                 return ERROR_TARGET_NOT_HALTED;
1944         }
1945
1946         /* sanitize arguments */
1947         if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1948                 return ERROR_INVALID_ARGUMENTS;
1949
1950         if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
1951                 return ERROR_TARGET_UNALIGNED_ACCESS;
1952         
1953         /* load the base register with the address of the first word */
1954         reg[0] = address;
1955         arm7_9->write_core_regs(target, 0x1, reg);
1956         
1957         /* Clear DBGACK, to make sure memory fetches work as expected */
1958         buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 0);
1959         embeddedice_store_reg(dbg_ctrl);
1960         
1961         switch (size)
1962         {
1963                 case 4:
1964                         while (num_accesses < count)
1965                         {
1966                                 u32 reg_list;
1967                                 thisrun_accesses = ((count - num_accesses) >= 14) ? 14 : (count - num_accesses);
1968                                 reg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe;
1969                                 
1970                                 for (i = 1; i <= thisrun_accesses; i++)
1971                                 {
1972                                         if (i > last_reg)
1973                                                 last_reg = i;
1974                                         reg[i] = target_buffer_get_u32(target, buffer);
1975                                         buffer += 4;
1976                                 }
1977                                 
1978                                 arm7_9->write_core_regs(target, reg_list, reg);
1979                                 
1980                                 arm7_9->store_word_regs(target, reg_list);
1981                                 
1982                                 /* fast memory writes are only safe when the target is running
1983                                  * from a sufficiently high clock (32 kHz is usually too slow)
1984                                  */
1985                                 if (arm7_9->fast_memory_access)
1986                                         arm7_9_execute_fast_sys_speed(target);
1987                                 else
1988                                         arm7_9_execute_sys_speed(target);
1989                                 
1990                                 num_accesses += thisrun_accesses;
1991                         }       
1992                         break;
1993                 case 2:
1994                         while (num_accesses < count)
1995                         {
1996                                 u32 reg_list;
1997                                 thisrun_accesses = ((count - num_accesses) >= 14) ? 14 : (count - num_accesses);
1998                                 reg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe;
1999                                 
2000                                 for (i = 1; i <= thisrun_accesses; i++)
2001                                 {
2002                                         if (i > last_reg)
2003                                                 last_reg = i;
2004                                         reg[i] = target_buffer_get_u16(target, buffer) & 0xffff;
2005                                         buffer += 2;
2006                                 }
2007                                 
2008                                 arm7_9->write_core_regs(target, reg_list, reg);
2009                                 
2010                                 for (i = 1; i <= thisrun_accesses; i++)
2011                                 {
2012                                         arm7_9->store_hword_reg(target, i);
2013                                         
2014                                         /* fast memory writes are only safe when the target is running
2015                                          * from a sufficiently high clock (32 kHz is usually too slow)
2016                                          */
2017                                         if (arm7_9->fast_memory_access)
2018                                                 arm7_9_execute_fast_sys_speed(target);
2019                                         else
2020                                                 arm7_9_execute_sys_speed(target);
2021                                 }
2022                                 
2023                                 num_accesses += thisrun_accesses;
2024                         }       
2025                         break;
2026                 case 1:
2027                         while (num_accesses < count)
2028                         {
2029                                 u32 reg_list;
2030                                 thisrun_accesses = ((count - num_accesses) >= 14) ? 14 : (count - num_accesses);
2031                                 reg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe;
2032                                 
2033                                 for (i = 1; i <= thisrun_accesses; i++)
2034                                 {
2035                                         if (i > last_reg)
2036                                                 last_reg = i;
2037                                         reg[i] = *buffer++ & 0xff;
2038                                 }
2039                                 
2040                                 arm7_9->write_core_regs(target, reg_list, reg);
2041                                 
2042                                 for (i = 1; i <= thisrun_accesses; i++)
2043                                 {
2044                                         arm7_9->store_byte_reg(target, i);
2045                                         /* fast memory writes are only safe when the target is running
2046                                          * from a sufficiently high clock (32 kHz is usually too slow)
2047                                          */
2048                                         if (arm7_9->fast_memory_access)
2049                                                 arm7_9_execute_fast_sys_speed(target);
2050                                         else
2051                                                 arm7_9_execute_sys_speed(target);
2052                                 }
2053                                 
2054                                 num_accesses += thisrun_accesses;
2055                         }       
2056                         break;
2057                 default:
2058                         LOG_ERROR("BUG: we shouldn't get here");
2059                         exit(-1);
2060                         break;
2061         }
2062         
2063         /* Re-Set DBGACK */
2064         buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 1);
2065         embeddedice_store_reg(dbg_ctrl);
2066         
2067         for (i=0; i<=last_reg; i++)
2068                 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;
2069
2070         arm7_9->read_xpsr(target, &cpsr, 0);
2071         if ((retval = jtag_execute_queue()) != ERROR_OK)
2072         {
2073                 LOG_ERROR("JTAG error while reading cpsr");
2074                 return ERROR_TARGET_DATA_ABORT;
2075         }
2076
2077         if (((cpsr & 0x1f) == ARMV4_5_MODE_ABT) && (armv4_5->core_mode != ARMV4_5_MODE_ABT))
2078         {
2079                 LOG_WARNING("memory write caused data abort (address: 0x%8.8x, size: 0x%x, count: 0x%x)", address, size, count);
2080
2081                 arm7_9->write_xpsr_im8(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & ~0x20, 0, 0);
2082
2083                 return ERROR_TARGET_DATA_ABORT;
2084         }
2085         
2086         return ERROR_OK;
2087 }
2088
2089 int arm7_9_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer)
2090 {
2091         armv4_5_common_t *armv4_5 = target->arch_info;
2092         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
2093         enum armv4_5_state core_state = armv4_5->core_state;
2094         u32 r0 = buf_get_u32(armv4_5->core_cache->reg_list[0].value, 0, 32);
2095         u32 r1 = buf_get_u32(armv4_5->core_cache->reg_list[1].value, 0, 32);
2096         u32 pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
2097         int i;
2098         
2099         u32 dcc_code[] = 
2100         {
2101                 /* MRC      TST         BNE         MRC         STR         B */
2102                 0xee101e10, 0xe3110001, 0x0afffffc, 0xee111e10, 0xe4801004, 0xeafffff9
2103         };
2104         
2105         if (!arm7_9->dcc_downloads)
2106                 return target->type->write_memory(target, address, 4, count, buffer);
2107
2108         /* regrab previously allocated working_area, or allocate a new one */
2109         if (!arm7_9->dcc_working_area)
2110         {
2111                 u8 dcc_code_buf[6 * 4];
2112                 
2113                 /* make sure we have a working area */
2114                 if (target_alloc_working_area(target, 24, &arm7_9->dcc_working_area) != ERROR_OK)
2115                 {
2116                         LOG_INFO("no working area available, falling back to memory writes");
2117                         return target->type->write_memory(target, address, 4, count, buffer);
2118                 }
2119                 
2120                 /* copy target instructions to target endianness */
2121                 for (i = 0; i < 6; i++)
2122                 {
2123                         target_buffer_set_u32(target, dcc_code_buf + i*4, dcc_code[i]);
2124                 }
2125                 
2126                 /* write DCC code to working area */
2127                 target->type->write_memory(target, arm7_9->dcc_working_area->address, 4, 6, dcc_code_buf);
2128         }
2129         
2130         buf_set_u32(armv4_5->core_cache->reg_list[0].value, 0, 32, address);
2131         armv4_5->core_cache->reg_list[0].valid = 1;
2132         armv4_5->core_cache->reg_list[0].dirty = 1;
2133         armv4_5->core_state = ARMV4_5_STATE_ARM;
2134
2135         arm7_9_resume(target, 0, arm7_9->dcc_working_area->address, 1, 1);
2136         
2137         int little=target->endianness==TARGET_LITTLE_ENDIAN;
2138         if (count>2)
2139         {
2140                 /* Handle first & last using standard embeddedice_write_reg and the middle ones w/the
2141                    core function repeated. 
2142                  */
2143                 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], fast_target_buffer_get_u32(buffer, little));
2144                 buffer+=4;
2145                 
2146                 embeddedice_reg_t *ice_reg = arm7_9->eice_cache->reg_list[EICE_COMMS_DATA].arch_info;
2147                 u8 reg_addr = ice_reg->addr & 0x1f;
2148                 int chain_pos = ice_reg->jtag_info->chain_pos;
2149                 /* we want the compiler to duplicate the code, which it does not
2150                  * do automatically.
2151                  */
2152                 if (little)
2153                 {
2154                         for (i = 1; i < count - 1; i++)
2155                         {
2156                                 embeddedice_write_reg_inner(chain_pos, reg_addr, fast_target_buffer_get_u32(buffer, little));
2157                                 buffer += 4;
2158                         }
2159                 } else
2160                 {
2161                         for (i = 1; i < count - 1; i++)
2162                         {
2163                                 embeddedice_write_reg_inner(chain_pos, reg_addr, fast_target_buffer_get_u32(buffer, little));
2164                                 buffer += 4;
2165                         }
2166                 }
2167                 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], fast_target_buffer_get_u32(buffer, little));
2168         } else
2169         {
2170                 for (i = 0; i < count; i++)
2171                 {
2172                         embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], fast_target_buffer_get_u32(buffer, little));
2173                         buffer += 4;
2174                 }
2175         }
2176         
2177         target->type->halt(target);
2178         
2179         for (i=0; i<100; i++)
2180         {
2181                 target->type->poll(target);
2182                 if (target->state == TARGET_HALTED)
2183                         break;
2184                 usleep(1000); /* sleep 1ms */
2185         }
2186         if (i == 100)
2187         {
2188                 LOG_ERROR("bulk write timed out, target not halted");
2189                 return ERROR_TARGET_TIMEOUT;
2190         }
2191         
2192         /* restore target state */
2193         buf_set_u32(armv4_5->core_cache->reg_list[0].value, 0, 32, r0);
2194         armv4_5->core_cache->reg_list[0].valid = 1;
2195         armv4_5->core_cache->reg_list[0].dirty = 1;
2196         buf_set_u32(armv4_5->core_cache->reg_list[1].value, 0, 32, r1);
2197         armv4_5->core_cache->reg_list[1].valid = 1;
2198         armv4_5->core_cache->reg_list[1].dirty = 1;
2199         buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, pc);
2200         armv4_5->core_cache->reg_list[15].valid = 1;
2201         armv4_5->core_cache->reg_list[15].dirty = 1;
2202         armv4_5->core_state = core_state;
2203         
2204         return ERROR_OK;
2205 }
2206
2207 int arm7_9_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum)
2208 {
2209         working_area_t *crc_algorithm;
2210         armv4_5_algorithm_t armv4_5_info;
2211         reg_param_t reg_params[2];
2212         int retval;
2213         
2214         u32 arm7_9_crc_code[] = {
2215                 0xE1A02000,                             /* mov          r2, r0 */
2216                 0xE3E00000,                             /* mov          r0, #0xffffffff */
2217                 0xE1A03001,                             /* mov          r3, r1 */
2218                 0xE3A04000,                             /* mov          r4, #0 */
2219                 0xEA00000B,                             /* b            ncomp */
2220                                                                 /* nbyte: */
2221                 0xE7D21004,                             /* ldrb r1, [r2, r4] */
2222                 0xE59F7030,                             /* ldr          r7, CRC32XOR */
2223                 0xE0200C01,                             /* eor          r0, r0, r1, asl 24 */
2224                 0xE3A05000,                             /* mov          r5, #0 */
2225                                                                 /* loop: */
2226                 0xE3500000,                             /* cmp          r0, #0 */
2227                 0xE1A06080,                             /* mov          r6, r0, asl #1 */
2228                 0xE2855001,                             /* add          r5, r5, #1 */
2229                 0xE1A00006,                             /* mov          r0, r6 */
2230                 0xB0260007,                             /* eorlt        r0, r6, r7 */
2231                 0xE3550008,                             /* cmp          r5, #8 */
2232                 0x1AFFFFF8,                             /* bne          loop */
2233                 0xE2844001,                             /* add          r4, r4, #1 */
2234                                                                 /* ncomp: */
2235                 0xE1540003,                             /* cmp          r4, r3 */
2236                 0x1AFFFFF1,                             /* bne          nbyte */
2237                                                                 /* end: */
2238                 0xEAFFFFFE,                             /* b            end */
2239                 0x04C11DB7                              /* CRC32XOR:    .word 0x04C11DB7 */
2240         };
2241         
2242         int i;
2243         
2244         if (target_alloc_working_area(target, sizeof(arm7_9_crc_code), &crc_algorithm) != ERROR_OK)
2245         {
2246                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2247         }
2248         
2249         /* convert flash writing code into a buffer in target endianness */
2250         for (i = 0; i < (sizeof(arm7_9_crc_code)/sizeof(u32)); i++)
2251                 target_write_u32(target, crc_algorithm->address + i*sizeof(u32), arm7_9_crc_code[i]);
2252         
2253         armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
2254         armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
2255         armv4_5_info.core_state = ARMV4_5_STATE_ARM;
2256         
2257         init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);
2258         init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
2259         
2260         buf_set_u32(reg_params[0].value, 0, 32, address);
2261         buf_set_u32(reg_params[1].value, 0, 32, count);
2262                 
2263         if ((retval = target->type->run_algorithm(target, 0, NULL, 2, reg_params,
2264                 crc_algorithm->address, crc_algorithm->address + (sizeof(arm7_9_crc_code) - 8), 20000, &armv4_5_info)) != ERROR_OK)
2265         {
2266                 LOG_ERROR("error executing arm7_9 crc algorithm");
2267                 destroy_reg_param(&reg_params[0]);
2268                 destroy_reg_param(&reg_params[1]);
2269                 target_free_working_area(target, crc_algorithm);
2270                 return retval;
2271         }
2272         
2273         *checksum = buf_get_u32(reg_params[0].value, 0, 32);
2274         
2275         destroy_reg_param(&reg_params[0]);
2276         destroy_reg_param(&reg_params[1]);
2277         
2278         target_free_working_area(target, crc_algorithm);
2279         
2280         return ERROR_OK;
2281 }
2282
2283 int arm7_9_register_commands(struct command_context_s *cmd_ctx)
2284 {
2285         command_t *arm7_9_cmd;
2286         
2287         arm7_9_cmd = register_command(cmd_ctx, NULL, "arm7_9", NULL, COMMAND_ANY, "arm7/9 specific commands");
2288
2289         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>");
2290         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>");
2291         
2292         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>");        
2293         
2294         register_command(cmd_ctx, arm7_9_cmd, "sw_bkpts", handle_arm7_9_sw_bkpts_command, COMMAND_EXEC, "support for software breakpoints <enable|disable>");
2295         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>");
2296         register_command(cmd_ctx, arm7_9_cmd, "dbgrq", handle_arm7_9_dbgrq_command,
2297                 COMMAND_ANY, "use EmbeddedICE dbgrq instead of breakpoint for target halt requests <enable|disable>");
2298         register_command(cmd_ctx, arm7_9_cmd, "fast_writes", handle_arm7_9_fast_memory_access_command,
2299                  COMMAND_ANY, "(deprecated, see: arm7_9 fast_memory_access)");
2300         register_command(cmd_ctx, arm7_9_cmd, "fast_memory_access", handle_arm7_9_fast_memory_access_command,
2301                  COMMAND_ANY, "use fast memory accesses instead of slower but potentially unsafe slow accesses <enable|disable>");
2302         register_command(cmd_ctx, arm7_9_cmd, "dcc_downloads", handle_arm7_9_dcc_downloads_command,
2303                 COMMAND_ANY, "use DCC downloads for larger memory writes <enable|disable>");
2304
2305         armv4_5_register_commands(cmd_ctx);
2306         
2307         etm_register_commands(cmd_ctx);
2308         
2309         return ERROR_OK;
2310 }
2311
2312 int handle_arm7_9_write_xpsr_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2313 {
2314         u32 value;
2315         int spsr;
2316         int retval;
2317         target_t *target = get_current_target(cmd_ctx);
2318         armv4_5_common_t *armv4_5;
2319         arm7_9_common_t *arm7_9;
2320
2321         if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
2322         {
2323                 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
2324                 return ERROR_OK;
2325         }
2326         
2327         if (target->state != TARGET_HALTED)
2328         {
2329                 command_print(cmd_ctx, "can't write registers while running");
2330                 return ERROR_OK;
2331         }
2332         
2333         if (argc < 2)
2334         {
2335                 command_print(cmd_ctx, "usage: write_xpsr <value> <not cpsr|spsr>");
2336                 return ERROR_OK;
2337         }
2338         
2339         value = strtoul(args[0], NULL, 0);
2340         spsr = strtol(args[1], NULL, 0);
2341         
2342         /* if we're writing the CPSR, mask the T bit */
2343         if (!spsr)
2344                 value &= ~0x20;
2345         
2346         arm7_9->write_xpsr(target, value, spsr);
2347         if ((retval = jtag_execute_queue()) != ERROR_OK)
2348         {
2349                 LOG_ERROR("JTAG error while writing to xpsr");
2350                 return retval;
2351         }
2352         
2353         return ERROR_OK;
2354 }
2355
2356 int handle_arm7_9_write_xpsr_im8_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2357 {
2358         u32 value;
2359         int rotate;
2360         int spsr;
2361         int retval;
2362         target_t *target = get_current_target(cmd_ctx);
2363         armv4_5_common_t *armv4_5;
2364         arm7_9_common_t *arm7_9;
2365
2366         if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
2367         {
2368                 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
2369                 return ERROR_OK;
2370         }
2371         
2372         if (target->state != TARGET_HALTED)
2373         {
2374                 command_print(cmd_ctx, "can't write registers while running");
2375                 return ERROR_OK;
2376         }
2377         
2378         if (argc < 3)
2379         {
2380                 command_print(cmd_ctx, "usage: write_xpsr_im8 <im8> <rotate> <not cpsr|spsr>");
2381                 return ERROR_OK;
2382         }
2383         
2384         value = strtoul(args[0], NULL, 0);
2385         rotate = strtol(args[1], NULL, 0);
2386         spsr = strtol(args[2], NULL, 0);
2387                 
2388         arm7_9->write_xpsr_im8(target, value, rotate, spsr);
2389         if ((retval = jtag_execute_queue()) != ERROR_OK)
2390         {
2391                 LOG_ERROR("JTAG error while writing 8-bit immediate to xpsr");
2392                 return retval;
2393         }
2394         
2395         return ERROR_OK;
2396 }
2397
2398 int handle_arm7_9_write_core_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2399 {
2400         u32 value;
2401         u32 mode;
2402         int num;
2403         target_t *target = get_current_target(cmd_ctx);
2404         armv4_5_common_t *armv4_5;
2405         arm7_9_common_t *arm7_9;
2406                 
2407         if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
2408         {
2409                 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
2410                 return ERROR_OK;
2411         }
2412         
2413         if (target->state != TARGET_HALTED)
2414         {
2415                 command_print(cmd_ctx, "can't write registers while running");
2416                 return ERROR_OK;
2417         }
2418         
2419         if (argc < 3)
2420         {
2421                 command_print(cmd_ctx, "usage: write_core_reg <num> <mode> <value>");
2422                 return ERROR_OK;
2423         }
2424         
2425         num = strtol(args[0], NULL, 0);
2426         mode = strtoul(args[1], NULL, 0);
2427         value = strtoul(args[2], NULL, 0);
2428         
2429         arm7_9_write_core_reg(target, num, mode, value);
2430         
2431         return ERROR_OK;
2432 }
2433
2434 int handle_arm7_9_sw_bkpts_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2435 {
2436         target_t *target = get_current_target(cmd_ctx);
2437         armv4_5_common_t *armv4_5;
2438         arm7_9_common_t *arm7_9;
2439         
2440         if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
2441         {
2442                 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
2443                 return ERROR_OK;
2444         }
2445         
2446         if (argc == 0)
2447         {
2448                 command_print(cmd_ctx, "software breakpoints %s", (arm7_9->sw_bkpts_enabled) ? "enabled" : "disabled");
2449                 return ERROR_OK;
2450         }
2451         
2452         if (strcmp("enable", args[0]) == 0)
2453         {
2454                 if (arm7_9->sw_bkpts_use_wp)
2455                 {
2456                         arm7_9_enable_sw_bkpts(target);
2457                 }
2458                 else
2459                 {
2460                         arm7_9->sw_bkpts_enabled = 1;
2461                 }
2462         }
2463         else if (strcmp("disable", args[0]) == 0)
2464         {
2465                 if (arm7_9->sw_bkpts_use_wp)
2466                 {
2467                         arm7_9_disable_sw_bkpts(target);
2468                 }
2469                 else
2470                 {
2471                         arm7_9->sw_bkpts_enabled = 0;
2472                 }
2473         }
2474         else
2475         {
2476                 command_print(cmd_ctx, "usage: arm7_9 sw_bkpts <enable|disable>");
2477         }
2478         
2479         command_print(cmd_ctx, "software breakpoints %s", (arm7_9->sw_bkpts_enabled) ? "enabled" : "disabled");
2480         
2481         return ERROR_OK;
2482 }
2483
2484 int handle_arm7_9_force_hw_bkpts_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2485 {
2486         target_t *target = get_current_target(cmd_ctx);
2487         armv4_5_common_t *armv4_5;
2488         arm7_9_common_t *arm7_9;
2489         
2490         if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
2491         {
2492                 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
2493                 return ERROR_OK;
2494         }
2495         
2496         if ((argc >= 1) && (strcmp("enable", args[0]) == 0))
2497         {
2498                 arm7_9->force_hw_bkpts = 1;
2499                 if (arm7_9->sw_bkpts_use_wp)
2500                 {
2501                         arm7_9_disable_sw_bkpts(target);
2502                 }
2503         }
2504         else if ((argc >= 1) && (strcmp("disable", args[0]) == 0))
2505         {
2506                 arm7_9->force_hw_bkpts = 0;
2507         }
2508         else
2509         {
2510                 command_print(cmd_ctx, "usage: arm7_9 force_hw_bkpts <enable|disable>");
2511         }
2512                 
2513         command_print(cmd_ctx, "force hardware breakpoints %s", (arm7_9->force_hw_bkpts) ? "enabled" : "disabled");
2514
2515         return ERROR_OK;
2516 }
2517
2518 int handle_arm7_9_dbgrq_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2519 {
2520         target_t *target = get_current_target(cmd_ctx);
2521         armv4_5_common_t *armv4_5;
2522         arm7_9_common_t *arm7_9;
2523         
2524         if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
2525         {
2526                 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
2527                 return ERROR_OK;
2528         }
2529         
2530         if (argc > 0)
2531         {
2532                 if (strcmp("enable", args[0]) == 0)
2533                 {
2534                         arm7_9->use_dbgrq = 1;
2535                 }
2536                 else if (strcmp("disable", args[0]) == 0)
2537                 {
2538                         arm7_9->use_dbgrq = 0;
2539                 }
2540                 else
2541                 {
2542                         command_print(cmd_ctx, "usage: arm7_9 dbgrq <enable|disable>");
2543                 }
2544         }
2545                 
2546         command_print(cmd_ctx, "use of EmbeddedICE dbgrq instead of breakpoint for target halt %s", (arm7_9->use_dbgrq) ? "enabled" : "disabled");
2547
2548         return ERROR_OK;
2549 }
2550
2551 int handle_arm7_9_fast_memory_access_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2552 {
2553         target_t *target = get_current_target(cmd_ctx);
2554         armv4_5_common_t *armv4_5;
2555         arm7_9_common_t *arm7_9;
2556         
2557         if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
2558         {
2559                 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
2560                 return ERROR_OK;
2561         }
2562         
2563         if (argc > 0)
2564         {
2565                 if (strcmp("enable", args[0]) == 0)
2566                 {
2567                         arm7_9->fast_memory_access = 1;
2568                 }
2569                 else if (strcmp("disable", args[0]) == 0)
2570                 {
2571                         arm7_9->fast_memory_access = 0;
2572                 }
2573                 else
2574                 {
2575                         command_print(cmd_ctx, "usage: arm7_9 fast_memory_access <enable|disable>");
2576                 }
2577         }
2578                 
2579         command_print(cmd_ctx, "fast memory access is %s", (arm7_9->fast_memory_access) ? "enabled" : "disabled");
2580
2581         return ERROR_OK;
2582 }
2583
2584 int handle_arm7_9_dcc_downloads_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2585 {
2586         target_t *target = get_current_target(cmd_ctx);
2587         armv4_5_common_t *armv4_5;
2588         arm7_9_common_t *arm7_9;
2589         
2590         if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
2591         {
2592                 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
2593                 return ERROR_OK;
2594         }
2595         
2596         if (argc > 0)
2597         {
2598                 if (strcmp("enable", args[0]) == 0)
2599                 {
2600                         arm7_9->dcc_downloads = 1;
2601                 }
2602                 else if (strcmp("disable", args[0]) == 0)
2603                 {
2604                         arm7_9->dcc_downloads = 0;
2605                 }
2606                 else
2607                 {
2608                         command_print(cmd_ctx, "usage: arm7_9 dcc_downloads <enable|disable>");
2609                 }
2610         }
2611                 
2612         command_print(cmd_ctx, "dcc downloads are %s", (arm7_9->dcc_downloads) ? "enabled" : "disabled");
2613
2614         return ERROR_OK;
2615 }
2616
2617 int arm7_9_init_arch_info(target_t *target, arm7_9_common_t *arm7_9)
2618 {
2619         armv4_5_common_t *armv4_5 = &arm7_9->armv4_5_common;
2620         
2621         arm7_9->common_magic = ARM7_9_COMMON_MAGIC;
2622         
2623         arm_jtag_setup_connection(&arm7_9->jtag_info);
2624         arm7_9->wp_available = 2;
2625         arm7_9->wp0_used = 0;
2626         arm7_9->wp1_used = 0;
2627         arm7_9->force_hw_bkpts = 0;
2628         arm7_9->use_dbgrq = 0;
2629         
2630         arm7_9->etm_ctx = NULL;
2631         arm7_9->has_single_step = 0;
2632         arm7_9->has_monitor_mode = 0;
2633         arm7_9->has_vector_catch = 0;
2634         
2635         arm7_9->reinit_embeddedice = 0;
2636         
2637         arm7_9->debug_entry_from_reset = 0;
2638         
2639         arm7_9->dcc_working_area = NULL;
2640         
2641         arm7_9->fast_memory_access = 0;
2642         arm7_9->dcc_downloads = 0;
2643
2644         jtag_register_event_callback(arm7_9_jtag_callback, target);
2645
2646         armv4_5->arch_info = arm7_9;
2647         armv4_5->read_core_reg = arm7_9_read_core_reg;
2648         armv4_5->write_core_reg = arm7_9_write_core_reg;
2649         armv4_5->full_context = arm7_9_full_context;
2650         
2651         armv4_5_init_arch_info(target, armv4_5);
2652         
2653         target_register_timer_callback(arm7_9_handle_target_request, 1, 1, target);
2654         
2655         return ERROR_OK;
2656 }