- Added support for ARM926EJ-S based cores
[fw/openocd] / src / target / arm926ejs.c
1 /***************************************************************************
2  *   Copyright (C) 2007 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 "arm926ejs.h"
25 #include "jtag.h"
26 #include "log.h"
27
28 #include <stdlib.h>
29 #include <string.h>
30
31 #if 0
32 #define _DEBUG_INSTRUCTION_EXECUTION_
33 #endif
34
35 /* cli handling */
36 int arm926ejs_register_commands(struct command_context_s *cmd_ctx);
37
38 int arm926ejs_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
39 int arm926ejs_handle_cp15i_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
40 int arm926ejs_handle_virt2phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
41 int arm926ejs_handle_cache_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
42 int arm926ejs_handle_md_phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
43 int arm926ejs_handle_mw_phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
44
45 int arm926ejs_handle_read_cache_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
46 int arm926ejs_handle_read_mmu_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
47
48 /* forward declarations */
49 int arm926ejs_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
50 int arm926ejs_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
51 int arm926ejs_quit();
52 int arm926ejs_arch_state(struct target_s *target, char *buf, int buf_size);
53 int arm926ejs_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
54 int arm926ejs_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
55 int arm926ejs_soft_reset_halt(struct target_s *target);
56
57 #define ARM926EJS_CP15_ADDR(opcode_1, opcode_2, CRn, CRm) ((opcode_1 << 11) | (opcode_2 << 8) | (CRn << 4) | (CRm << 0))
58
59 target_type_t arm926ejs_target =
60 {
61         .name = "arm926ejs",
62
63         .poll = arm7_9_poll,
64         .arch_state = arm926ejs_arch_state,
65
66         .halt = arm7_9_halt,
67         .resume = arm7_9_resume,
68         .step = arm7_9_step,
69
70         .assert_reset = arm7_9_assert_reset,
71         .deassert_reset = arm7_9_deassert_reset,
72         .soft_reset_halt = arm926ejs_soft_reset_halt,
73         
74         .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
75
76         .read_memory = arm7_9_read_memory,
77         .write_memory = arm926ejs_write_memory,
78         .bulk_write_memory = arm7_9_bulk_write_memory,
79
80         .run_algorithm = armv4_5_run_algorithm,
81
82         .add_breakpoint = arm7_9_add_breakpoint,
83         .remove_breakpoint = arm7_9_remove_breakpoint,
84         .add_watchpoint = arm7_9_add_watchpoint,
85         .remove_watchpoint = arm7_9_remove_watchpoint,
86
87         .register_commands = arm926ejs_register_commands,
88         .target_command = arm926ejs_target_command,
89         .init_target = arm926ejs_init_target,
90         .quit = arm926ejs_quit
91 };
92
93 int arm926ejs_read_cp15(target_t *target, u32 address, u32 *value)
94 {
95         armv4_5_common_t *armv4_5 = target->arch_info;
96         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
97         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
98         scan_field_t fields[4];
99         u8 address_buf[2];
100         u8 nr_w_buf = 0;
101         u8 access = 1;
102         
103         buf_set_u32(address_buf, 0, 14, address);
104         
105         jtag_add_end_state(TAP_RTI);
106         arm_jtag_scann(jtag_info, 0xf);
107         arm_jtag_set_instr(jtag_info, jtag_info->intest_instr);
108
109         fields[0].device = jtag_info->chain_pos;
110         fields[0].num_bits = 32;
111         fields[0].out_value = NULL;
112         fields[0].out_mask = NULL;
113         fields[0].in_value = NULL;
114         fields[0].in_check_value = NULL;
115         fields[0].in_check_mask = NULL;
116         fields[0].in_handler = NULL;
117         fields[0].in_handler_priv = NULL;
118
119         fields[1].device = jtag_info->chain_pos;
120         fields[1].num_bits = 1;
121         fields[1].out_value = &access;
122         fields[1].out_mask = NULL;
123         fields[1].in_value = &access;
124         fields[1].in_check_value = NULL;
125         fields[1].in_check_mask = NULL;
126         fields[1].in_handler = NULL;
127         fields[1].in_handler_priv = NULL;
128
129         fields[2].device = jtag_info->chain_pos;
130         fields[2].num_bits = 14;
131         fields[2].out_value = address_buf;
132         fields[2].out_mask = NULL;
133         fields[2].in_value = NULL;
134         fields[2].in_check_value = NULL;
135         fields[2].in_check_mask = NULL;
136         fields[2].in_handler = NULL;
137         fields[2].in_handler_priv = NULL;
138
139         fields[3].device = jtag_info->chain_pos;
140         fields[3].num_bits = 1;
141         fields[3].out_value = &nr_w_buf;
142         fields[3].out_mask = NULL;
143         fields[3].in_value = NULL;
144         fields[3].in_check_value = NULL;
145         fields[3].in_check_mask = NULL;
146         fields[3].in_handler = NULL;
147         fields[3].in_handler_priv = NULL;
148         
149         jtag_add_dr_scan(4, fields, -1);
150
151         /* rescan with NOP, to wait for the access to complete */
152         access = 0;
153         
154         fields[0].in_handler_priv = value;
155         fields[0].in_handler = arm_jtag_buf_to_u32;
156         
157         do
158         {
159                 jtag_add_dr_scan(4, fields, -1);
160                 jtag_execute_queue();
161         } while ((access & 1) != 1);
162
163 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
164         DEBUG("addr: 0x%x value: %8.8x", address, *value);
165 #endif
166
167         return ERROR_OK;
168 }
169
170 int arm926ejs_write_cp15(target_t *target, u32 address, u32 value)
171 {
172         armv4_5_common_t *armv4_5 = target->arch_info;
173         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
174         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
175         scan_field_t fields[4];
176         u8 value_buf[4];
177         u8 address_buf[2];
178         u8 nr_w_buf = 1;
179         u8 access = 1;
180         
181         buf_set_u32(address_buf, 0, 14, address);
182         buf_set_u32(value_buf, 0, 32, value);
183         
184         jtag_add_end_state(TAP_RTI);
185         arm_jtag_scann(jtag_info, 0xf);
186         arm_jtag_set_instr(jtag_info, jtag_info->intest_instr);
187
188         fields[0].device = jtag_info->chain_pos;
189         fields[0].num_bits = 32;
190         fields[0].out_value = value_buf;
191         fields[0].out_mask = NULL;
192         fields[0].in_value = NULL;
193         fields[0].in_check_value = NULL;
194         fields[0].in_check_mask = NULL;
195         fields[0].in_handler = NULL;
196         fields[0].in_handler_priv = NULL;
197
198         fields[1].device = jtag_info->chain_pos;
199         fields[1].num_bits = 1;
200         fields[1].out_value = &access;
201         fields[1].out_mask = NULL;
202         fields[1].in_value = &access;
203         fields[1].in_check_value = NULL;
204         fields[1].in_check_mask = NULL;
205         fields[1].in_handler = NULL;
206         fields[1].in_handler_priv = NULL;
207
208         fields[2].device = jtag_info->chain_pos;
209         fields[2].num_bits = 14;
210         fields[2].out_value = address_buf;
211         fields[2].out_mask = NULL;
212         fields[2].in_value = NULL;
213         fields[2].in_check_value = NULL;
214         fields[2].in_check_mask = NULL;
215         fields[2].in_handler = NULL;
216         fields[2].in_handler_priv = NULL;
217
218         fields[3].device = jtag_info->chain_pos;
219         fields[3].num_bits = 1;
220         fields[3].out_value = &nr_w_buf;
221         fields[3].out_mask = NULL;
222         fields[3].in_value = NULL;
223         fields[3].in_check_value = NULL;
224         fields[3].in_check_mask = NULL;
225         fields[3].in_handler = NULL;
226         fields[3].in_handler_priv = NULL;
227         
228         jtag_add_dr_scan(4, fields, -1);
229
230         /* rescan with NOP, to wait for the access to complete */
231         access = 0;
232         
233         do
234         {
235                 jtag_add_dr_scan(4, fields, -1);
236                 jtag_execute_queue();
237         } while (access != 1);
238
239 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
240         DEBUG("addr: 0x%x value: %8.8x", address, value);
241 #endif
242
243         return ERROR_OK;
244 }
245
246 int arm926ejs_examine_debug_reason(target_t *target)
247 {
248         armv4_5_common_t *armv4_5 = target->arch_info;
249         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
250         reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
251         int debug_reason;
252         int retval;
253
254         embeddedice_read_reg(dbg_stat);
255         if ((retval = jtag_execute_queue()) != ERROR_OK)
256                 return retval;
257         
258         debug_reason = buf_get_u32(dbg_stat->value, 6, 4);
259         
260         switch (debug_reason)
261         {
262                 case 1:
263                         DEBUG("breakpoint from EICE unit 0");
264                         target->debug_reason = DBG_REASON_BREAKPOINT;
265                         break;
266                 case 2:
267                         DEBUG("breakpoint from EICE unit 1");
268                         target->debug_reason = DBG_REASON_BREAKPOINT;
269                         break;
270                 case 3:
271                         DEBUG("soft breakpoint (BKPT instruction)");
272                         target->debug_reason = DBG_REASON_BREAKPOINT;
273                         break;
274                 case 4:
275                         DEBUG("vector catch breakpoint");
276                         target->debug_reason = DBG_REASON_BREAKPOINT;
277                         break;
278                 case 5:
279                         DEBUG("external breakpoint");
280                         target->debug_reason = DBG_REASON_BREAKPOINT;
281                         break;
282                 case 6:
283                         DEBUG("watchpoint from EICE unit 0");
284                         target->debug_reason = DBG_REASON_WATCHPOINT;
285                         break;
286                 case 7:
287                         DEBUG("watchpoint from EICE unit 1");
288                         target->debug_reason = DBG_REASON_WATCHPOINT;
289                         break;
290                 case 8:
291                         DEBUG("external watchpoint");
292                         target->debug_reason = DBG_REASON_WATCHPOINT;
293                         break;
294                 case 9:
295                         DEBUG("internal debug request");
296                         target->debug_reason = DBG_REASON_DBGRQ;
297                         break;
298                 case 10:
299                         DEBUG("external debug request");
300                         target->debug_reason = DBG_REASON_DBGRQ;
301                         break;
302                 case 11:
303                         ERROR("BUG: debug re-entry from system speed access shouldn't be handled here");
304                         break;
305                 default:
306                         ERROR("BUG: unknown debug reason: 0x%x", debug_reason);
307                         target->debug_reason = DBG_REASON_DBGRQ;
308         }
309         
310         return ERROR_OK;
311 }
312
313 u32 arm926ejs_get_ttb(target_t *target)
314 {
315         int retval;
316         u32 ttb = 0x0;
317
318         if ((retval = arm926ejs_read_cp15(target, ARM926EJS_CP15_ADDR(0, 0, 2, 0), &ttb)) != ERROR_OK)
319                 return retval;
320
321         return ttb;
322 }
323
324 void arm926ejs_disable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
325 {
326         u32 cp15_control;
327
328         /* read cp15 control register */
329         arm926ejs_read_cp15(target, ARM926EJS_CP15_ADDR(0, 0, 1, 0), &cp15_control);
330         jtag_execute_queue();
331         
332         if (mmu)
333         {
334                 /* invalidate TLB */
335                 arm926ejs_write_cp15(target, ARM926EJS_CP15_ADDR(0, 0, 8, 7), 0x0);
336                 
337                 cp15_control &= ~0x1U;
338         }
339         
340         if (d_u_cache)
341         {
342                 u32 debug_override;
343                 /* read-modify-write CP15 debug override register 
344                  * to enable "test and clean all" */
345                 arm926ejs_read_cp15(target, ARM926EJS_CP15_ADDR(0, 0, 15, 0), &debug_override);
346                 debug_override |= 0x80000;
347                 arm926ejs_write_cp15(target, ARM926EJS_CP15_ADDR(0, 0, 15, 0), debug_override);
348                 
349                 /* clean and invalidate DCache */
350                 arm926ejs_write_cp15(target, ARM926EJS_CP15_ADDR(0, 0, 7, 5), 0x0);
351
352                 /* write CP15 debug override register 
353                  * to disable "test and clean all" */
354                 debug_override &= ~0x80000;
355                 arm926ejs_write_cp15(target, ARM926EJS_CP15_ADDR(0, 0, 15, 0), debug_override);
356                 
357                 cp15_control &= ~0x4U;
358         }
359         
360         if (i_cache)
361         {
362                 /* invalidate ICache */
363                 arm926ejs_write_cp15(target, ARM926EJS_CP15_ADDR(0, 0, 7, 5), 0x0);
364                 
365                 cp15_control &= ~0x1000U;
366         }
367         
368         arm926ejs_write_cp15(target, ARM926EJS_CP15_ADDR(0, 0, 1, 0), cp15_control);
369 }
370
371 void arm926ejs_enable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
372 {
373         u32 cp15_control;
374
375         /* read cp15 control register */
376         arm926ejs_read_cp15(target, ARM926EJS_CP15_ADDR(0, 0, 1, 0), &cp15_control);
377         jtag_execute_queue();
378                 
379         if (mmu)
380                 cp15_control |= 0x1U;
381         
382         if (d_u_cache)
383                 cp15_control |= 0x4U;
384         
385         if (i_cache)
386                 cp15_control |= 0x1000U;
387         
388         arm926ejs_write_cp15(target, ARM926EJS_CP15_ADDR(0, 0, 1, 0), cp15_control);
389 }
390
391 void arm926ejs_post_debug_entry(target_t *target)
392 {
393         armv4_5_common_t *armv4_5 = target->arch_info;
394         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
395         arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
396         arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
397         
398         /* examine cp15 control reg */
399         arm926ejs_read_cp15(target, ARM926EJS_CP15_ADDR(0, 0, 1, 0), &arm926ejs->cp15_control_reg);
400         jtag_execute_queue();
401         DEBUG("cp15_control_reg: %8.8x", arm926ejs->cp15_control_reg);
402
403         if (arm926ejs->armv4_5_mmu.armv4_5_cache.ctype == -1)
404         {
405                 u32 cache_type_reg;
406                 /* identify caches */
407                 arm926ejs_read_cp15(target, ARM926EJS_CP15_ADDR(0, 1, 0, 0), &cache_type_reg);
408                 jtag_execute_queue();
409                 armv4_5_identify_cache(cache_type_reg, &arm926ejs->armv4_5_mmu.armv4_5_cache);
410         }
411
412         arm926ejs->armv4_5_mmu.mmu_enabled = (arm926ejs->cp15_control_reg & 0x1U) ? 1 : 0;
413         arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = (arm926ejs->cp15_control_reg & 0x4U) ? 1 : 0;
414         arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled = (arm926ejs->cp15_control_reg & 0x1000U) ? 1 : 0;
415
416         /* save i/d fault status and address register */
417         arm926ejs_read_cp15(target, ARM926EJS_CP15_ADDR(0, 0, 5, 0), &arm926ejs->d_fsr);
418         arm926ejs_read_cp15(target, ARM926EJS_CP15_ADDR(0, 1, 5, 0), &arm926ejs->i_fsr);
419         arm926ejs_read_cp15(target, ARM926EJS_CP15_ADDR(0, 0, 6, 0), &arm926ejs->d_far);
420         
421         DEBUG("D FSR: 0x%8.8x, D FAR: 0x%8.8x, I FSR: 0x%8.8x",
422                 arm926ejs->d_fsr, arm926ejs->d_far, arm926ejs->i_fsr);  
423
424
425         u32 cache_dbg_ctrl;
426         
427         /* read-modify-write CP15 cache debug control register 
428          * to disable I/D-cache linefills and force WT */
429         arm926ejs_read_cp15(target, ARM926EJS_CP15_ADDR(7, 0, 15, 0), &cache_dbg_ctrl);
430         cache_dbg_ctrl |= 0x7;
431         arm926ejs_write_cp15(target, ARM926EJS_CP15_ADDR(7, 0, 15, 0), cache_dbg_ctrl);
432
433 }
434
435 void arm926ejs_pre_restore_context(target_t *target)
436 {
437         armv4_5_common_t *armv4_5 = target->arch_info;
438         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
439         arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
440         arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
441         
442         /* restore i/d fault status and address register */
443         arm926ejs_write_cp15(target, ARM926EJS_CP15_ADDR(0, 0, 5, 0), arm926ejs->d_fsr);
444         arm926ejs_write_cp15(target, ARM926EJS_CP15_ADDR(0, 1, 5, 0), arm926ejs->i_fsr);
445         arm926ejs_write_cp15(target, ARM926EJS_CP15_ADDR(0, 0, 6, 0), arm926ejs->d_far);
446         
447         u32 cache_dbg_ctrl;
448         
449         /* read-modify-write CP15 cache debug control register 
450          * to reenable I/D-cache linefills and disable WT */
451         arm926ejs_read_cp15(target, ARM926EJS_CP15_ADDR(7, 0, 15, 0), &cache_dbg_ctrl);
452         cache_dbg_ctrl |= 0x7;
453         arm926ejs_write_cp15(target, ARM926EJS_CP15_ADDR(7, 0, 15, 0), cache_dbg_ctrl);
454 }
455
456 int arm926ejs_get_arch_pointers(target_t *target, armv4_5_common_t **armv4_5_p, arm7_9_common_t **arm7_9_p, arm9tdmi_common_t **arm9tdmi_p, arm926ejs_common_t **arm926ejs_p)
457 {
458         armv4_5_common_t *armv4_5 = target->arch_info;
459         arm7_9_common_t *arm7_9;
460         arm9tdmi_common_t *arm9tdmi;
461         arm926ejs_common_t *arm926ejs;
462         
463         if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
464         {
465                 return -1;
466         }
467         
468         arm7_9 = armv4_5->arch_info;
469         if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
470         {
471                 return -1;
472         }
473         
474         arm9tdmi = arm7_9->arch_info;
475         if (arm9tdmi->common_magic != ARM9TDMI_COMMON_MAGIC)
476         {
477                 return -1;
478         }
479         
480         arm926ejs = arm9tdmi->arch_info;
481         if (arm926ejs->common_magic != ARM926EJS_COMMON_MAGIC)
482         {
483                 return -1;
484         }
485         
486         *armv4_5_p = armv4_5;
487         *arm7_9_p = arm7_9;
488         *arm9tdmi_p = arm9tdmi;
489         *arm926ejs_p = arm926ejs;
490         
491         return ERROR_OK;
492 }
493
494 int arm926ejs_arch_state(struct target_s *target, char *buf, int buf_size)
495 {
496         armv4_5_common_t *armv4_5 = target->arch_info;
497         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
498         arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
499         arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
500         
501         char *state[] = 
502         {
503                 "disabled", "enabled"
504         };
505         
506         if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
507         {
508                 ERROR("BUG: called for a non-ARMv4/5 target");
509                 exit(-1);
510         }
511         
512         snprintf(buf, buf_size,
513                         "target halted in %s state due to %s, current mode: %s\n"
514                         "cpsr: 0x%8.8x pc: 0x%8.8x\n"
515                         "MMU: %s, D-Cache: %s, I-Cache: %s",
516                          armv4_5_state_strings[armv4_5->core_state],
517                          target_debug_reason_strings[target->debug_reason],
518                          armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)],
519                          buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
520                          buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
521                          state[arm926ejs->armv4_5_mmu.mmu_enabled],
522                          state[arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled], 
523                          state[arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled]);
524         
525         return ERROR_OK;
526 }
527
528 int arm926ejs_soft_reset_halt(struct target_s *target)
529 {
530         armv4_5_common_t *armv4_5 = target->arch_info;
531         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
532         arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
533         arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
534         reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
535         
536         if (target->state == TARGET_RUNNING)
537         {
538                 target->type->halt(target);
539         }
540         
541         while (buf_get_u32(dbg_stat->value, EICE_DBG_CONTROL_DBGACK, 1) == 0)
542         {
543                 embeddedice_read_reg(dbg_stat);
544                 jtag_execute_queue();
545         }
546         
547         target->state = TARGET_HALTED;
548         
549         /* SVC, ARM state, IRQ and FIQ disabled */
550         buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8, 0xd3);
551         armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
552         armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
553         
554         /* start fetching from 0x0 */
555         buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
556         armv4_5->core_cache->reg_list[15].dirty = 1;
557         armv4_5->core_cache->reg_list[15].valid = 1;
558         
559         armv4_5->core_mode = ARMV4_5_MODE_SVC;
560         armv4_5->core_state = ARMV4_5_STATE_ARM;
561         
562         arm926ejs_disable_mmu_caches(target, 1, 1, 1);
563         arm926ejs->armv4_5_mmu.mmu_enabled = 0;
564         arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;
565         arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;
566
567         target_call_event_callbacks(target, TARGET_EVENT_HALTED);
568         
569         return ERROR_OK;
570 }
571
572 int arm926ejs_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
573 {
574         int retval;
575         armv4_5_common_t *armv4_5 = target->arch_info;
576         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
577         arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
578         arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
579         
580         if ((retval = arm7_9_write_memory(target, address, size, count, buffer)) != ERROR_OK)
581                 return retval;
582
583         /* If ICache is enabled, we have to invalidate affected ICache lines
584          * the DCache is forced to write-through, so we don't have to clean it here
585          */
586         if (arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled)
587         {
588                 if (count <= 1)
589                 {
590                         /* invalidate ICache single entry with MVA */
591                         arm926ejs_write_cp15(target, ARM926EJS_CP15_ADDR(0, 1, 7, 5), address);
592                 }
593                 else
594                 {
595                         /* invalidate ICache */
596                         arm926ejs_write_cp15(target, ARM926EJS_CP15_ADDR(0, 0, 7, 5), address);
597                 }
598         }
599
600         return retval;
601 }
602
603 int arm926ejs_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
604 {
605         arm9tdmi_init_target(cmd_ctx, target);
606                 
607         return ERROR_OK;
608         
609 }
610
611 int arm926ejs_quit()
612 {
613         
614         return ERROR_OK;
615 }
616
617 int arm926ejs_init_arch_info(target_t *target, arm926ejs_common_t *arm926ejs, int chain_pos, char *variant)
618 {
619         arm9tdmi_common_t *arm9tdmi = &arm926ejs->arm9tdmi_common;
620         arm7_9_common_t *arm7_9 = &arm9tdmi->arm7_9_common;
621         
622         /* initialize arm9tdmi specific info (including arm7_9 and armv4_5)
623          */
624         arm9tdmi_init_arch_info(target, arm9tdmi, chain_pos, variant);
625
626         arm9tdmi->arch_info = arm926ejs;
627         arm926ejs->common_magic = ARM926EJS_COMMON_MAGIC;
628         
629         arm7_9->post_debug_entry = arm926ejs_post_debug_entry;
630         arm7_9->pre_restore_context = arm926ejs_pre_restore_context;
631         
632         arm926ejs->armv4_5_mmu.armv4_5_cache.ctype = -1;
633         arm926ejs->armv4_5_mmu.get_ttb = arm926ejs_get_ttb;
634         arm926ejs->armv4_5_mmu.read_memory = arm7_9_read_memory;
635         arm926ejs->armv4_5_mmu.write_memory = arm7_9_write_memory;
636         arm926ejs->armv4_5_mmu.disable_mmu_caches = arm926ejs_disable_mmu_caches;
637         arm926ejs->armv4_5_mmu.enable_mmu_caches = arm926ejs_enable_mmu_caches;
638         arm926ejs->armv4_5_mmu.has_tiny_pages = 1;
639         arm926ejs->armv4_5_mmu.mmu_enabled = 0;
640         
641         arm7_9->examine_debug_reason = arm926ejs_examine_debug_reason;
642         
643         return ERROR_OK;
644 }
645
646 int arm926ejs_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
647 {
648         int chain_pos;
649         char *variant = NULL;
650         arm926ejs_common_t *arm926ejs = malloc(sizeof(arm926ejs_common_t));
651         
652         if (argc < 4)
653         {
654                 ERROR("'target arm926ejs' requires at least one additional argument");
655                 exit(-1);
656         }
657         
658         chain_pos = strtoul(args[3], NULL, 0);
659         
660         if (argc >= 5)
661                 variant = args[4];
662         
663         DEBUG("chain_pos: %i, variant: %s", chain_pos, variant);
664         
665         arm926ejs_init_arch_info(target, arm926ejs, chain_pos, variant);
666
667         return ERROR_OK;
668 }
669
670 int arm926ejs_register_commands(struct command_context_s *cmd_ctx)
671 {
672         int retval;
673         command_t *arm926ejs_cmd;
674         
675                 
676         retval = arm9tdmi_register_commands(cmd_ctx);
677         
678         arm926ejs_cmd = register_command(cmd_ctx, NULL, "arm926ejs", NULL, COMMAND_ANY, "arm926ejs specific commands");
679
680         register_command(cmd_ctx, arm926ejs_cmd, "cp15", arm926ejs_handle_cp15_command, COMMAND_EXEC, "display/modify cp15 register <opcode_1> <opcode_2> <CRn> <CRm> [value]");
681         
682         register_command(cmd_ctx, arm926ejs_cmd, "cache_info", arm926ejs_handle_cache_info_command, COMMAND_EXEC, "display information about target caches");
683         register_command(cmd_ctx, arm926ejs_cmd, "virt2phys", arm926ejs_handle_virt2phys_command, COMMAND_EXEC, "translate va to pa <va>");
684
685         register_command(cmd_ctx, arm926ejs_cmd, "mdw_phys", arm926ejs_handle_md_phys_command, COMMAND_EXEC, "display memory words <physical addr> [count]");
686         register_command(cmd_ctx, arm926ejs_cmd, "mdh_phys", arm926ejs_handle_md_phys_command, COMMAND_EXEC, "display memory half-words <physical addr> [count]");
687         register_command(cmd_ctx, arm926ejs_cmd, "mdb_phys", arm926ejs_handle_md_phys_command, COMMAND_EXEC, "display memory bytes <physical addr> [count]");
688
689         register_command(cmd_ctx, arm926ejs_cmd, "mww_phys", arm926ejs_handle_mw_phys_command, COMMAND_EXEC, "write memory word <physical addr> <value>");
690         register_command(cmd_ctx, arm926ejs_cmd, "mwh_phys", arm926ejs_handle_mw_phys_command, COMMAND_EXEC, "write memory half-word <physical addr> <value>");
691         register_command(cmd_ctx, arm926ejs_cmd, "mwb_phys", arm926ejs_handle_mw_phys_command, COMMAND_EXEC, "write memory byte <physical addr> <value>");
692
693         return ERROR_OK;
694 }
695
696 int arm926ejs_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
697 {
698         int retval;
699         target_t *target = get_current_target(cmd_ctx);
700         armv4_5_common_t *armv4_5;
701         arm7_9_common_t *arm7_9;
702         arm9tdmi_common_t *arm9tdmi;
703         arm926ejs_common_t *arm926ejs;
704         int opcode_1 = strtoul(args[0], NULL, 0);
705         int opcode_2 = strtoul(args[1], NULL, 0);
706         int CRn = strtoul(args[2], NULL, 0);
707         int CRm = strtoul(args[3], NULL, 0);
708
709         if (arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs) != ERROR_OK)
710         {
711                 command_print(cmd_ctx, "current target isn't an ARM926EJ-S target");
712                 return ERROR_OK;
713         }
714         
715         if (target->state != TARGET_HALTED)
716         {
717                 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
718                 return ERROR_OK;
719         }
720         
721         if ((argc < 4) || (argc > 5))
722         {
723                 command_print(cmd_ctx, "usage: arm926ejs cp15 <opcode_1> <opcode_2> <CRn> <CRm> [value]");
724         }
725
726         if (argc == 4)
727         {
728                 u32 value;
729                 if ((retval = arm926ejs_read_cp15(target, ARM926EJS_CP15_ADDR(opcode_1, opcode_2, CRn, CRm), &value)) != ERROR_OK)
730                 {
731                         command_print(cmd_ctx, "couldn't access register");
732                         return ERROR_OK;
733                 }
734                 jtag_execute_queue();
735                 
736                 command_print(cmd_ctx, "%i %i %i %i: %8.8x", opcode_1, opcode_2, CRn, CRm, value);
737         }
738         else
739         {
740                 u32 value = strtoul(args[4], NULL, 0);
741                 if ((retval = arm926ejs_write_cp15(target, ARM926EJS_CP15_ADDR(opcode_1, opcode_2, CRn, CRm), value)) != ERROR_OK)
742                 {
743                         command_print(cmd_ctx, "couldn't access register");
744                         return ERROR_OK;
745                 }
746                 command_print(cmd_ctx, "%i %i %i %i: %8.8x", opcode_1, opcode_2, CRn, CRm, value);
747         }
748
749         return ERROR_OK;
750 }
751
752 int arm926ejs_handle_cache_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
753 {
754         target_t *target = get_current_target(cmd_ctx);
755         armv4_5_common_t *armv4_5;
756         arm7_9_common_t *arm7_9;
757         arm9tdmi_common_t *arm9tdmi;
758         arm926ejs_common_t *arm926ejs;
759         
760         if (arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs) != ERROR_OK)
761         {
762                 command_print(cmd_ctx, "current target isn't an ARM926EJ-S target");
763                 return ERROR_OK;
764         }
765         
766         return armv4_5_handle_cache_info_command(cmd_ctx, &arm926ejs->armv4_5_mmu.armv4_5_cache);
767 }
768
769 int arm926ejs_handle_virt2phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
770 {       
771         target_t *target = get_current_target(cmd_ctx);
772         armv4_5_common_t *armv4_5;
773         arm7_9_common_t *arm7_9;
774         arm9tdmi_common_t *arm9tdmi;
775         arm926ejs_common_t *arm926ejs;
776         arm_jtag_t *jtag_info;
777
778         if (arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs) != ERROR_OK)
779         {
780                 command_print(cmd_ctx, "current target isn't an ARM926EJ-S target");
781                 return ERROR_OK;
782         }
783         
784         jtag_info = &arm7_9->jtag_info;
785         
786         if (target->state != TARGET_HALTED)
787         {
788                 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
789                 return ERROR_OK;
790         }
791                 
792         return armv4_5_mmu_handle_virt2phys_command(cmd_ctx, cmd, args, argc, target, &arm926ejs->armv4_5_mmu);
793 }
794
795 int arm926ejs_handle_md_phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
796 {       
797         target_t *target = get_current_target(cmd_ctx);
798         armv4_5_common_t *armv4_5;
799         arm7_9_common_t *arm7_9;
800         arm9tdmi_common_t *arm9tdmi;
801         arm926ejs_common_t *arm926ejs;
802         arm_jtag_t *jtag_info;
803
804         if (arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs) != ERROR_OK)
805         {
806                 command_print(cmd_ctx, "current target isn't an ARM926EJ-S target");
807                 return ERROR_OK;
808         }
809         
810         jtag_info = &arm7_9->jtag_info;
811         
812         if (target->state != TARGET_HALTED)
813         {
814                 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
815                 return ERROR_OK;
816         }
817         
818         return armv4_5_mmu_handle_md_phys_command(cmd_ctx, cmd, args, argc, target, &arm926ejs->armv4_5_mmu);
819 }
820
821 int arm926ejs_handle_mw_phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
822 {       
823         target_t *target = get_current_target(cmd_ctx);
824         armv4_5_common_t *armv4_5;
825         arm7_9_common_t *arm7_9;
826         arm9tdmi_common_t *arm9tdmi;
827         arm926ejs_common_t *arm926ejs;
828         arm_jtag_t *jtag_info;
829
830         if (arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs) != ERROR_OK)
831         {
832                 command_print(cmd_ctx, "current target isn't an ARM926EJ-S target");
833                 return ERROR_OK;
834         }
835         
836         jtag_info = &arm7_9->jtag_info;
837         
838         if (target->state != TARGET_HALTED)
839         {
840                 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
841                 return ERROR_OK;
842         }
843         
844         return armv4_5_mmu_handle_mw_phys_command(cmd_ctx, cmd, args, argc, target, &arm926ejs->armv4_5_mmu);
845 }