- prepare OpenOCD for branching, created ./trunk/
[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 #include "config.h"
21
22 #include "arm920t.h"
23 #include "jtag.h"
24 #include "log.h"
25
26 #include <stdlib.h>
27 #include <string.h>
28
29 #if 0
30 #define _DEBUG_INSTRUCTION_EXECUTION_
31 #endif
32
33 /* cli handling */
34 int arm920t_register_commands(struct command_context_s *cmd_ctx);
35
36 int arm920t_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
37 int arm920t_handle_cp15i_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
38 int arm920t_handle_virt2phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
39 int arm920t_handle_cache_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
40 int arm920t_handle_md_phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
41 int arm920t_handle_mw_phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
42
43 /* forward declarations */
44 int arm920t_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
45 int arm920t_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
46 int arm920t_quit();
47 int arm920t_arch_state(struct target_s *target, char *buf, int buf_size);
48 int arm920t_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
49 int arm920t_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
50 int arm920t_soft_reset_halt(struct target_s *target);
51
52 target_type_t arm920t_target =
53 {
54         .name = "arm920t",
55
56         .poll = arm7_9_poll,
57         .arch_state = arm920t_arch_state,
58
59         .halt = arm7_9_halt,
60         .resume = arm7_9_resume,
61         .step = arm7_9_step,
62
63         .assert_reset = arm7_9_assert_reset,
64         .deassert_reset = arm7_9_deassert_reset,
65         .soft_reset_halt = arm920t_soft_reset_halt,
66         
67         .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
68
69         .read_memory = arm920t_read_memory,
70         .write_memory = arm920t_write_memory,
71         .bulk_write_memory = arm7_9_bulk_write_memory,
72
73         .run_algorithm = armv4_5_run_algorithm,
74
75         .add_breakpoint = arm7_9_add_breakpoint,
76         .remove_breakpoint = arm7_9_remove_breakpoint,
77         .add_watchpoint = arm7_9_add_watchpoint,
78         .remove_watchpoint = arm7_9_remove_watchpoint,
79
80         .register_commands = arm920t_register_commands,
81         .target_command = arm920t_target_command,
82         .init_target = arm920t_init_target,
83         .quit = arm920t_quit
84 };
85
86 int arm920t_read_cp15_physical(target_t *target, int reg_addr, u32 *value)
87 {
88         armv4_5_common_t *armv4_5 = target->arch_info;
89         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
90         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
91         scan_field_t fields[4];
92         u8 access_type_buf = 1;
93         u8 reg_addr_buf = reg_addr & 0x3f;
94         u8 nr_w_buf = 0;
95         
96         jtag_add_end_state(TAP_RTI);
97         arm_jtag_scann(jtag_info, 0xf);
98         arm_jtag_set_instr(jtag_info, jtag_info->intest_instr);
99
100         fields[0].device = jtag_info->chain_pos;
101         fields[0].num_bits = 1;
102         fields[0].out_value = &access_type_buf;
103         fields[0].out_mask = NULL;
104         fields[0].in_value = NULL;
105         fields[0].in_check_value = NULL;
106         fields[0].in_check_mask = NULL;
107         fields[0].in_handler = NULL;
108         fields[0].in_handler_priv = NULL;
109
110         fields[1].device = jtag_info->chain_pos;
111         fields[1].num_bits = 32;
112         fields[1].out_value = NULL;
113         fields[1].out_mask = NULL;
114         fields[1].in_value = NULL;
115         fields[1].in_check_value = NULL;
116         fields[1].in_check_mask = NULL;
117         fields[1].in_handler = NULL;
118         fields[1].in_handler_priv = NULL;
119
120         fields[2].device = jtag_info->chain_pos;
121         fields[2].num_bits = 6;
122         fields[2].out_value = &reg_addr_buf;
123         fields[2].out_mask = NULL;
124         fields[2].in_value = NULL;
125         fields[2].in_check_value = NULL;
126         fields[2].in_check_mask = NULL;
127         fields[2].in_handler = NULL;
128         fields[2].in_handler_priv = NULL;
129
130         fields[3].device = jtag_info->chain_pos;
131         fields[3].num_bits = 1;
132         fields[3].out_value = &nr_w_buf;
133         fields[3].out_mask = NULL;
134         fields[3].in_value = NULL;
135         fields[3].in_check_value = NULL;
136         fields[3].in_check_mask = NULL;
137         fields[3].in_handler = NULL;
138         fields[3].in_handler_priv = NULL;
139         
140         jtag_add_dr_scan(4, fields, -1);
141
142         fields[1].in_value = (u8*)value;
143
144         jtag_add_dr_scan(4, fields, -1);
145
146         return ERROR_OK;
147 }
148
149 int arm920t_write_cp15_physical(target_t *target, int reg_addr, u32 value)
150 {
151         armv4_5_common_t *armv4_5 = target->arch_info;
152         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
153         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
154         scan_field_t fields[4];
155         u8 access_type_buf = 1;
156         u8 reg_addr_buf = reg_addr & 0x3f;
157         u8 nr_w_buf = 1;
158         
159         jtag_add_end_state(TAP_RTI);
160         arm_jtag_scann(jtag_info, 0xf);
161         arm_jtag_set_instr(jtag_info, jtag_info->intest_instr);
162
163         fields[0].device = jtag_info->chain_pos;
164         fields[0].num_bits = 1;
165         fields[0].out_value = &access_type_buf;
166         fields[0].out_mask = NULL;
167         fields[0].in_value = NULL;
168         fields[0].in_check_value = NULL;
169         fields[0].in_check_mask = NULL;
170         fields[0].in_handler = NULL;
171         fields[0].in_handler_priv = NULL;
172
173         fields[1].device = jtag_info->chain_pos;
174         fields[1].num_bits = 32;
175         fields[1].out_value = (u8*)&value;
176         fields[1].out_mask = NULL;
177         fields[1].in_value = NULL;
178         fields[1].in_check_value = NULL;
179         fields[1].in_check_mask = NULL;
180         fields[1].in_handler = NULL;
181         fields[1].in_handler_priv = NULL;
182
183         fields[2].device = jtag_info->chain_pos;
184         fields[2].num_bits = 6;
185         fields[2].out_value = &reg_addr_buf;
186         fields[2].out_mask = NULL;
187         fields[2].in_value = NULL;
188         fields[2].in_check_value = NULL;
189         fields[2].in_check_mask = NULL;
190         fields[2].in_handler = NULL;
191         fields[2].in_handler_priv = NULL;
192
193         fields[3].device = jtag_info->chain_pos;
194         fields[3].num_bits = 1;
195         fields[3].out_value = &nr_w_buf;
196         fields[3].out_mask = NULL;
197         fields[3].in_value = NULL;
198         fields[3].in_check_value = NULL;
199         fields[3].in_check_mask = NULL;
200         fields[3].in_handler = NULL;
201         fields[3].in_handler_priv = NULL;
202         
203         jtag_add_dr_scan(4, fields, -1);
204
205         return ERROR_OK;
206 }
207
208 int arm920t_read_cp15_interpreted(target_t *target, u32 opcode, u32 *value)
209 {
210         u32 cp15c15 = 0x0;
211         scan_field_t fields[4];
212         u8 access_type_buf = 0;         /* interpreted access */
213         u8 reg_addr_buf = 0x0;
214         u8 nr_w_buf = 0;
215         armv4_5_common_t *armv4_5 = target->arch_info;
216         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
217         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
218         u32* context_p[1];      
219         
220         /* read-modify-write CP15 test state register 
221         * to enable interpreted access mode */
222         arm920t_read_cp15_physical(target, 0x1e, &cp15c15);     
223         jtag_execute_queue();
224         cp15c15 |= 1;   /* set interpret mode */
225         arm920t_write_cp15_physical(target, 0x1e, cp15c15);
226
227         jtag_add_end_state(TAP_RTI);
228         arm_jtag_scann(jtag_info, 0xf);
229         arm_jtag_set_instr(jtag_info, jtag_info->intest_instr);
230
231         fields[0].device = jtag_info->chain_pos;
232         fields[0].num_bits = 1;
233         fields[0].out_value = &access_type_buf;
234         fields[0].out_mask = NULL;
235         fields[0].in_value = NULL;
236         fields[0].in_check_value = NULL;
237         fields[0].in_check_mask = NULL;
238         fields[0].in_handler = NULL;
239         fields[0].in_handler_priv = NULL;
240
241         fields[1].device = jtag_info->chain_pos;
242         fields[1].num_bits = 32;
243         fields[1].out_value = (u8*)&opcode;
244         fields[1].out_mask = NULL;
245         fields[1].in_value = NULL;
246         fields[1].in_check_value = NULL;
247         fields[1].in_check_mask = NULL;
248         fields[1].in_handler = NULL;
249         fields[1].in_handler_priv = NULL;
250
251         fields[2].device = jtag_info->chain_pos;
252         fields[2].num_bits = 6;
253         fields[2].out_value = &reg_addr_buf;
254         fields[2].out_mask = NULL;
255         fields[2].in_value = NULL;
256         fields[2].in_check_value = NULL;
257         fields[2].in_check_mask = NULL;
258         fields[2].in_handler = NULL;
259         fields[2].in_handler_priv = NULL;
260
261         fields[3].device = jtag_info->chain_pos;
262         fields[3].num_bits = 1;
263         fields[3].out_value = &nr_w_buf;
264         fields[3].out_mask = NULL;
265         fields[3].in_value = NULL;
266         fields[3].in_check_value = NULL;
267         fields[3].in_check_mask = NULL;
268         fields[3].in_handler = NULL;
269         fields[3].in_handler_priv = NULL;
270
271         jtag_add_dr_scan(4, fields, -1);
272
273         arm9tdmi_clock_out(jtag_info, ARMV4_5_LDR(0, 15), 0, NULL, 0);
274         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
275         arm7_9_execute_sys_speed(target);
276         jtag_execute_queue();
277
278         /* read-modify-write CP15 test state register 
279         * to disable interpreted access mode */
280         arm920t_read_cp15_physical(target, 0x1e, &cp15c15);     
281         jtag_execute_queue();
282         cp15c15 &= ~1U; /* clear interpret mode */
283         arm920t_write_cp15_physical(target, 0x1e, cp15c15);
284
285         context_p[0] = value;
286         arm9tdmi_read_core_regs(target, 0x1, context_p);
287         jtag_execute_queue();
288         
289         DEBUG("opcode: %8.8x, value: %8.8x", opcode, *value);
290
291         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).dirty = 1;
292         ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 15).dirty = 1;
293
294         return ERROR_OK;
295 }
296
297 int arm920t_write_cp15_interpreted(target_t *target, u32 opcode, u32 value, u32 address)
298 {
299         u32 cp15c15 = 0x0;
300         scan_field_t fields[4];
301         u8 access_type_buf = 0;         /* interpreted access */
302         u8 reg_addr_buf = 0x0;
303         u8 nr_w_buf = 0;
304         armv4_5_common_t *armv4_5 = target->arch_info;
305         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
306         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
307         u32 regs[2];
308
309         regs[0] = value;
310         regs[1] = address;
311         
312         arm9tdmi_write_core_regs(target, 0x3, regs);
313
314         /* read-modify-write CP15 test state register 
315         * to enable interpreted access mode */
316         arm920t_read_cp15_physical(target, 0x1e, &cp15c15);
317         jtag_execute_queue();
318         cp15c15 |= 1;   /* set interpret mode */
319         arm920t_write_cp15_physical(target, 0x1e, cp15c15);
320
321         jtag_add_end_state(TAP_RTI);
322         arm_jtag_scann(jtag_info, 0xf);
323         arm_jtag_set_instr(jtag_info, jtag_info->intest_instr);
324
325         fields[0].device = jtag_info->chain_pos;
326         fields[0].num_bits = 1;
327         fields[0].out_value = &access_type_buf;
328         fields[0].out_mask = NULL;
329         fields[0].in_value = NULL;
330         fields[0].in_check_value = NULL;
331         fields[0].in_check_mask = NULL;
332         fields[0].in_handler = NULL;
333         fields[0].in_handler_priv = NULL;
334
335         fields[1].device = jtag_info->chain_pos;
336         fields[1].num_bits = 32;
337         fields[1].out_value = (u8*)&opcode;
338         fields[1].out_mask = NULL;
339         fields[1].in_value = NULL;
340         fields[1].in_check_value = NULL;
341         fields[1].in_check_mask = NULL;
342         fields[1].in_handler = NULL;
343         fields[1].in_handler_priv = NULL;
344
345         fields[2].device = jtag_info->chain_pos;
346         fields[2].num_bits = 6;
347         fields[2].out_value = &reg_addr_buf;
348         fields[2].out_mask = NULL;
349         fields[2].in_value = NULL;
350         fields[2].in_check_value = NULL;
351         fields[2].in_check_mask = NULL;
352         fields[2].in_handler = NULL;
353         fields[2].in_handler_priv = NULL;
354
355         fields[3].device = jtag_info->chain_pos;
356         fields[3].num_bits = 1;
357         fields[3].out_value = &nr_w_buf;
358         fields[3].out_mask = NULL;
359         fields[3].in_value = NULL;
360         fields[3].in_check_value = NULL;
361         fields[3].in_check_mask = NULL;
362         fields[3].in_handler = NULL;
363         fields[3].in_handler_priv = NULL;
364
365         jtag_add_dr_scan(4, fields, -1);
366
367         arm9tdmi_clock_out(jtag_info, ARMV4_5_STR(0, 1), 0, NULL, 0);
368         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
369         arm7_9_execute_sys_speed(target);
370         jtag_execute_queue();
371
372         /* read-modify-write CP15 test state register 
373         * to disable interpreted access mode */
374         arm920t_read_cp15_physical(target, 0x1e, &cp15c15);     
375         jtag_execute_queue();
376         cp15c15 &= ~1U; /* set interpret mode */
377         arm920t_write_cp15_physical(target, 0x1e, cp15c15);
378
379         DEBUG("opcode: %8.8x, value: %8.8x, address: %8.8x", opcode, value, address);
380
381         return ERROR_OK;
382 }
383
384 u32 arm920t_get_ttb(target_t *target)
385 {
386         int retval;
387         u32 ttb = 0x0;
388
389         if ((retval = arm920t_read_cp15_interpreted(target, 0xeebf0f51, &ttb)) != ERROR_OK)
390                 return retval;
391
392         return ttb;
393 }
394
395 void arm920t_disable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
396 {
397         u32 cp15_control;
398
399         /* read cp15 control register */
400         arm920t_read_cp15_physical(target, 0x2, &cp15_control);
401         jtag_execute_queue();
402                 
403         if (mmu)
404                 cp15_control &= ~0x1U;
405         
406         if (d_u_cache)
407                 cp15_control &= ~0x4U;
408         
409         if (i_cache)
410                 cp15_control &= ~0x1000U;
411
412         arm920t_write_cp15_physical(target, 0x2, cp15_control);
413 }
414
415 void arm920t_enable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
416 {
417         u32 cp15_control;
418
419         /* read cp15 control register */
420         arm920t_read_cp15_physical(target, 0x2, &cp15_control);
421         jtag_execute_queue();
422                 
423         if (mmu)
424                 cp15_control |= 0x1U;
425         
426         if (d_u_cache)
427                 cp15_control |= 0x4U;
428         
429         if (i_cache)
430                 cp15_control |= 0x1000U;
431         
432         arm920t_write_cp15_physical(target, 0x2, cp15_control);
433 }
434
435 void arm920t_post_debug_entry(target_t *target)
436 {
437         u32 cp15c15;
438         armv4_5_common_t *armv4_5 = target->arch_info;
439         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
440         arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
441         arm920t_common_t *arm920t = arm9tdmi->arch_info;
442         
443         /* examine cp15 control reg */
444         arm920t_read_cp15_physical(target, 0x2, &arm920t->cp15_control_reg);
445         jtag_execute_queue();
446         DEBUG("cp15_control_reg: %8.8x", arm920t->cp15_control_reg);
447
448         if (arm920t->armv4_5_mmu.armv4_5_cache.ctype == -1)
449         {
450                 u32 cache_type_reg;
451                 /* identify caches */
452                 arm920t_read_cp15_physical(target, 0x1, &cache_type_reg);
453                 jtag_execute_queue();
454                 armv4_5_identify_cache(cache_type_reg, &arm920t->armv4_5_mmu.armv4_5_cache);
455         }
456
457         arm920t->armv4_5_mmu.mmu_enabled = (arm920t->cp15_control_reg & 0x1U) ? 1 : 0;
458         arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = (arm920t->cp15_control_reg & 0x4U) ? 1 : 0;
459         arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = (arm920t->cp15_control_reg & 0x1000U) ? 1 : 0;
460
461         /* save i/d fault status and address register */
462         arm920t_read_cp15_interpreted(target, 0xee150f10, &arm920t->d_fsr);
463         arm920t_read_cp15_interpreted(target, 0xee150f30, &arm920t->i_fsr);
464         arm920t_read_cp15_interpreted(target, 0xee160f10, &arm920t->d_far);
465         arm920t_read_cp15_interpreted(target, 0xee160f30, &arm920t->i_far);
466
467         /* read-modify-write CP15 test state register 
468         * to disable I/D-cache linefills */
469         arm920t_read_cp15_physical(target, 0x1e, &cp15c15);     
470         jtag_execute_queue();
471         cp15c15 |= 0x600;
472         arm920t_write_cp15_physical(target, 0x1e, cp15c15);
473
474 }
475
476 void arm920t_pre_restore_context(target_t *target)
477 {
478         u32 cp15c15;
479         armv4_5_common_t *armv4_5 = target->arch_info;
480         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
481         arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
482         arm920t_common_t *arm920t = arm9tdmi->arch_info;
483         
484         /* restore i/d fault status and address register */
485         arm920t_write_cp15_interpreted(target, 0xee050f10, arm920t->d_fsr, 0x0);
486         arm920t_write_cp15_interpreted(target, 0xee050f30, arm920t->i_fsr, 0x0);
487         arm920t_write_cp15_interpreted(target, 0xee060f10, arm920t->d_far, 0x0);
488         arm920t_write_cp15_interpreted(target, 0xee060f30, arm920t->i_far, 0x0);
489         
490         /* read-modify-write CP15 test state register 
491         * to reenable I/D-cache linefills */
492         arm920t_read_cp15_physical(target, 0x1e, &cp15c15);
493         jtag_execute_queue();
494         cp15c15 &= ~0x600U;
495         arm920t_write_cp15_physical(target, 0x1e, cp15c15);
496
497 }
498
499 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)
500 {
501         armv4_5_common_t *armv4_5 = target->arch_info;
502         arm7_9_common_t *arm7_9;
503         arm9tdmi_common_t *arm9tdmi;
504         arm920t_common_t *arm920t;
505         
506         if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
507         {
508                 return -1;
509         }
510         
511         arm7_9 = armv4_5->arch_info;
512         if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
513         {
514                 return -1;
515         }
516         
517         arm9tdmi = arm7_9->arch_info;
518         if (arm9tdmi->common_magic != ARM9TDMI_COMMON_MAGIC)
519         {
520                 return -1;
521         }
522         
523         arm920t = arm9tdmi->arch_info;
524         if (arm920t->common_magic != ARM920T_COMMON_MAGIC)
525         {
526                 return -1;
527         }
528         
529         *armv4_5_p = armv4_5;
530         *arm7_9_p = arm7_9;
531         *arm9tdmi_p = arm9tdmi;
532         *arm920t_p = arm920t;
533         
534         return ERROR_OK;
535 }
536
537 int arm920t_arch_state(struct target_s *target, char *buf, int buf_size)
538 {
539         armv4_5_common_t *armv4_5 = target->arch_info;
540         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
541         arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
542         arm920t_common_t *arm920t = arm9tdmi->arch_info;
543         
544         char *state[] = 
545         {
546                 "disabled", "enabled"
547         };
548         
549         if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
550         {
551                 ERROR("BUG: called for a non-ARMv4/5 target");
552                 exit(-1);
553         }
554         
555         snprintf(buf, buf_size,
556                         "target halted in %s state due to %s, current mode: %s\n"
557                         "cpsr: 0x%8.8x pc: 0x%8.8x\n"
558                         "MMU: %s, D-Cache: %s, I-Cache: %s",
559                          armv4_5_state_strings[armv4_5->core_state],
560                          target_debug_reason_strings[target->debug_reason],
561                          armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)],
562                          buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
563                          buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
564                          state[arm920t->armv4_5_mmu.mmu_enabled],
565                          state[arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled], 
566                          state[arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled]);
567         
568         return ERROR_OK;
569 }
570
571 int arm920t_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
572 {
573         int retval;
574         
575         retval = arm7_9_read_memory(target, address, size, count, buffer);
576         
577         return retval;
578 }
579
580 int arm920t_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
581 {
582         int retval;
583         armv4_5_common_t *armv4_5 = target->arch_info;
584         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
585         arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
586         arm920t_common_t *arm920t = arm9tdmi->arch_info;
587         
588         if ((retval = arm7_9_write_memory(target, address, size, count, buffer)) != ERROR_OK)
589                 return retval;
590
591         if (((size == 4) || (size == 2)) && (count == 1))
592         {
593                 if (arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled)
594                 {
595                         DEBUG("D-Cache enabled, writing through to main memory");
596                         u32 pa, cb, ap;
597                         int type, domain;
598
599                         pa = armv4_5_mmu_translate_va(target, &arm920t->armv4_5_mmu, address, &type, &cb, &domain, &ap);
600                         if (type == -1)
601                                 return ERROR_OK;
602                         /* cacheable & bufferable means write-back region */
603                         if (cb == 3)
604                                 armv4_5_mmu_write_physical(target, &arm920t->armv4_5_mmu, pa, size, count, buffer);
605                 }
606                 
607                 if (arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled)
608                 {
609                         DEBUG("I-Cache enabled, invalidating affected I-Cache line");
610                         arm920t_write_cp15_interpreted(target, 0xee070f35, 0x0, address);
611                 }
612         }
613
614         return retval;
615 }
616
617 int arm920t_soft_reset_halt(struct target_s *target)
618 {
619         armv4_5_common_t *armv4_5 = target->arch_info;
620         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
621         arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
622         arm920t_common_t *arm920t = arm9tdmi->arch_info;
623         reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
624         
625         if (target->state == TARGET_RUNNING)
626         {
627                 target->type->halt(target);
628         }
629         
630         while (buf_get_u32(dbg_stat->value, EICE_DBG_CONTROL_DBGACK, 1) == 0)
631         {
632                 embeddedice_read_reg(dbg_stat);
633                 jtag_execute_queue();
634         }
635         
636         target->state = TARGET_HALTED;
637         
638         /* SVC, ARM state, IRQ and FIQ disabled */
639         buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8, 0xd3);
640         armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
641         armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
642         
643         /* start fetching from 0x0 */
644         buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
645         armv4_5->core_cache->reg_list[15].dirty = 1;
646         armv4_5->core_cache->reg_list[15].valid = 1;
647         
648         armv4_5->core_mode = ARMV4_5_MODE_SVC;
649         armv4_5->core_state = ARMV4_5_STATE_ARM;
650         
651         arm920t_disable_mmu_caches(target, 1, 1, 1);
652         arm920t->armv4_5_mmu.mmu_enabled = 0;
653         arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;
654         arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;
655
656         target_call_event_callbacks(target, TARGET_EVENT_HALTED);
657         
658         return ERROR_OK;
659 }
660
661 int arm920t_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
662 {
663         arm9tdmi_init_target(cmd_ctx, target);
664                 
665         return ERROR_OK;
666         
667 }
668
669 int arm920t_quit()
670 {
671         
672         return ERROR_OK;
673 }
674
675 int arm920t_init_arch_info(target_t *target, arm920t_common_t *arm920t, int chain_pos, char *variant)
676 {
677         arm9tdmi_common_t *arm9tdmi = &arm920t->arm9tdmi_common;
678         arm7_9_common_t *arm7_9 = &arm9tdmi->arm7_9_common;
679         
680         arm9tdmi_init_arch_info(target, arm9tdmi, chain_pos, variant);
681
682         arm9tdmi->arch_info = arm920t;
683         arm920t->common_magic = ARM920T_COMMON_MAGIC;
684         
685         arm7_9->post_debug_entry = arm920t_post_debug_entry;
686         arm7_9->pre_restore_context = arm920t_pre_restore_context;
687         
688         arm920t->armv4_5_mmu.armv4_5_cache.ctype = -1;
689         arm920t->armv4_5_mmu.get_ttb = arm920t_get_ttb;
690         arm920t->armv4_5_mmu.read_memory = arm7_9_read_memory;
691         arm920t->armv4_5_mmu.write_memory = arm7_9_write_memory;
692         arm920t->armv4_5_mmu.disable_mmu_caches = arm920t_disable_mmu_caches;
693         arm920t->armv4_5_mmu.enable_mmu_caches = arm920t_enable_mmu_caches;
694         arm920t->armv4_5_mmu.has_tiny_pages = 1;
695         arm920t->armv4_5_mmu.mmu_enabled = 0;
696         
697         arm9tdmi->has_single_step = 1;
698         
699         return ERROR_OK;
700 }
701
702 int arm920t_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
703 {
704         int chain_pos;
705         char *variant = NULL;
706         arm920t_common_t *arm920t = malloc(sizeof(arm920t_common_t));
707         
708         if (argc < 4)
709         {
710                 ERROR("'target arm920t' requires at least one additional argument");
711                 exit(-1);
712         }
713         
714         chain_pos = strtoul(args[3], NULL, 0);
715         
716         if (argc >= 5)
717                 variant = strdup(args[4]);
718         
719         DEBUG("chain_pos: %i, variant: %s", chain_pos, variant);
720         
721         arm920t_init_arch_info(target, arm920t, chain_pos, variant);
722
723         return ERROR_OK;
724 }
725
726 int arm920t_register_commands(struct command_context_s *cmd_ctx)
727 {
728         int retval;
729         command_t *arm920t_cmd;
730         
731                 
732         retval = arm9tdmi_register_commands(cmd_ctx);
733         
734         arm920t_cmd = register_command(cmd_ctx, NULL, "arm920t", NULL, COMMAND_ANY, "arm920t specific commands");
735
736         register_command(cmd_ctx, arm920t_cmd, "cp15", arm920t_handle_cp15_command, COMMAND_EXEC, "display/modify cp15 register <num> [value]");
737         register_command(cmd_ctx, arm920t_cmd, "cp15i", arm920t_handle_cp15i_command, COMMAND_EXEC, "display/modify cp15 (interpreted access) <opcode> [value] [address]");
738         register_command(cmd_ctx, arm920t_cmd, "cache_info", arm920t_handle_cache_info_command, COMMAND_EXEC, "display information about target caches");
739         register_command(cmd_ctx, arm920t_cmd, "virt2phys", arm920t_handle_virt2phys_command, COMMAND_EXEC, "translate va to pa <va>");
740
741         register_command(cmd_ctx, arm920t_cmd, "mdw_phys", arm920t_handle_md_phys_command, COMMAND_EXEC, "display memory words <physical addr> [count]");
742         register_command(cmd_ctx, arm920t_cmd, "mdh_phys", arm920t_handle_md_phys_command, COMMAND_EXEC, "display memory half-words <physical addr> [count]");
743         register_command(cmd_ctx, arm920t_cmd, "mdb_phys", arm920t_handle_md_phys_command, COMMAND_EXEC, "display memory bytes <physical addr> [count]");
744
745         register_command(cmd_ctx, arm920t_cmd, "mww_phys", arm920t_handle_mw_phys_command, COMMAND_EXEC, "write memory word <physical addr> <value>");
746         register_command(cmd_ctx, arm920t_cmd, "mwh_phys", arm920t_handle_mw_phys_command, COMMAND_EXEC, "write memory half-word <physical addr> <value>");
747         register_command(cmd_ctx, arm920t_cmd, "mwb_phys", arm920t_handle_mw_phys_command, COMMAND_EXEC, "write memory byte <physical addr> <value>");
748
749         return ERROR_OK;
750 }
751
752 int arm920t_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
753 {
754         int retval;
755         target_t *target = get_current_target(cmd_ctx);
756         armv4_5_common_t *armv4_5;
757         arm7_9_common_t *arm7_9;
758         arm9tdmi_common_t *arm9tdmi;
759         arm920t_common_t *arm920t;
760         arm_jtag_t *jtag_info;
761
762         if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
763         {
764                 command_print(cmd_ctx, "current target isn't an ARM920t target");
765                 return ERROR_OK;
766         }
767         
768         jtag_info = &arm7_9->jtag_info;
769         
770         if (target->state != TARGET_HALTED)
771         {
772                 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
773                 return ERROR_OK;
774         }
775
776         /* one or more argument, access a single register (write if second argument is given */
777         if (argc >= 1)
778         {
779                 int address = strtoul(args[0], NULL, 0);
780
781                 if (argc == 1)
782                 {
783                         u32 value;
784                         if ((retval = arm920t_read_cp15_physical(target, address, &value)) != ERROR_OK)
785                         {
786                                 command_print(cmd_ctx, "couldn't access reg %i", address);
787                                 return ERROR_OK;
788                         }
789                         jtag_execute_queue();
790                         
791                         command_print(cmd_ctx, "%i: %8.8x", address, value);
792                 }
793                 else if (argc == 2)
794                 {
795                         u32 value = strtoul(args[1], NULL, 0);
796                         if ((retval = arm920t_write_cp15_physical(target, address, value)) != ERROR_OK)
797                         {
798                                 command_print(cmd_ctx, "couldn't access reg %i", address);
799                                 return ERROR_OK;
800                         }
801                         command_print(cmd_ctx, "%i: %8.8x", address, value);
802                 }
803         }
804
805         return ERROR_OK;
806 }
807
808 int arm920t_handle_cp15i_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
809 {
810         int retval;
811         target_t *target = get_current_target(cmd_ctx);
812         armv4_5_common_t *armv4_5;
813         arm7_9_common_t *arm7_9;
814         arm9tdmi_common_t *arm9tdmi;
815         arm920t_common_t *arm920t;
816         arm_jtag_t *jtag_info;
817
818         if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
819         {
820                 command_print(cmd_ctx, "current target isn't an ARM920t target");
821                 return ERROR_OK;
822         }
823         
824         jtag_info = &arm7_9->jtag_info;
825         
826         if (target->state != TARGET_HALTED)
827         {
828                 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
829                 return ERROR_OK;
830         }
831
832         /* one or more argument, access a single register (write if second argument is given */
833         if (argc >= 1)
834         {
835                 u32 opcode = strtoul(args[0], NULL, 0);
836
837                 if (argc == 1)
838                 {
839                         u32 value;
840                         if ((retval = arm920t_read_cp15_interpreted(target, opcode, &value)) != ERROR_OK)
841                         {
842                                 command_print(cmd_ctx, "couldn't execute %8.8x", opcode);
843                                 return ERROR_OK;
844                         }
845                         
846                         command_print(cmd_ctx, "%8.8x: %8.8x", opcode, value);
847                 }
848                 else if (argc == 2)
849                 {
850                         u32 value = strtoul(args[1], NULL, 0);
851                         if ((retval = arm920t_write_cp15_interpreted(target, opcode, value, 0)) != ERROR_OK)
852                         {
853                                 command_print(cmd_ctx, "couldn't execute %8.8x", opcode);
854                                 return ERROR_OK;
855                         }
856                         command_print(cmd_ctx, "%8.8x: %8.8x", opcode, value);
857                 }
858                 else if (argc == 3)
859                 {
860                         u32 value = strtoul(args[1], NULL, 0);
861                         u32 address = strtoul(args[2], NULL, 0);
862                         if ((retval = arm920t_write_cp15_interpreted(target, opcode, value, address)) != ERROR_OK)
863                         {
864                                 command_print(cmd_ctx, "couldn't execute %8.8x", opcode);
865                                 return ERROR_OK;
866                         }
867                         command_print(cmd_ctx, "%8.8x: %8.8x %8.8x", opcode, value, address);
868                 }
869         }
870
871         return ERROR_OK;
872 }
873
874 int arm920t_handle_cache_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
875 {
876         target_t *target = get_current_target(cmd_ctx);
877         armv4_5_common_t *armv4_5;
878         arm7_9_common_t *arm7_9;
879         arm9tdmi_common_t *arm9tdmi;
880         arm920t_common_t *arm920t;
881         
882         if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
883         {
884                 command_print(cmd_ctx, "current target isn't an ARM920t target");
885                 return ERROR_OK;
886         }
887         
888         return armv4_5_handle_cache_info_command(cmd_ctx, &arm920t->armv4_5_mmu.armv4_5_cache);
889 }
890
891 int arm920t_handle_virt2phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
892 {       
893         target_t *target = get_current_target(cmd_ctx);
894         armv4_5_common_t *armv4_5;
895         arm7_9_common_t *arm7_9;
896         arm9tdmi_common_t *arm9tdmi;
897         arm920t_common_t *arm920t;
898         arm_jtag_t *jtag_info;
899
900         if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
901         {
902                 command_print(cmd_ctx, "current target isn't an ARM920t target");
903                 return ERROR_OK;
904         }
905         
906         jtag_info = &arm7_9->jtag_info;
907         
908         if (target->state != TARGET_HALTED)
909         {
910                 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
911                 return ERROR_OK;
912         }
913                 
914         return armv4_5_mmu_handle_virt2phys_command(cmd_ctx, cmd, args, argc, target, &arm920t->armv4_5_mmu);
915 }
916
917 int arm920t_handle_md_phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
918 {       
919         target_t *target = get_current_target(cmd_ctx);
920         armv4_5_common_t *armv4_5;
921         arm7_9_common_t *arm7_9;
922         arm9tdmi_common_t *arm9tdmi;
923         arm920t_common_t *arm920t;
924         arm_jtag_t *jtag_info;
925
926         if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
927         {
928                 command_print(cmd_ctx, "current target isn't an ARM920t target");
929                 return ERROR_OK;
930         }
931         
932         jtag_info = &arm7_9->jtag_info;
933         
934         if (target->state != TARGET_HALTED)
935         {
936                 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
937                 return ERROR_OK;
938         }
939         
940         return armv4_5_mmu_handle_md_phys_command(cmd_ctx, cmd, args, argc, target, &arm920t->armv4_5_mmu);
941 }
942
943 int arm920t_handle_mw_phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
944 {       
945         target_t *target = get_current_target(cmd_ctx);
946         armv4_5_common_t *armv4_5;
947         arm7_9_common_t *arm7_9;
948         arm9tdmi_common_t *arm9tdmi;
949         arm920t_common_t *arm920t;
950         arm_jtag_t *jtag_info;
951
952         if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
953         {
954                 command_print(cmd_ctx, "current target isn't an ARM920t target");
955                 return ERROR_OK;
956         }
957         
958         jtag_info = &arm7_9->jtag_info;
959         
960         if (target->state != TARGET_HALTED)
961         {
962                 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
963                 return ERROR_OK;
964         }
965         
966         return armv4_5_mmu_handle_mw_phys_command(cmd_ctx, cmd, args, argc, target, &arm920t->armv4_5_mmu);
967 }