David Brownell <david-b@pacbell.net> whitespace fixes.
[fw/openocd] / src / target / arm920t.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 "arm920t.h"
25 #include "jtag.h"
26 #include "log.h"
27 #include "time_support.h"
28
29 #include <stdlib.h>
30 #include <string.h>
31
32 #if 0
33 #define _DEBUG_INSTRUCTION_EXECUTION_
34 #endif
35
36 /* cli handling */
37 int arm920t_register_commands(struct command_context_s *cmd_ctx);
38
39 int arm920t_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
40 int arm920t_handle_cp15i_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
41 int arm920t_handle_virt2phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
42 int arm920t_handle_cache_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
43 int arm920t_handle_md_phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
44 int arm920t_handle_mw_phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
45
46 int arm920t_handle_read_cache_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
47 int arm920t_handle_read_mmu_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
48
49 /* forward declarations */
50 int arm920t_target_create(struct target_s *target, Jim_Interp *interp);
51 int arm920t_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
52 int arm920t_quit(void);
53 int arm920t_arch_state(struct target_s *target);
54 int arm920t_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
55 int arm920t_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
56 int arm920t_soft_reset_halt(struct target_s *target);
57
58 #define ARM920T_CP15_PHYS_ADDR(x, y, z) ((x << 5) | (y << 1) << (z))
59
60 target_type_t arm920t_target =
61 {
62         .name = "arm920t",
63
64         .poll = arm7_9_poll,
65         .arch_state = arm920t_arch_state,
66
67         .target_request_data = arm7_9_target_request_data,
68
69         .halt = arm7_9_halt,
70         .resume = arm7_9_resume,
71         .step = arm7_9_step,
72
73         .assert_reset = arm7_9_assert_reset,
74         .deassert_reset = arm7_9_deassert_reset,
75         .soft_reset_halt = arm920t_soft_reset_halt,
76
77         .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
78
79         .read_memory = arm920t_read_memory,
80         .write_memory = arm920t_write_memory,
81         .bulk_write_memory = arm7_9_bulk_write_memory,
82         .checksum_memory = arm7_9_checksum_memory,
83         .blank_check_memory = arm7_9_blank_check_memory,
84
85         .run_algorithm = armv4_5_run_algorithm,
86
87         .add_breakpoint = arm7_9_add_breakpoint,
88         .remove_breakpoint = arm7_9_remove_breakpoint,
89         .add_watchpoint = arm7_9_add_watchpoint,
90         .remove_watchpoint = arm7_9_remove_watchpoint,
91
92         .register_commands = arm920t_register_commands,
93         .target_create = arm920t_target_create,
94         .init_target = arm920t_init_target,
95         .examine = arm9tdmi_examine,
96         .quit = arm920t_quit
97 };
98
99 int arm920t_read_cp15_physical(target_t *target, int reg_addr, u32 *value)
100 {
101         armv4_5_common_t *armv4_5 = target->arch_info;
102         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
103         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
104         scan_field_t fields[4];
105         u8 access_type_buf = 1;
106         u8 reg_addr_buf = reg_addr & 0x3f;
107         u8 nr_w_buf = 0;
108
109         jtag_add_end_state(TAP_IDLE);
110         arm_jtag_scann(jtag_info, 0xf);
111         arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
112
113         fields[0].tap = jtag_info->tap;
114         fields[0].num_bits = 1;
115         fields[0].out_value = &access_type_buf;
116         fields[0].in_value = NULL;
117
118         fields[1].tap = jtag_info->tap;
119         fields[1].num_bits = 32;
120         fields[1].out_value = NULL;
121         fields[1].in_value = NULL;
122
123         fields[2].tap = jtag_info->tap;
124         fields[2].num_bits = 6;
125         fields[2].out_value = &reg_addr_buf;
126         fields[2].in_value = NULL;
127
128         fields[3].tap = jtag_info->tap;
129         fields[3].num_bits = 1;
130         fields[3].out_value = &nr_w_buf;
131         fields[3].in_value = NULL;
132
133         jtag_add_dr_scan(4, fields, TAP_INVALID);
134
135         u8 tmp[4];
136         fields[1].in_value = tmp;
137
138         jtag_add_dr_scan_now(4, fields, TAP_INVALID);
139
140         *value=le_to_h_u32(tmp);
141
142         #ifdef _DEBUG_INSTRUCTION_EXECUTION_
143         jtag_execute_queue();
144         LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value);
145 #endif
146
147         return ERROR_OK;
148 }
149
150 int arm920t_write_cp15_physical(target_t *target, int reg_addr, u32 value)
151 {
152         armv4_5_common_t *armv4_5 = target->arch_info;
153         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
154         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
155         scan_field_t fields[4];
156         u8 access_type_buf = 1;
157         u8 reg_addr_buf = reg_addr & 0x3f;
158         u8 nr_w_buf = 1;
159         u8 value_buf[4];
160
161         buf_set_u32(value_buf, 0, 32, value);
162
163         jtag_add_end_state(TAP_IDLE);
164         arm_jtag_scann(jtag_info, 0xf);
165         arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
166
167         fields[0].tap = jtag_info->tap;
168         fields[0].num_bits = 1;
169         fields[0].out_value = &access_type_buf;
170         fields[0].in_value = NULL;
171
172         fields[1].tap = jtag_info->tap;
173         fields[1].num_bits = 32;
174         fields[1].out_value = value_buf;
175         fields[1].in_value = NULL;
176
177         fields[2].tap = jtag_info->tap;
178         fields[2].num_bits = 6;
179         fields[2].out_value = &reg_addr_buf;
180         fields[2].in_value = NULL;
181
182         fields[3].tap = jtag_info->tap;
183         fields[3].num_bits = 1;
184         fields[3].out_value = &nr_w_buf;
185         fields[3].in_value = NULL;
186
187         jtag_add_dr_scan(4, fields, TAP_INVALID);
188
189 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
190         LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, value);
191 #endif
192
193         return ERROR_OK;
194 }
195
196 int arm920t_execute_cp15(target_t *target, u32 cp15_opcode, u32 arm_opcode)
197 {
198         int retval;
199         armv4_5_common_t *armv4_5 = target->arch_info;
200         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
201         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
202         scan_field_t fields[4];
203         u8 access_type_buf = 0;         /* interpreted access */
204         u8 reg_addr_buf = 0x0;
205         u8 nr_w_buf = 0;
206         u8 cp15_opcode_buf[4];
207
208         jtag_add_end_state(TAP_IDLE);
209         arm_jtag_scann(jtag_info, 0xf);
210         arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
211
212         buf_set_u32(cp15_opcode_buf, 0, 32, cp15_opcode);
213
214         fields[0].tap = jtag_info->tap;
215         fields[0].num_bits = 1;
216         fields[0].out_value = &access_type_buf;
217         fields[0].in_value = NULL;
218
219         fields[1].tap = jtag_info->tap;
220         fields[1].num_bits = 32;
221         fields[1].out_value = cp15_opcode_buf;
222         fields[1].in_value = NULL;
223
224         fields[2].tap = jtag_info->tap;
225         fields[2].num_bits = 6;
226         fields[2].out_value = &reg_addr_buf;
227         fields[2].in_value = NULL;
228
229         fields[3].tap = jtag_info->tap;
230         fields[3].num_bits = 1;
231         fields[3].out_value = &nr_w_buf;
232         fields[3].in_value = NULL;
233
234         jtag_add_dr_scan(4, fields, TAP_INVALID);
235
236         arm9tdmi_clock_out(jtag_info, arm_opcode, 0, NULL, 0);
237         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
238         retval = arm7_9_execute_sys_speed(target);
239         if (retval != ERROR_OK)
240                 return retval;
241
242         if ((retval = jtag_execute_queue()) != ERROR_OK)
243         {
244                 LOG_ERROR("failed executing JTAG queue, exiting");
245                 return retval;
246         }
247
248         return ERROR_OK;
249 }
250
251 int arm920t_read_cp15_interpreted(target_t *target, u32 cp15_opcode, u32 address, u32 *value)
252 {
253         armv4_5_common_t *armv4_5 = target->arch_info;
254         u32* regs_p[1];
255         u32 regs[2];
256         u32 cp15c15 = 0x0;
257
258         /* load address into R1 */
259         regs[1] = address;
260         arm9tdmi_write_core_regs(target, 0x2, regs);
261
262         /* read-modify-write CP15 test state register
263         * to enable interpreted access mode */
264         arm920t_read_cp15_physical(target, 0x1e, &cp15c15);
265         jtag_execute_queue();
266         cp15c15 |= 1;   /* set interpret mode */
267         arm920t_write_cp15_physical(target, 0x1e, cp15c15);
268
269         /* execute CP15 instruction and ARM load (reading from coprocessor) */
270         arm920t_execute_cp15(target, cp15_opcode, ARMV4_5_LDR(0, 1));
271
272         /* disable interpreted access mode */
273         cp15c15 &= ~1U; /* clear interpret mode */
274         arm920t_write_cp15_physical(target, 0x1e, cp15c15);
275
276         /* retrieve value from R0 */
277         regs_p[0] = value;
278         arm9tdmi_read_core_regs(target, 0x1, regs_p);
279         jtag_execute_queue();
280
281 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
282         LOG_DEBUG("cp15_opcode: %8.8x, address: %8.8x, value: %8.8x", cp15_opcode, address, *value);
283 #endif
284
285         if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
286                 return ERROR_FAIL;
287
288         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).dirty = 1;
289         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 1).dirty = 1;
290
291         return ERROR_OK;
292 }
293
294 int arm920t_write_cp15_interpreted(target_t *target, u32 cp15_opcode, u32 value, u32 address)
295 {
296         u32 cp15c15 = 0x0;
297         armv4_5_common_t *armv4_5 = target->arch_info;
298         u32 regs[2];
299
300         /* load value, address into R0, R1 */
301         regs[0] = value;
302         regs[1] = address;
303         arm9tdmi_write_core_regs(target, 0x3, regs);
304
305         /* read-modify-write CP15 test state register
306         * to enable interpreted access mode */
307         arm920t_read_cp15_physical(target, 0x1e, &cp15c15);
308         jtag_execute_queue();
309         cp15c15 |= 1;   /* set interpret mode */
310         arm920t_write_cp15_physical(target, 0x1e, cp15c15);
311
312         /* execute CP15 instruction and ARM store (writing to coprocessor) */
313         arm920t_execute_cp15(target, cp15_opcode, ARMV4_5_STR(0, 1));
314
315         /* disable interpreted access mode */
316         cp15c15 &= ~1U; /* set interpret mode */
317         arm920t_write_cp15_physical(target, 0x1e, cp15c15);
318
319 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
320         LOG_DEBUG("cp15_opcode: %8.8x, value: %8.8x, address: %8.8x", cp15_opcode, value, address);
321 #endif
322
323         if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
324                 return ERROR_FAIL;
325
326         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).dirty = 1;
327         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 1).dirty = 1;
328
329         return ERROR_OK;
330 }
331
332 u32 arm920t_get_ttb(target_t *target)
333 {
334         int retval;
335         u32 ttb = 0x0;
336
337         if ((retval = arm920t_read_cp15_interpreted(target, 0xeebf0f51, 0x0, &ttb)) != ERROR_OK)
338                 return retval;
339
340         return ttb;
341 }
342
343 void arm920t_disable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
344 {
345         u32 cp15_control;
346
347         /* read cp15 control register */
348         arm920t_read_cp15_physical(target, 0x2, &cp15_control);
349         jtag_execute_queue();
350
351         if (mmu)
352                 cp15_control &= ~0x1U;
353
354         if (d_u_cache)
355                 cp15_control &= ~0x4U;
356
357         if (i_cache)
358                 cp15_control &= ~0x1000U;
359
360         arm920t_write_cp15_physical(target, 0x2, cp15_control);
361 }
362
363 void arm920t_enable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
364 {
365         u32 cp15_control;
366
367         /* read cp15 control register */
368         arm920t_read_cp15_physical(target, 0x2, &cp15_control);
369         jtag_execute_queue();
370
371         if (mmu)
372                 cp15_control |= 0x1U;
373
374         if (d_u_cache)
375                 cp15_control |= 0x4U;
376
377         if (i_cache)
378                 cp15_control |= 0x1000U;
379
380         arm920t_write_cp15_physical(target, 0x2, cp15_control);
381 }
382
383 void arm920t_post_debug_entry(target_t *target)
384 {
385         u32 cp15c15;
386         armv4_5_common_t *armv4_5 = target->arch_info;
387         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
388         arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
389         arm920t_common_t *arm920t = arm9tdmi->arch_info;
390
391         /* examine cp15 control reg */
392         arm920t_read_cp15_physical(target, 0x2, &arm920t->cp15_control_reg);
393         jtag_execute_queue();
394         LOG_DEBUG("cp15_control_reg: %8.8x", arm920t->cp15_control_reg);
395
396         if (arm920t->armv4_5_mmu.armv4_5_cache.ctype == -1)
397         {
398                 u32 cache_type_reg;
399                 /* identify caches */
400                 arm920t_read_cp15_physical(target, 0x1, &cache_type_reg);
401                 jtag_execute_queue();
402                 armv4_5_identify_cache(cache_type_reg, &arm920t->armv4_5_mmu.armv4_5_cache);
403         }
404
405         arm920t->armv4_5_mmu.mmu_enabled = (arm920t->cp15_control_reg & 0x1U) ? 1 : 0;
406         arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = (arm920t->cp15_control_reg & 0x4U) ? 1 : 0;
407         arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = (arm920t->cp15_control_reg & 0x1000U) ? 1 : 0;
408
409         /* save i/d fault status and address register */
410         arm920t_read_cp15_interpreted(target, 0xee150f10, 0x0, &arm920t->d_fsr);
411         arm920t_read_cp15_interpreted(target, 0xee150f30, 0x0, &arm920t->i_fsr);
412         arm920t_read_cp15_interpreted(target, 0xee160f10, 0x0, &arm920t->d_far);
413         arm920t_read_cp15_interpreted(target, 0xee160f30, 0x0, &arm920t->i_far);
414
415         LOG_DEBUG("D FSR: 0x%8.8x, D FAR: 0x%8.8x, I FSR: 0x%8.8x, I FAR: 0x%8.8x",
416                 arm920t->d_fsr, arm920t->d_far, arm920t->i_fsr, arm920t->i_far);
417
418         if (arm920t->preserve_cache)
419         {
420                 /* read-modify-write CP15 test state register
421                  * to disable I/D-cache linefills */
422                 arm920t_read_cp15_physical(target, 0x1e, &cp15c15);
423                 jtag_execute_queue();
424                 cp15c15 |= 0x600;
425                 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
426         }
427 }
428
429 void arm920t_pre_restore_context(target_t *target)
430 {
431         u32 cp15c15;
432         armv4_5_common_t *armv4_5 = target->arch_info;
433         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
434         arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
435         arm920t_common_t *arm920t = arm9tdmi->arch_info;
436
437         /* restore i/d fault status and address register */
438         arm920t_write_cp15_interpreted(target, 0xee050f10, arm920t->d_fsr, 0x0);
439         arm920t_write_cp15_interpreted(target, 0xee050f30, arm920t->i_fsr, 0x0);
440         arm920t_write_cp15_interpreted(target, 0xee060f10, arm920t->d_far, 0x0);
441         arm920t_write_cp15_interpreted(target, 0xee060f30, arm920t->i_far, 0x0);
442
443         /* read-modify-write CP15 test state register
444         * to reenable I/D-cache linefills */
445         if (arm920t->preserve_cache)
446         {
447                 arm920t_read_cp15_physical(target, 0x1e, &cp15c15);
448                 jtag_execute_queue();
449                 cp15c15 &= ~0x600U;
450                 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
451         }
452 }
453
454 int arm920t_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, arm920t_common_t **arm920t_p)
455 {
456         armv4_5_common_t *armv4_5 = target->arch_info;
457         arm7_9_common_t *arm7_9;
458         arm9tdmi_common_t *arm9tdmi;
459         arm920t_common_t *arm920t;
460
461         if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
462         {
463                 return -1;
464         }
465
466         arm7_9 = armv4_5->arch_info;
467         if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
468         {
469                 return -1;
470         }
471
472         arm9tdmi = arm7_9->arch_info;
473         if (arm9tdmi->common_magic != ARM9TDMI_COMMON_MAGIC)
474         {
475                 return -1;
476         }
477
478         arm920t = arm9tdmi->arch_info;
479         if (arm920t->common_magic != ARM920T_COMMON_MAGIC)
480         {
481                 return -1;
482         }
483
484         *armv4_5_p = armv4_5;
485         *arm7_9_p = arm7_9;
486         *arm9tdmi_p = arm9tdmi;
487         *arm920t_p = arm920t;
488
489         return ERROR_OK;
490 }
491
492 int arm920t_arch_state(struct target_s *target)
493 {
494         armv4_5_common_t *armv4_5 = target->arch_info;
495         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
496         arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
497         arm920t_common_t *arm920t = arm9tdmi->arch_info;
498
499         char *state[] =
500         {
501                 "disabled", "enabled"
502         };
503
504         if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
505         {
506                 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
507                 exit(-1);
508         }
509
510         LOG_USER(       "target halted in %s state due to %s, current mode: %s\n"
511                         "cpsr: 0x%8.8x pc: 0x%8.8x\n"
512                         "MMU: %s, D-Cache: %s, I-Cache: %s",
513                          armv4_5_state_strings[armv4_5->core_state],
514                          Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name,
515                          armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)],
516                          buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
517                          buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
518                          state[arm920t->armv4_5_mmu.mmu_enabled],
519                          state[arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],
520                          state[arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled]);
521
522         return ERROR_OK;
523 }
524
525 int arm920t_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
526 {
527         int retval;
528
529         retval = arm7_9_read_memory(target, address, size, count, buffer);
530
531         return retval;
532 }
533
534 int arm920t_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
535 {
536         int retval;
537         armv4_5_common_t *armv4_5 = target->arch_info;
538         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
539         arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
540         arm920t_common_t *arm920t = arm9tdmi->arch_info;
541
542         if ((retval = arm7_9_write_memory(target, address, size, count, buffer)) != ERROR_OK)
543                 return retval;
544
545         if (((size == 4) || (size == 2)) && (count == 1))
546         {
547                 if (arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled)
548                 {
549                         LOG_DEBUG("D-Cache enabled, writing through to main memory");
550                         u32 pa, cb, ap;
551                         int type, domain;
552
553                         pa = armv4_5_mmu_translate_va(target, &arm920t->armv4_5_mmu, address, &type, &cb, &domain, &ap);
554                         if (type == -1)
555                                 return ERROR_OK;
556                         /* cacheable & bufferable means write-back region */
557                         if (cb == 3)
558                                 armv4_5_mmu_write_physical(target, &arm920t->armv4_5_mmu, pa, size, count, buffer);
559                 }
560
561                 if (arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled)
562                 {
563                         LOG_DEBUG("I-Cache enabled, invalidating affected I-Cache line");
564                         arm920t_write_cp15_interpreted(target, 0xee070f35, 0x0, address);
565                 }
566         }
567
568         return retval;
569 }
570
571 int arm920t_soft_reset_halt(struct target_s *target)
572 {
573         int retval = ERROR_OK;
574         armv4_5_common_t *armv4_5 = target->arch_info;
575         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
576         arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
577         arm920t_common_t *arm920t = arm9tdmi->arch_info;
578         reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
579
580         if ((retval = target_halt(target)) != ERROR_OK)
581         {
582                 return retval;
583         }
584
585         long long then=timeval_ms();
586         int timeout;
587         while (!(timeout=((timeval_ms()-then)>1000)))
588         {
589                 if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0)
590                 {
591                         embeddedice_read_reg(dbg_stat);
592                         if ((retval = jtag_execute_queue()) != ERROR_OK)
593                         {
594                                 return retval;
595                         }
596                 } else
597                 {
598                         break;
599                 }
600                 if (debug_level>=3)
601                 {
602                         /* do not eat all CPU, time out after 1 se*/
603                         alive_sleep(100);
604                 } else
605                 {
606                         keep_alive();
607                 }
608         }
609         if (timeout)
610         {
611                 LOG_ERROR("Failed to halt CPU after 1 sec");
612                 return ERROR_TARGET_TIMEOUT;
613         }
614
615         target->state = TARGET_HALTED;
616
617         /* SVC, ARM state, IRQ and FIQ disabled */
618         buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8, 0xd3);
619         armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
620         armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
621
622         /* start fetching from 0x0 */
623         buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
624         armv4_5->core_cache->reg_list[15].dirty = 1;
625         armv4_5->core_cache->reg_list[15].valid = 1;
626
627         armv4_5->core_mode = ARMV4_5_MODE_SVC;
628         armv4_5->core_state = ARMV4_5_STATE_ARM;
629
630         arm920t_disable_mmu_caches(target, 1, 1, 1);
631         arm920t->armv4_5_mmu.mmu_enabled = 0;
632         arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;
633         arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;
634
635         if ((retval = target_call_event_callbacks(target, TARGET_EVENT_HALTED)) != ERROR_OK)
636         {
637                 return retval;
638         }
639
640         return ERROR_OK;
641 }
642
643 int arm920t_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
644 {
645         arm9tdmi_init_target(cmd_ctx, target);
646
647         return ERROR_OK;
648 }
649
650 int arm920t_quit(void)
651 {
652         return ERROR_OK;
653 }
654
655 int arm920t_init_arch_info(target_t *target, arm920t_common_t *arm920t, jtag_tap_t *tap)
656 {
657         arm9tdmi_common_t *arm9tdmi = &arm920t->arm9tdmi_common;
658         arm7_9_common_t *arm7_9 = &arm9tdmi->arm7_9_common;
659
660         /* initialize arm9tdmi specific info (including arm7_9 and armv4_5)
661          */
662         arm9tdmi_init_arch_info(target, arm9tdmi, tap);
663
664         arm9tdmi->arch_info = arm920t;
665         arm920t->common_magic = ARM920T_COMMON_MAGIC;
666
667         arm7_9->post_debug_entry = arm920t_post_debug_entry;
668         arm7_9->pre_restore_context = arm920t_pre_restore_context;
669
670         arm920t->armv4_5_mmu.armv4_5_cache.ctype = -1;
671         arm920t->armv4_5_mmu.get_ttb = arm920t_get_ttb;
672         arm920t->armv4_5_mmu.read_memory = arm7_9_read_memory;
673         arm920t->armv4_5_mmu.write_memory = arm7_9_write_memory;
674         arm920t->armv4_5_mmu.disable_mmu_caches = arm920t_disable_mmu_caches;
675         arm920t->armv4_5_mmu.enable_mmu_caches = arm920t_enable_mmu_caches;
676         arm920t->armv4_5_mmu.has_tiny_pages = 1;
677         arm920t->armv4_5_mmu.mmu_enabled = 0;
678
679         /* disabling linefills leads to lockups, so keep them enabled for now
680          * this doesn't affect correctness, but might affect timing issues, if
681          * important data is evicted from the cache during the debug session
682          * */
683         arm920t->preserve_cache = 0;
684
685         /* override hw single-step capability from ARM9TDMI */
686         arm7_9->has_single_step = 1;
687
688         return ERROR_OK;
689 }
690
691 int arm920t_target_create(struct target_s *target, Jim_Interp *interp)
692 {
693         arm920t_common_t *arm920t = calloc(1,sizeof(arm920t_common_t));
694
695         arm920t_init_arch_info(target, arm920t, target->tap);
696
697         return ERROR_OK;
698 }
699
700 int arm920t_register_commands(struct command_context_s *cmd_ctx)
701 {
702         int retval;
703         command_t *arm920t_cmd;
704
705
706         retval = arm9tdmi_register_commands(cmd_ctx);
707
708         arm920t_cmd = register_command(cmd_ctx, NULL, "arm920t", NULL, COMMAND_ANY, "arm920t specific commands");
709
710         register_command(cmd_ctx, arm920t_cmd, "cp15", arm920t_handle_cp15_command, COMMAND_EXEC, "display/modify cp15 register <num> [value]");
711         register_command(cmd_ctx, arm920t_cmd, "cp15i", arm920t_handle_cp15i_command, COMMAND_EXEC, "display/modify cp15 (interpreted access) <opcode> [value] [address]");
712         register_command(cmd_ctx, arm920t_cmd, "cache_info", arm920t_handle_cache_info_command, COMMAND_EXEC, "display information about target caches");
713         register_command(cmd_ctx, arm920t_cmd, "virt2phys", arm920t_handle_virt2phys_command, COMMAND_EXEC, "translate va to pa <va>");
714
715         register_command(cmd_ctx, arm920t_cmd, "mdw_phys", arm920t_handle_md_phys_command, COMMAND_EXEC, "display memory words <physical addr> [count]");
716         register_command(cmd_ctx, arm920t_cmd, "mdh_phys", arm920t_handle_md_phys_command, COMMAND_EXEC, "display memory half-words <physical addr> [count]");
717         register_command(cmd_ctx, arm920t_cmd, "mdb_phys", arm920t_handle_md_phys_command, COMMAND_EXEC, "display memory bytes <physical addr> [count]");
718
719         register_command(cmd_ctx, arm920t_cmd, "mww_phys", arm920t_handle_mw_phys_command, COMMAND_EXEC, "write memory word <physical addr> <value>");
720         register_command(cmd_ctx, arm920t_cmd, "mwh_phys", arm920t_handle_mw_phys_command, COMMAND_EXEC, "write memory half-word <physical addr> <value>");
721         register_command(cmd_ctx, arm920t_cmd, "mwb_phys", arm920t_handle_mw_phys_command, COMMAND_EXEC, "write memory byte <physical addr> <value>");
722
723         register_command(cmd_ctx, arm920t_cmd, "read_cache", arm920t_handle_read_cache_command, COMMAND_EXEC, "display I/D cache content");
724         register_command(cmd_ctx, arm920t_cmd, "read_mmu", arm920t_handle_read_mmu_command, COMMAND_EXEC, "display I/D mmu content");
725
726         return retval;
727 }
728
729 int arm920t_handle_read_cache_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
730 {
731         int retval = ERROR_OK;
732         target_t *target = get_current_target(cmd_ctx);
733         armv4_5_common_t *armv4_5;
734         arm7_9_common_t *arm7_9;
735         arm9tdmi_common_t *arm9tdmi;
736         arm920t_common_t *arm920t;
737         arm_jtag_t *jtag_info;
738         u32 cp15c15;
739         u32 cp15_ctrl, cp15_ctrl_saved;
740         u32 regs[16];
741         u32 *regs_p[16];
742         u32 C15_C_D_Ind, C15_C_I_Ind;
743         int i;
744         FILE *output;
745         arm920t_cache_line_t d_cache[8][64], i_cache[8][64];
746         int segment, index;
747
748         if (argc != 1)
749         {
750                 command_print(cmd_ctx, "usage: arm920t read_cache <filename>");
751                 return ERROR_OK;
752         }
753
754         if ((output = fopen(args[0], "w")) == NULL)
755         {
756                 LOG_DEBUG("error opening cache content file");
757                 return ERROR_OK;
758         }
759
760         for (i = 0; i < 16; i++)
761                 regs_p[i] = &regs[i];
762
763         if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
764         {
765                 command_print(cmd_ctx, "current target isn't an ARM920t target");
766                 return ERROR_OK;
767         }
768
769         jtag_info = &arm7_9->jtag_info;
770
771         /* disable MMU and Caches */
772         arm920t_read_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), &cp15_ctrl);
773         if ((retval = jtag_execute_queue()) != ERROR_OK)
774         {
775                 return retval;
776         }
777         cp15_ctrl_saved = cp15_ctrl;
778         cp15_ctrl &= ~(ARMV4_5_MMU_ENABLED | ARMV4_5_D_U_CACHE_ENABLED | ARMV4_5_I_CACHE_ENABLED);
779         arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), cp15_ctrl);
780
781         /* read CP15 test state register */
782         arm920t_read_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), &cp15c15);
783         jtag_execute_queue();
784
785         /* read DCache content */
786         fprintf(output, "DCache:\n");
787
788         /* go through segments 0 to nsets (8 on ARM920T, 4 on ARM922T) */
789         for (segment = 0; segment < arm920t->armv4_5_mmu.armv4_5_cache.d_u_size.nsets; segment++)
790         {
791                 fprintf(output, "\nsegment: %i\n----------", segment);
792
793                 /* Ra: r0 = SBZ(31:8):segment(7:5):SBZ(4:0) */
794                 regs[0] = 0x0 | (segment << 5);
795                 arm9tdmi_write_core_regs(target, 0x1, regs);
796
797                 /* set interpret mode */
798                 cp15c15 |= 0x1;
799                 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
800
801                 /* D CAM Read, loads current victim into C15.C.D.Ind */
802                 arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,6,2), ARMV4_5_LDR(1, 0));
803
804                 /* read current victim */
805                 arm920t_read_cp15_physical(target, 0x3d, &C15_C_D_Ind);
806
807                 /* clear interpret mode */
808                 cp15c15 &= ~0x1;
809                 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
810
811                 for (index = 0; index < 64; index++)
812                 {
813                         /* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */
814                         regs[0] = 0x0 | (segment << 5) | (index << 26);
815                         arm9tdmi_write_core_regs(target, 0x1, regs);
816
817                         /* set interpret mode */
818                         cp15c15 |= 0x1;
819                         arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
820
821                         /* Write DCache victim */
822                         arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,9,1,0), ARMV4_5_LDR(1, 0));
823
824                         /* Read D RAM */
825                         arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,10,2), ARMV4_5_LDMIA(0, 0x1fe, 0, 0));
826
827                         /* Read D CAM */
828                         arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,6,2), ARMV4_5_LDR(9, 0));
829
830                         /* clear interpret mode */
831                         cp15c15 &= ~0x1;
832                         arm920t_write_cp15_physical(target, 0x1e, cp15c15);
833
834                         /* read D RAM and CAM content */
835                         arm9tdmi_read_core_regs(target, 0x3fe, regs_p);
836                         if ((retval = jtag_execute_queue()) != ERROR_OK)
837                         {
838                                 return retval;
839                         }
840
841                         d_cache[segment][index].cam = regs[9];
842
843                         /* mask LFSR[6] */
844                         regs[9] &= 0xfffffffe;
845                         fprintf(output, "\nsegment: %i, index: %i, CAM: 0x%8.8x, content (%s):\n", segment, index, regs[9], (regs[9] & 0x10) ? "valid" : "invalid");
846
847                         for (i = 1; i < 9; i++)
848                         {
849                                  d_cache[segment][index].data[i] = regs[i];
850                                  fprintf(output, "%i: 0x%8.8x\n", i-1, regs[i]);
851                         }
852
853                 }
854
855                 /* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */
856                 regs[0] = 0x0 | (segment << 5) | (C15_C_D_Ind << 26);
857                 arm9tdmi_write_core_regs(target, 0x1, regs);
858
859                 /* set interpret mode */
860                 cp15c15 |= 0x1;
861                 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
862
863                 /* Write DCache victim */
864                 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,9,1,0), ARMV4_5_LDR(1, 0));
865
866                 /* clear interpret mode */
867                 cp15c15 &= ~0x1;
868                 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
869         }
870
871         /* read ICache content */
872         fprintf(output, "ICache:\n");
873
874         /* go through segments 0 to nsets (8 on ARM920T, 4 on ARM922T) */
875         for (segment = 0; segment < arm920t->armv4_5_mmu.armv4_5_cache.d_u_size.nsets; segment++)
876         {
877                 fprintf(output, "segment: %i\n----------", segment);
878
879                 /* Ra: r0 = SBZ(31:8):segment(7:5):SBZ(4:0) */
880                 regs[0] = 0x0 | (segment << 5);
881                 arm9tdmi_write_core_regs(target, 0x1, regs);
882
883                 /* set interpret mode */
884                 cp15c15 |= 0x1;
885                 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
886
887                 /* I CAM Read, loads current victim into C15.C.I.Ind */
888                 arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,5,2), ARMV4_5_LDR(1, 0));
889
890                 /* read current victim */
891                 arm920t_read_cp15_physical(target, 0x3b, &C15_C_I_Ind);
892
893                 /* clear interpret mode */
894                 cp15c15 &= ~0x1;
895                 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
896
897                 for (index = 0; index < 64; index++)
898                 {
899                         /* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */
900                         regs[0] = 0x0 | (segment << 5) | (index << 26);
901                         arm9tdmi_write_core_regs(target, 0x1, regs);
902
903                         /* set interpret mode */
904                         cp15c15 |= 0x1;
905                         arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
906
907                         /* Write ICache victim */
908                         arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,9,1,1), ARMV4_5_LDR(1, 0));
909
910                         /* Read I RAM */
911                         arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,9,2), ARMV4_5_LDMIA(0, 0x1fe, 0, 0));
912
913                         /* Read I CAM */
914                         arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,5,2), ARMV4_5_LDR(9, 0));
915
916                         /* clear interpret mode */
917                         cp15c15 &= ~0x1;
918                         arm920t_write_cp15_physical(target, 0x1e, cp15c15);
919
920                         /* read I RAM and CAM content */
921                         arm9tdmi_read_core_regs(target, 0x3fe, regs_p);
922                         if ((retval = jtag_execute_queue()) != ERROR_OK)
923                         {
924                                 return retval;
925                         }
926
927                         i_cache[segment][index].cam = regs[9];
928
929                         /* mask LFSR[6] */
930                         regs[9] &= 0xfffffffe;
931                         fprintf(output, "\nsegment: %i, index: %i, CAM: 0x%8.8x, content (%s):\n", segment, index, regs[9], (regs[9] & 0x10) ? "valid" : "invalid");
932
933                         for (i = 1; i < 9; i++)
934                         {
935                                  i_cache[segment][index].data[i] = regs[i];
936                                  fprintf(output, "%i: 0x%8.8x\n", i-1, regs[i]);
937                         }
938                 }
939
940                 /* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */
941                 regs[0] = 0x0 | (segment << 5) | (C15_C_D_Ind << 26);
942                 arm9tdmi_write_core_regs(target, 0x1, regs);
943
944                 /* set interpret mode */
945                 cp15c15 |= 0x1;
946                 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
947
948                 /* Write ICache victim */
949                 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,9,1,1), ARMV4_5_LDR(1, 0));
950
951                 /* clear interpret mode */
952                 cp15c15 &= ~0x1;
953                 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
954         }
955
956         /* restore CP15 MMU and Cache settings */
957         arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), cp15_ctrl_saved);
958
959         command_print(cmd_ctx, "cache content successfully output to %s", args[0]);
960
961         fclose(output);
962
963         if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
964                 return ERROR_FAIL;
965
966         /* mark registers dirty. */
967         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;
968         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 1).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 1).valid;
969         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 2).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 2).valid;
970         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 3).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 3).valid;
971         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 4).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 4).valid;
972         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 5).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 5).valid;
973         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 6).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 6).valid;
974         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 7).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 7).valid;
975         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 8).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 8).valid;
976         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 9).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 9).valid;
977
978         return ERROR_OK;
979 }
980
981 int arm920t_handle_read_mmu_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
982 {
983         int retval = ERROR_OK;
984         target_t *target = get_current_target(cmd_ctx);
985         armv4_5_common_t *armv4_5;
986         arm7_9_common_t *arm7_9;
987         arm9tdmi_common_t *arm9tdmi;
988         arm920t_common_t *arm920t;
989         arm_jtag_t *jtag_info;
990         u32 cp15c15;
991         u32 cp15_ctrl, cp15_ctrl_saved;
992         u32 regs[16];
993         u32 *regs_p[16];
994         int i;
995         FILE *output;
996         u32 Dlockdown, Ilockdown;
997         arm920t_tlb_entry_t d_tlb[64], i_tlb[64];
998         int victim;
999
1000         if (argc != 1)
1001         {
1002                 command_print(cmd_ctx, "usage: arm920t read_mmu <filename>");
1003                 return ERROR_OK;
1004         }
1005
1006         if ((output = fopen(args[0], "w")) == NULL)
1007         {
1008                 LOG_DEBUG("error opening mmu content file");
1009                 return ERROR_OK;
1010         }
1011
1012         for (i = 0; i < 16; i++)
1013                 regs_p[i] = &regs[i];
1014
1015         if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
1016         {
1017                 command_print(cmd_ctx, "current target isn't an ARM920t target");
1018                 return ERROR_OK;
1019         }
1020
1021         jtag_info = &arm7_9->jtag_info;
1022
1023         /* disable MMU and Caches */
1024         arm920t_read_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), &cp15_ctrl);
1025         if ((retval = jtag_execute_queue()) != ERROR_OK)
1026         {
1027                 return retval;
1028         }
1029         cp15_ctrl_saved = cp15_ctrl;
1030         cp15_ctrl &= ~(ARMV4_5_MMU_ENABLED | ARMV4_5_D_U_CACHE_ENABLED | ARMV4_5_I_CACHE_ENABLED);
1031         arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), cp15_ctrl);
1032
1033         /* read CP15 test state register */
1034         arm920t_read_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), &cp15c15);
1035         if ((retval = jtag_execute_queue()) != ERROR_OK)
1036         {
1037                 return retval;
1038         }
1039
1040         /* prepare reading D TLB content
1041          * */
1042
1043         /* set interpret mode */
1044         cp15c15 |= 0x1;
1045         arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
1046
1047         /* Read D TLB lockdown */
1048         arm920t_execute_cp15(target, ARMV4_5_MRC(15,0,0,10,0,0), ARMV4_5_LDR(1, 0));
1049
1050         /* clear interpret mode */
1051         cp15c15 &= ~0x1;
1052         arm920t_write_cp15_physical(target, 0x1e, cp15c15);
1053
1054         /* read D TLB lockdown stored to r1 */
1055         arm9tdmi_read_core_regs(target, 0x2, regs_p);
1056         if ((retval = jtag_execute_queue()) != ERROR_OK)
1057         {
1058                 return retval;
1059         }
1060         Dlockdown = regs[1];
1061
1062         for (victim = 0; victim < 64; victim += 8)
1063         {
1064                 /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
1065                  * base remains unchanged, victim goes through entries 0 to 63 */
1066                 regs[1] = (Dlockdown & 0xfc000000) | (victim << 20);
1067                 arm9tdmi_write_core_regs(target, 0x2, regs);
1068
1069                 /* set interpret mode */
1070                 cp15c15 |= 0x1;
1071                 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
1072
1073                 /* Write D TLB lockdown */
1074                 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,0), ARMV4_5_STR(1, 0));
1075
1076                 /* Read D TLB CAM */
1077                 arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,6,4), ARMV4_5_LDMIA(0, 0x3fc, 0, 0));
1078
1079                 /* clear interpret mode */
1080                 cp15c15 &= ~0x1;
1081                 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
1082
1083                 /* read D TLB CAM content stored to r2-r9 */
1084                 arm9tdmi_read_core_regs(target, 0x3fc, regs_p);
1085                 if ((retval = jtag_execute_queue()) != ERROR_OK)
1086                 {
1087                         return retval;
1088                 }
1089
1090                 for (i = 0; i < 8; i++)
1091                         d_tlb[victim + i].cam = regs[i + 2];
1092         }
1093
1094         for (victim = 0; victim < 64; victim++)
1095         {
1096                 /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
1097                  * base remains unchanged, victim goes through entries 0 to 63 */
1098                 regs[1] = (Dlockdown & 0xfc000000) | (victim << 20);
1099                 arm9tdmi_write_core_regs(target, 0x2, regs);
1100
1101                 /* set interpret mode */
1102                 cp15c15 |= 0x1;
1103                 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
1104
1105                 /* Write D TLB lockdown */
1106                 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,0), ARMV4_5_STR(1, 0));
1107
1108                 /* Read D TLB RAM1 */
1109                 arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,10,4), ARMV4_5_LDR(2,0));
1110
1111                 /* Read D TLB RAM2 */
1112                 arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,2,5), ARMV4_5_LDR(3,0));
1113
1114                 /* clear interpret mode */
1115                 cp15c15 &= ~0x1;
1116                 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
1117
1118                 /* read D TLB RAM content stored to r2 and r3 */
1119                 arm9tdmi_read_core_regs(target, 0xc, regs_p);
1120                 if ((retval = jtag_execute_queue()) != ERROR_OK)
1121                 {
1122                         return retval;
1123                 }
1124
1125                 d_tlb[victim].ram1 = regs[2];
1126                 d_tlb[victim].ram2 = regs[3];
1127         }
1128
1129         /* restore D TLB lockdown */
1130         regs[1] = Dlockdown;
1131         arm9tdmi_write_core_regs(target, 0x2, regs);
1132
1133         /* Write D TLB lockdown */
1134         arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,0), ARMV4_5_STR(1, 0));
1135
1136         /* prepare reading I TLB content
1137          * */
1138
1139         /* set interpret mode */
1140         cp15c15 |= 0x1;
1141         arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
1142
1143         /* Read I TLB lockdown */
1144         arm920t_execute_cp15(target, ARMV4_5_MRC(15,0,0,10,0,1), ARMV4_5_LDR(1, 0));
1145
1146         /* clear interpret mode */
1147         cp15c15 &= ~0x1;
1148         arm920t_write_cp15_physical(target, 0x1e, cp15c15);
1149
1150         /* read I TLB lockdown stored to r1 */
1151         arm9tdmi_read_core_regs(target, 0x2, regs_p);
1152         if ((retval = jtag_execute_queue()) != ERROR_OK)
1153         {
1154                 return retval;
1155         }
1156         Ilockdown = regs[1];
1157
1158         for (victim = 0; victim < 64; victim += 8)
1159         {
1160                 /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
1161                  * base remains unchanged, victim goes through entries 0 to 63 */
1162                 regs[1] = (Ilockdown & 0xfc000000) | (victim << 20);
1163                 arm9tdmi_write_core_regs(target, 0x2, regs);
1164
1165                 /* set interpret mode */
1166                 cp15c15 |= 0x1;
1167                 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
1168
1169                 /* Write I TLB lockdown */
1170                 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,1), ARMV4_5_STR(1, 0));
1171
1172                 /* Read I TLB CAM */
1173                 arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,5,4), ARMV4_5_LDMIA(0, 0x3fc, 0, 0));
1174
1175                 /* clear interpret mode */
1176                 cp15c15 &= ~0x1;
1177                 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
1178
1179                 /* read I TLB CAM content stored to r2-r9 */
1180                 arm9tdmi_read_core_regs(target, 0x3fc, regs_p);
1181                 if ((retval = jtag_execute_queue()) != ERROR_OK)
1182                 {
1183                         return retval;
1184                 }
1185
1186                 for (i = 0; i < 8; i++)
1187                         i_tlb[i + victim].cam = regs[i + 2];
1188         }
1189
1190         for (victim = 0; victim < 64; victim++)
1191         {
1192                 /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
1193                  * base remains unchanged, victim goes through entries 0 to 63 */
1194                 regs[1] = (Dlockdown & 0xfc000000) | (victim << 20);
1195                 arm9tdmi_write_core_regs(target, 0x2, regs);
1196
1197                 /* set interpret mode */
1198                 cp15c15 |= 0x1;
1199                 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
1200
1201                 /* Write I TLB lockdown */
1202                 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,1), ARMV4_5_STR(1, 0));
1203
1204                 /* Read I TLB RAM1 */
1205                 arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,9,4), ARMV4_5_LDR(2,0));
1206
1207                 /* Read I TLB RAM2 */
1208                 arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,1,5), ARMV4_5_LDR(3,0));
1209
1210                 /* clear interpret mode */
1211                 cp15c15 &= ~0x1;
1212                 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
1213
1214                 /* read I TLB RAM content stored to r2 and r3 */
1215                 arm9tdmi_read_core_regs(target, 0xc, regs_p);
1216                 if ((retval = jtag_execute_queue()) != ERROR_OK)
1217                 {
1218                         return retval;
1219                 }
1220
1221                 i_tlb[victim].ram1 = regs[2];
1222                 i_tlb[victim].ram2 = regs[3];
1223         }
1224
1225         /* restore I TLB lockdown */
1226         regs[1] = Ilockdown;
1227         arm9tdmi_write_core_regs(target, 0x2, regs);
1228
1229         /* Write I TLB lockdown */
1230         arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,1), ARMV4_5_STR(1, 0));
1231
1232         /* restore CP15 MMU and Cache settings */
1233         arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), cp15_ctrl_saved);
1234
1235         /* output data to file */
1236         fprintf(output, "D TLB content:\n");
1237         for (i = 0; i < 64; i++)
1238         {
1239                 fprintf(output, "%i: 0x%8.8x 0x%8.8x 0x%8.8x %s\n", i, d_tlb[i].cam, d_tlb[i].ram1, d_tlb[i].ram2, (d_tlb[i].cam & 0x20) ? "(valid)" : "(invalid)");
1240         }
1241
1242         fprintf(output, "\n\nI TLB content:\n");
1243         for (i = 0; i < 64; i++)
1244         {
1245                 fprintf(output, "%i: 0x%8.8x 0x%8.8x 0x%8.8x %s\n", i, i_tlb[i].cam, i_tlb[i].ram1, i_tlb[i].ram2, (i_tlb[i].cam & 0x20) ? "(valid)" : "(invalid)");
1246         }
1247
1248         command_print(cmd_ctx, "mmu content successfully output to %s", args[0]);
1249
1250         fclose(output);
1251
1252         if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
1253                 return ERROR_FAIL;
1254
1255         /* mark registers dirty */
1256         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;
1257         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 1).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 1).valid;
1258         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 2).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 2).valid;
1259         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 3).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 3).valid;
1260         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 4).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 4).valid;
1261         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 5).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 5).valid;
1262         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 6).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 6).valid;
1263         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 7).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 7).valid;
1264         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 8).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 8).valid;
1265         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 9).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 9).valid;
1266
1267         return ERROR_OK;
1268 }
1269 int arm920t_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1270 {
1271         int retval;
1272         target_t *target = get_current_target(cmd_ctx);
1273         armv4_5_common_t *armv4_5;
1274         arm7_9_common_t *arm7_9;
1275         arm9tdmi_common_t *arm9tdmi;
1276         arm920t_common_t *arm920t;
1277         arm_jtag_t *jtag_info;
1278
1279         if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
1280         {
1281                 command_print(cmd_ctx, "current target isn't an ARM920t target");
1282                 return ERROR_OK;
1283         }
1284
1285         jtag_info = &arm7_9->jtag_info;
1286
1287         if (target->state != TARGET_HALTED)
1288         {
1289                 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
1290                 return ERROR_OK;
1291         }
1292
1293         /* one or more argument, access a single register (write if second argument is given */
1294         if (argc >= 1)
1295         {
1296                 int address = strtoul(args[0], NULL, 0);
1297
1298                 if (argc == 1)
1299                 {
1300                         u32 value;
1301                         if ((retval = arm920t_read_cp15_physical(target, address, &value)) != ERROR_OK)
1302                         {
1303                                 command_print(cmd_ctx, "couldn't access reg %i", address);
1304                                 return ERROR_OK;
1305                         }
1306                         if ((retval = jtag_execute_queue()) != ERROR_OK)
1307                         {
1308                                 return retval;
1309                         }
1310
1311                         command_print(cmd_ctx, "%i: %8.8x", address, value);
1312                 }
1313                 else if (argc == 2)
1314                 {
1315                         u32 value = strtoul(args[1], NULL, 0);
1316                         if ((retval = arm920t_write_cp15_physical(target, address, value)) != ERROR_OK)
1317                         {
1318                                 command_print(cmd_ctx, "couldn't access reg %i", address);
1319                                 return ERROR_OK;
1320                         }
1321                         command_print(cmd_ctx, "%i: %8.8x", address, value);
1322                 }
1323         }
1324
1325         return ERROR_OK;
1326 }
1327
1328 int arm920t_handle_cp15i_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1329 {
1330         int retval;
1331         target_t *target = get_current_target(cmd_ctx);
1332         armv4_5_common_t *armv4_5;
1333         arm7_9_common_t *arm7_9;
1334         arm9tdmi_common_t *arm9tdmi;
1335         arm920t_common_t *arm920t;
1336         arm_jtag_t *jtag_info;
1337
1338         if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
1339         {
1340                 command_print(cmd_ctx, "current target isn't an ARM920t target");
1341                 return ERROR_OK;
1342         }
1343
1344         jtag_info = &arm7_9->jtag_info;
1345
1346         if (target->state != TARGET_HALTED)
1347         {
1348                 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
1349                 return ERROR_OK;
1350         }
1351
1352         /* one or more argument, access a single register (write if second argument is given */
1353         if (argc >= 1)
1354         {
1355                 u32 opcode = strtoul(args[0], NULL, 0);
1356
1357                 if (argc == 1)
1358                 {
1359                         u32 value;
1360                         if ((retval = arm920t_read_cp15_interpreted(target, opcode, 0x0, &value)) != ERROR_OK)
1361                         {
1362                                 command_print(cmd_ctx, "couldn't execute %8.8x", opcode);
1363                                 return ERROR_OK;
1364                         }
1365
1366                         command_print(cmd_ctx, "%8.8x: %8.8x", opcode, value);
1367                 }
1368                 else if (argc == 2)
1369                 {
1370                         u32 value = strtoul(args[1], NULL, 0);
1371                         if ((retval = arm920t_write_cp15_interpreted(target, opcode, value, 0)) != ERROR_OK)
1372                         {
1373                                 command_print(cmd_ctx, "couldn't execute %8.8x", opcode);
1374                                 return ERROR_OK;
1375                         }
1376                         command_print(cmd_ctx, "%8.8x: %8.8x", opcode, value);
1377                 }
1378                 else if (argc == 3)
1379                 {
1380                         u32 value = strtoul(args[1], NULL, 0);
1381                         u32 address = strtoul(args[2], NULL, 0);
1382                         if ((retval = arm920t_write_cp15_interpreted(target, opcode, value, address)) != ERROR_OK)
1383                         {
1384                                 command_print(cmd_ctx, "couldn't execute %8.8x", opcode);
1385                                 return ERROR_OK;
1386                         }
1387                         command_print(cmd_ctx, "%8.8x: %8.8x %8.8x", opcode, value, address);
1388                 }
1389         }
1390         else
1391         {
1392                 command_print(cmd_ctx, "usage: arm920t cp15i <opcode> [value] [address]");
1393         }
1394
1395         return ERROR_OK;
1396 }
1397
1398 int arm920t_handle_cache_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1399 {
1400         target_t *target = get_current_target(cmd_ctx);
1401         armv4_5_common_t *armv4_5;
1402         arm7_9_common_t *arm7_9;
1403         arm9tdmi_common_t *arm9tdmi;
1404         arm920t_common_t *arm920t;
1405
1406         if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
1407         {
1408                 command_print(cmd_ctx, "current target isn't an ARM920t target");
1409                 return ERROR_OK;
1410         }
1411
1412         return armv4_5_handle_cache_info_command(cmd_ctx, &arm920t->armv4_5_mmu.armv4_5_cache);
1413 }
1414
1415 int arm920t_handle_virt2phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
1416 {
1417         target_t *target = get_current_target(cmd_ctx);
1418         armv4_5_common_t *armv4_5;
1419         arm7_9_common_t *arm7_9;
1420         arm9tdmi_common_t *arm9tdmi;
1421         arm920t_common_t *arm920t;
1422         arm_jtag_t *jtag_info;
1423
1424         if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
1425         {
1426                 command_print(cmd_ctx, "current target isn't an ARM920t target");
1427                 return ERROR_OK;
1428         }
1429
1430         jtag_info = &arm7_9->jtag_info;
1431
1432         if (target->state != TARGET_HALTED)
1433         {
1434                 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
1435                 return ERROR_OK;
1436         }
1437
1438         return armv4_5_mmu_handle_virt2phys_command(cmd_ctx, cmd, args, argc, target, &arm920t->armv4_5_mmu);
1439 }
1440
1441 int arm920t_handle_md_phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
1442 {
1443         target_t *target = get_current_target(cmd_ctx);
1444         armv4_5_common_t *armv4_5;
1445         arm7_9_common_t *arm7_9;
1446         arm9tdmi_common_t *arm9tdmi;
1447         arm920t_common_t *arm920t;
1448         arm_jtag_t *jtag_info;
1449
1450         if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
1451         {
1452                 command_print(cmd_ctx, "current target isn't an ARM920t target");
1453                 return ERROR_OK;
1454         }
1455
1456         jtag_info = &arm7_9->jtag_info;
1457
1458         if (target->state != TARGET_HALTED)
1459         {
1460                 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
1461                 return ERROR_OK;
1462         }
1463
1464         return armv4_5_mmu_handle_md_phys_command(cmd_ctx, cmd, args, argc, target, &arm920t->armv4_5_mmu);
1465 }
1466
1467 int arm920t_handle_mw_phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
1468 {
1469         target_t *target = get_current_target(cmd_ctx);
1470         armv4_5_common_t *armv4_5;
1471         arm7_9_common_t *arm7_9;
1472         arm9tdmi_common_t *arm9tdmi;
1473         arm920t_common_t *arm920t;
1474         arm_jtag_t *jtag_info;
1475
1476         if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
1477         {
1478                 command_print(cmd_ctx, "current target isn't an ARM920t target");
1479                 return ERROR_OK;
1480         }
1481
1482         jtag_info = &arm7_9->jtag_info;
1483
1484         if (target->state != TARGET_HALTED)
1485         {
1486                 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
1487                 return ERROR_OK;
1488         }
1489
1490         return armv4_5_mmu_handle_mw_phys_command(cmd_ctx, cmd, args, argc, target, &arm920t->armv4_5_mmu);
1491 }