cef7061ed13ac3e05d4c958ee96f20afaf7d21b7
[fw/openocd] / src / target / arm926ejs.c
1 /***************************************************************************
2  *   Copyright (C) 2007 by Dominic Rath                                    *
3  *   Dominic.Rath@gmx.de                                                   *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "arm926ejs.h"
25 #include "time_support.h"
26
27
28 #if 0
29 #define _DEBUG_INSTRUCTION_EXECUTION_
30 #endif
31
32 /* cli handling */
33 int arm926ejs_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
34 int arm926ejs_handle_cp15i_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
35 int arm926ejs_handle_virt2phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
36 int arm926ejs_handle_cache_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
37 int arm926ejs_handle_md_phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
38 int arm926ejs_handle_mw_phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
39
40 int arm926ejs_handle_read_cache_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
41 int arm926ejs_handle_read_mmu_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
42
43 /* forward declarations */
44 int arm926ejs_target_create(struct target_s *target, Jim_Interp *interp);
45 int arm926ejs_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
46 int arm926ejs_quit(void);
47 int arm926ejs_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
48
49 static int arm926ejs_virt2phys(struct target_s *target, u32 virtual, u32 *physical);
50 static int arm926ejs_mmu(struct target_s *target, int *enabled);
51
52 target_type_t arm926ejs_target =
53 {
54         .name = "arm926ejs",
55
56         .poll = arm7_9_poll,
57         .arch_state = arm926ejs_arch_state,
58
59         .target_request_data = arm7_9_target_request_data,
60
61         .halt = arm7_9_halt,
62         .resume = arm7_9_resume,
63         .step = arm7_9_step,
64
65         .assert_reset = arm7_9_assert_reset,
66         .deassert_reset = arm7_9_deassert_reset,
67         .soft_reset_halt = arm926ejs_soft_reset_halt,
68
69         .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
70
71         .read_memory = arm7_9_read_memory,
72         .write_memory = arm926ejs_write_memory,
73         .bulk_write_memory = arm7_9_bulk_write_memory,
74         .checksum_memory = arm7_9_checksum_memory,
75         .blank_check_memory = arm7_9_blank_check_memory,
76
77         .run_algorithm = armv4_5_run_algorithm,
78
79         .add_breakpoint = arm7_9_add_breakpoint,
80         .remove_breakpoint = arm7_9_remove_breakpoint,
81         .add_watchpoint = arm7_9_add_watchpoint,
82         .remove_watchpoint = arm7_9_remove_watchpoint,
83
84         .register_commands = arm926ejs_register_commands,
85         .target_create = arm926ejs_target_create,
86         .init_target = arm926ejs_init_target,
87         .examine = arm9tdmi_examine,
88         .quit = arm926ejs_quit,
89         .virt2phys = arm926ejs_virt2phys,
90         .mmu = arm926ejs_mmu
91 };
92
93 int arm926ejs_catch_broken_irscan(u8 *captured, void *priv, scan_field_t *field)
94 {
95         /* FIX!!!! this code should be reenabled. For now it does not check
96          * the queue...*/
97         return 0;
98 #if 0
99         /* The ARM926EJ-S' instruction register is 4 bits wide */
100         u8 t = *captured & 0xf;
101         u8 t2 = *field->in_check_value & 0xf;
102         if (t == t2)
103         {
104                 return ERROR_OK;
105         }
106         else if ((t == 0x0f) || (t == 0x00))
107         {
108                 LOG_DEBUG("caught ARM926EJ-S invalid Capture-IR result after CP15 access");
109                 return ERROR_OK;
110         }
111         return ERROR_JTAG_QUEUE_FAILED;;
112 #endif
113 }
114
115 #define ARM926EJS_CP15_ADDR(opcode_1, opcode_2, CRn, CRm) ((opcode_1 << 11) | (opcode_2 << 8) | (CRn << 4) | (CRm << 0))
116
117 int arm926ejs_cp15_read(target_t *target, u32 op1, u32 op2, u32 CRn, u32 CRm, u32 *value)
118 {
119         int retval = ERROR_OK;
120         armv4_5_common_t *armv4_5 = target->arch_info;
121         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
122         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
123         u32 address = ARM926EJS_CP15_ADDR(op1, op2, CRn, CRm);
124         scan_field_t fields[4];
125         u8 address_buf[2];
126         u8 nr_w_buf = 0;
127         u8 access = 1;
128
129         buf_set_u32(address_buf, 0, 14, address);
130
131         jtag_add_end_state(TAP_IDLE);
132         if ((retval = arm_jtag_scann(jtag_info, 0xf)) != ERROR_OK)
133         {
134                 return retval;
135         }
136         arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
137
138         fields[0].tap = jtag_info->tap;
139         fields[0].num_bits = 32;
140         fields[0].out_value = NULL;
141         fields[0].in_value = (u8 *)value;
142
143
144         fields[1].tap = jtag_info->tap;
145         fields[1].num_bits = 1;
146         fields[1].out_value = &access;
147         fields[1].in_value = &access;
148
149         fields[2].tap = jtag_info->tap;
150         fields[2].num_bits = 14;
151         fields[2].out_value = address_buf;
152         fields[2].in_value = NULL;
153
154         fields[3].tap = jtag_info->tap;
155         fields[3].num_bits = 1;
156         fields[3].out_value = &nr_w_buf;
157         fields[3].in_value = NULL;
158
159         jtag_add_dr_scan(4, fields, TAP_INVALID);
160
161         /*TODO: add timeout*/
162         do
163         {
164                 /* rescan with NOP, to wait for the access to complete */
165                 access = 0;
166                 nr_w_buf = 0;
167                 jtag_add_dr_scan(4, fields, TAP_INVALID);
168
169                 jtag_add_callback(arm_le_to_h_u32, (u8 *)value);
170
171                 if ((retval = jtag_execute_queue()) != ERROR_OK)
172                 {
173                         return retval;
174                 }
175         } while (buf_get_u32(&access, 0, 1) != 1);
176
177 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
178         LOG_DEBUG("addr: 0x%x value: %8.8x", address, *value);
179 #endif
180
181         arm_jtag_set_instr(jtag_info, 0xc, &arm926ejs_catch_broken_irscan);
182
183         return ERROR_OK;
184 }
185
186 int arm926ejs_cp15_write(target_t *target, u32 op1, u32 op2, u32 CRn, u32 CRm, u32 value)
187 {
188         int retval = ERROR_OK;
189         armv4_5_common_t *armv4_5 = target->arch_info;
190         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
191         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
192         u32 address = ARM926EJS_CP15_ADDR(op1, op2, CRn, CRm);
193         scan_field_t fields[4];
194         u8 value_buf[4];
195         u8 address_buf[2];
196         u8 nr_w_buf = 1;
197         u8 access = 1;
198
199         buf_set_u32(address_buf, 0, 14, address);
200         buf_set_u32(value_buf, 0, 32, value);
201
202         jtag_add_end_state(TAP_IDLE);
203         if ((retval = arm_jtag_scann(jtag_info, 0xf)) != ERROR_OK)
204         {
205                 return retval;
206         }
207         arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
208
209         fields[0].tap = jtag_info->tap;
210         fields[0].num_bits = 32;
211         fields[0].out_value = value_buf;
212         fields[0].in_value = NULL;
213
214         fields[1].tap = jtag_info->tap;
215         fields[1].num_bits = 1;
216         fields[1].out_value = &access;
217         fields[1].in_value = &access;
218
219         fields[2].tap = jtag_info->tap;
220         fields[2].num_bits = 14;
221         fields[2].out_value = address_buf;
222         fields[2].in_value = NULL;
223
224         fields[3].tap = jtag_info->tap;
225         fields[3].num_bits = 1;
226         fields[3].out_value = &nr_w_buf;
227         fields[3].in_value = NULL;
228
229         jtag_add_dr_scan(4, fields, TAP_INVALID);
230         /*TODO: add timeout*/
231         do
232         {
233                 /* rescan with NOP, to wait for the access to complete */
234                 access = 0;
235                 nr_w_buf = 0;
236                 jtag_add_dr_scan(4, fields, TAP_INVALID);
237                 if ((retval = jtag_execute_queue()) != ERROR_OK)
238                 {
239                         return retval;
240                 }
241         } while (buf_get_u32(&access, 0, 1) != 1);
242
243 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
244         LOG_DEBUG("addr: 0x%x value: %8.8x", address, value);
245 #endif
246
247         arm_jtag_set_instr(jtag_info, 0xf, &arm926ejs_catch_broken_irscan);
248
249         return ERROR_OK;
250 }
251
252 int arm926ejs_examine_debug_reason(target_t *target)
253 {
254         armv4_5_common_t *armv4_5 = target->arch_info;
255         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
256         reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
257         int debug_reason;
258         int retval;
259
260         embeddedice_read_reg(dbg_stat);
261         if ((retval = jtag_execute_queue()) != ERROR_OK)
262                 return retval;
263
264         debug_reason = buf_get_u32(dbg_stat->value, 6, 4);
265
266         switch (debug_reason)
267         {
268                 case 1:
269                         LOG_DEBUG("breakpoint from EICE unit 0");
270                         target->debug_reason = DBG_REASON_BREAKPOINT;
271                         break;
272                 case 2:
273                         LOG_DEBUG("breakpoint from EICE unit 1");
274                         target->debug_reason = DBG_REASON_BREAKPOINT;
275                         break;
276                 case 3:
277                         LOG_DEBUG("soft breakpoint (BKPT instruction)");
278                         target->debug_reason = DBG_REASON_BREAKPOINT;
279                         break;
280                 case 4:
281                         LOG_DEBUG("vector catch breakpoint");
282                         target->debug_reason = DBG_REASON_BREAKPOINT;
283                         break;
284                 case 5:
285                         LOG_DEBUG("external breakpoint");
286                         target->debug_reason = DBG_REASON_BREAKPOINT;
287                         break;
288                 case 6:
289                         LOG_DEBUG("watchpoint from EICE unit 0");
290                         target->debug_reason = DBG_REASON_WATCHPOINT;
291                         break;
292                 case 7:
293                         LOG_DEBUG("watchpoint from EICE unit 1");
294                         target->debug_reason = DBG_REASON_WATCHPOINT;
295                         break;
296                 case 8:
297                         LOG_DEBUG("external watchpoint");
298                         target->debug_reason = DBG_REASON_WATCHPOINT;
299                         break;
300                 case 9:
301                         LOG_DEBUG("internal debug request");
302                         target->debug_reason = DBG_REASON_DBGRQ;
303                         break;
304                 case 10:
305                         LOG_DEBUG("external debug request");
306                         target->debug_reason = DBG_REASON_DBGRQ;
307                         break;
308                 case 11:
309                         LOG_ERROR("BUG: debug re-entry from system speed access shouldn't be handled here");
310                         break;
311                 case 12:
312                         /* FIX!!!! here be dragons!!! We need to fail here so
313                          * the target will interpreted as halted but we won't
314                          * try to talk to it right now... a resume + halt seems
315                          * to sync things up again. Please send an email to
316                          * openocd development mailing list if you have hardware
317                          * to donate to look into this problem....
318                          */
319                         LOG_ERROR("mystery debug reason MOE=0xc. Try issuing a resume + halt.");
320                         target->debug_reason = DBG_REASON_DBGRQ;
321                         retval = ERROR_TARGET_FAILURE;
322                         break;
323                 default:
324                         LOG_ERROR("BUG: unknown debug reason: 0x%x", debug_reason);
325                         target->debug_reason = DBG_REASON_DBGRQ;
326                         /* if we fail here, we won't talk to the target and it will
327                          * be reported to be in the halted state */
328                         retval = ERROR_TARGET_FAILURE;
329                         break;
330         }
331
332         return retval;
333 }
334
335 u32 arm926ejs_get_ttb(target_t *target)
336 {
337         armv4_5_common_t *armv4_5 = target->arch_info;
338         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
339         arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
340         arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
341         int retval;
342         u32 ttb = 0x0;
343
344         if ((retval = arm926ejs->read_cp15(target, 0, 0, 2, 0, &ttb)) != ERROR_OK)
345                 return retval;
346
347         return ttb;
348 }
349
350 void arm926ejs_disable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
351 {
352         armv4_5_common_t *armv4_5 = target->arch_info;
353         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
354         arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
355         arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
356         u32 cp15_control;
357
358         /* read cp15 control register */
359         arm926ejs->read_cp15(target, 0, 0, 1, 0, &cp15_control);
360         jtag_execute_queue();
361
362         if (mmu)
363         {
364                 /* invalidate TLB */
365                 arm926ejs->write_cp15(target, 0, 0, 8, 7, 0x0);
366
367                 cp15_control &= ~0x1U;
368         }
369
370         if (d_u_cache)
371         {
372                 u32 debug_override;
373                 /* read-modify-write CP15 debug override register
374                  * to enable "test and clean all" */
375                 arm926ejs->read_cp15(target, 0, 0, 15, 0, &debug_override);
376                 debug_override |= 0x80000;
377                 arm926ejs->write_cp15(target, 0, 0, 15, 0, debug_override);
378
379                 /* clean and invalidate DCache */
380                 arm926ejs->write_cp15(target, 0, 0, 7, 5, 0x0);
381
382                 /* write CP15 debug override register
383                  * to disable "test and clean all" */
384                 debug_override &= ~0x80000;
385                 arm926ejs->write_cp15(target, 0, 0, 15, 0, debug_override);
386
387                 cp15_control &= ~0x4U;
388         }
389
390         if (i_cache)
391         {
392                 /* invalidate ICache */
393                 arm926ejs->write_cp15(target, 0, 0, 7, 5, 0x0);
394
395                 cp15_control &= ~0x1000U;
396         }
397
398         arm926ejs->write_cp15(target, 0, 0, 1, 0, cp15_control);
399 }
400
401 void arm926ejs_enable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
402 {
403         armv4_5_common_t *armv4_5 = target->arch_info;
404         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
405         arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
406         arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
407         u32 cp15_control;
408
409         /* read cp15 control register */
410         arm926ejs->read_cp15(target, 0, 0, 1, 0, &cp15_control);
411         jtag_execute_queue();
412
413         if (mmu)
414                 cp15_control |= 0x1U;
415
416         if (d_u_cache)
417                 cp15_control |= 0x4U;
418
419         if (i_cache)
420                 cp15_control |= 0x1000U;
421
422         arm926ejs->write_cp15(target, 0, 0, 1, 0, cp15_control);
423 }
424
425 void arm926ejs_post_debug_entry(target_t *target)
426 {
427         armv4_5_common_t *armv4_5 = target->arch_info;
428         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
429         arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
430         arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
431
432         /* examine cp15 control reg */
433         arm926ejs->read_cp15(target, 0, 0, 1, 0, &arm926ejs->cp15_control_reg);
434         jtag_execute_queue();
435         LOG_DEBUG("cp15_control_reg: %8.8x", arm926ejs->cp15_control_reg);
436
437         if (arm926ejs->armv4_5_mmu.armv4_5_cache.ctype == -1)
438         {
439                 u32 cache_type_reg;
440                 /* identify caches */
441                 arm926ejs->read_cp15(target, 0, 1, 0, 0, &cache_type_reg);
442                 jtag_execute_queue();
443                 armv4_5_identify_cache(cache_type_reg, &arm926ejs->armv4_5_mmu.armv4_5_cache);
444         }
445
446         arm926ejs->armv4_5_mmu.mmu_enabled = (arm926ejs->cp15_control_reg & 0x1U) ? 1 : 0;
447         arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = (arm926ejs->cp15_control_reg & 0x4U) ? 1 : 0;
448         arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled = (arm926ejs->cp15_control_reg & 0x1000U) ? 1 : 0;
449
450         /* save i/d fault status and address register */
451         arm926ejs->read_cp15(target, 0, 0, 5, 0, &arm926ejs->d_fsr);
452         arm926ejs->read_cp15(target, 0, 1, 5, 0, &arm926ejs->i_fsr);
453         arm926ejs->read_cp15(target, 0, 0, 6, 0, &arm926ejs->d_far);
454
455         LOG_DEBUG("D FSR: 0x%8.8x, D FAR: 0x%8.8x, I FSR: 0x%8.8x",
456                 arm926ejs->d_fsr, arm926ejs->d_far, arm926ejs->i_fsr);
457
458         u32 cache_dbg_ctrl;
459
460         /* read-modify-write CP15 cache debug control register
461          * to disable I/D-cache linefills and force WT */
462         arm926ejs->read_cp15(target, 7, 0, 15, 0, &cache_dbg_ctrl);
463         cache_dbg_ctrl |= 0x7;
464         arm926ejs->write_cp15(target, 7, 0, 15, 0, cache_dbg_ctrl);
465 }
466
467 void arm926ejs_pre_restore_context(target_t *target)
468 {
469         armv4_5_common_t *armv4_5 = target->arch_info;
470         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
471         arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
472         arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
473
474         /* restore i/d fault status and address register */
475         arm926ejs->write_cp15(target, 0, 0, 5, 0, arm926ejs->d_fsr);
476         arm926ejs->write_cp15(target, 0, 1, 5, 0, arm926ejs->i_fsr);
477         arm926ejs->write_cp15(target, 0, 0, 6, 0, arm926ejs->d_far);
478
479         u32 cache_dbg_ctrl;
480
481         /* read-modify-write CP15 cache debug control register
482          * to reenable I/D-cache linefills and disable WT */
483         arm926ejs->read_cp15(target, 7, 0, 15, 0, &cache_dbg_ctrl);
484         cache_dbg_ctrl &= ~0x7;
485         arm926ejs->write_cp15(target, 7, 0, 15, 0, cache_dbg_ctrl);
486 }
487
488 int arm926ejs_get_arch_pointers(target_t *target, armv4_5_common_t **armv4_5_p, arm7_9_common_t **arm7_9_p, arm9tdmi_common_t **arm9tdmi_p, arm926ejs_common_t **arm926ejs_p)
489 {
490         armv4_5_common_t *armv4_5 = target->arch_info;
491         arm7_9_common_t *arm7_9;
492         arm9tdmi_common_t *arm9tdmi;
493         arm926ejs_common_t *arm926ejs;
494
495         if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
496         {
497                 return -1;
498         }
499
500         arm7_9 = armv4_5->arch_info;
501         if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
502         {
503                 return -1;
504         }
505
506         arm9tdmi = arm7_9->arch_info;
507         if (arm9tdmi->common_magic != ARM9TDMI_COMMON_MAGIC)
508         {
509                 return -1;
510         }
511
512         arm926ejs = arm9tdmi->arch_info;
513         if (arm926ejs->common_magic != ARM926EJS_COMMON_MAGIC)
514         {
515                 return -1;
516         }
517
518         *armv4_5_p = armv4_5;
519         *arm7_9_p = arm7_9;
520         *arm9tdmi_p = arm9tdmi;
521         *arm926ejs_p = arm926ejs;
522
523         return ERROR_OK;
524 }
525
526 int arm926ejs_arch_state(struct target_s *target)
527 {
528         armv4_5_common_t *armv4_5 = target->arch_info;
529         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
530         arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
531         arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
532
533         char *state[] =
534         {
535                 "disabled", "enabled"
536         };
537
538         if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
539         {
540                 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
541                 exit(-1);
542         }
543
544         LOG_USER(
545                         "target halted in %s state due to %s, current mode: %s\n"
546                         "cpsr: 0x%8.8x pc: 0x%8.8x\n"
547                         "MMU: %s, D-Cache: %s, I-Cache: %s",
548                          armv4_5_state_strings[armv4_5->core_state],
549                          Jim_Nvp_value2name_simple( nvp_target_debug_reason,target->debug_reason)->name,
550                          armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)],
551                          buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
552                          buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
553                          state[arm926ejs->armv4_5_mmu.mmu_enabled],
554                          state[arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],
555                          state[arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled]);
556
557         return ERROR_OK;
558 }
559
560 int arm926ejs_soft_reset_halt(struct target_s *target)
561 {
562         int retval = ERROR_OK;
563         armv4_5_common_t *armv4_5 = target->arch_info;
564         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
565         arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
566         arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
567         reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
568
569         if ((retval = target_halt(target)) != ERROR_OK)
570         {
571                 return retval;
572         }
573
574         long long then=timeval_ms();
575         int timeout;
576         while (!(timeout=((timeval_ms()-then)>1000)))
577         {
578                 if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0)
579                 {
580                         embeddedice_read_reg(dbg_stat);
581                         if ((retval = jtag_execute_queue()) != ERROR_OK)
582                         {
583                                 return retval;
584                         }
585                 }  else
586                 {
587                         break;
588                 }
589                 if (debug_level>=1)
590                 {
591                         /* do not eat all CPU, time out after 1 se*/
592                         alive_sleep(100);
593                 } else
594                 {
595                         keep_alive();
596                 }
597         }
598         if (timeout)
599         {
600                 LOG_ERROR("Failed to halt CPU after 1 sec");
601                 return ERROR_TARGET_TIMEOUT;
602         }
603
604         target->state = TARGET_HALTED;
605
606         /* SVC, ARM state, IRQ and FIQ disabled */
607         buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8, 0xd3);
608         armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
609         armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
610
611         /* start fetching from 0x0 */
612         buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
613         armv4_5->core_cache->reg_list[15].dirty = 1;
614         armv4_5->core_cache->reg_list[15].valid = 1;
615
616         armv4_5->core_mode = ARMV4_5_MODE_SVC;
617         armv4_5->core_state = ARMV4_5_STATE_ARM;
618
619         arm926ejs_disable_mmu_caches(target, 1, 1, 1);
620         arm926ejs->armv4_5_mmu.mmu_enabled = 0;
621         arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;
622         arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;
623
624         return target_call_event_callbacks(target, TARGET_EVENT_HALTED);
625 }
626
627 int arm926ejs_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
628 {
629         int retval;
630         armv4_5_common_t *armv4_5 = target->arch_info;
631         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
632         arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
633         arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
634
635         if ((retval = arm7_9_write_memory(target, address, size, count, buffer)) != ERROR_OK)
636                 return retval;
637
638         /* If ICache is enabled, we have to invalidate affected ICache lines
639          * the DCache is forced to write-through, so we don't have to clean it here
640          */
641         if (arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled)
642         {
643                 if (count <= 1)
644                 {
645                         /* invalidate ICache single entry with MVA */
646                         arm926ejs->write_cp15(target, 0, 1, 7, 5, address);
647                 }
648                 else
649                 {
650                         /* invalidate ICache */
651                         arm926ejs->write_cp15(target, 0, 0, 7, 5, address);
652                 }
653         }
654
655         return retval;
656 }
657
658 int arm926ejs_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
659 {
660         arm9tdmi_init_target(cmd_ctx, target);
661
662         return ERROR_OK;
663 }
664
665 int arm926ejs_quit(void)
666 {
667         return ERROR_OK;
668 }
669
670 int arm926ejs_init_arch_info(target_t *target, arm926ejs_common_t *arm926ejs, jtag_tap_t *tap)
671 {
672         arm9tdmi_common_t *arm9tdmi = &arm926ejs->arm9tdmi_common;
673         arm7_9_common_t *arm7_9 = &arm9tdmi->arm7_9_common;
674
675         /* initialize arm9tdmi specific info (including arm7_9 and armv4_5)
676          */
677         arm9tdmi_init_arch_info(target, arm9tdmi, tap);
678
679         arm9tdmi->arch_info = arm926ejs;
680         arm926ejs->common_magic = ARM926EJS_COMMON_MAGIC;
681
682         arm7_9->post_debug_entry = arm926ejs_post_debug_entry;
683         arm7_9->pre_restore_context = arm926ejs_pre_restore_context;
684
685         arm926ejs->read_cp15 = arm926ejs_cp15_read;
686         arm926ejs->write_cp15 = arm926ejs_cp15_write;
687         arm926ejs->armv4_5_mmu.armv4_5_cache.ctype = -1;
688         arm926ejs->armv4_5_mmu.get_ttb = arm926ejs_get_ttb;
689         arm926ejs->armv4_5_mmu.read_memory = arm7_9_read_memory;
690         arm926ejs->armv4_5_mmu.write_memory = arm7_9_write_memory;
691         arm926ejs->armv4_5_mmu.disable_mmu_caches = arm926ejs_disable_mmu_caches;
692         arm926ejs->armv4_5_mmu.enable_mmu_caches = arm926ejs_enable_mmu_caches;
693         arm926ejs->armv4_5_mmu.has_tiny_pages = 1;
694         arm926ejs->armv4_5_mmu.mmu_enabled = 0;
695
696         arm7_9->examine_debug_reason = arm926ejs_examine_debug_reason;
697
698         /* The ARM926EJ-S implements the ARMv5TE architecture which
699          * has the BKPT instruction, so we don't have to use a watchpoint comparator
700          */
701         arm7_9->arm_bkpt = ARMV5_BKPT(0x0);
702         arm7_9->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
703
704         return ERROR_OK;
705 }
706
707 int arm926ejs_target_create(struct target_s *target, Jim_Interp *interp)
708 {
709         arm926ejs_common_t *arm926ejs = calloc(1,sizeof(arm926ejs_common_t));
710
711         arm926ejs_init_arch_info(target, arm926ejs, target->tap);
712
713         return ERROR_OK;
714 }
715
716 int arm926ejs_register_commands(struct command_context_s *cmd_ctx)
717 {
718         int retval;
719         command_t *arm926ejs_cmd;
720
721
722         retval = arm9tdmi_register_commands(cmd_ctx);
723
724         arm926ejs_cmd = register_command(cmd_ctx, NULL, "arm926ejs", NULL, COMMAND_ANY, "arm926ejs specific commands");
725
726         register_command(cmd_ctx, arm926ejs_cmd, "cp15", arm926ejs_handle_cp15_command, COMMAND_EXEC, "display/modify cp15 register <opcode_1> <opcode_2> <CRn> <CRm> [value]");
727
728         register_command(cmd_ctx, arm926ejs_cmd, "cache_info", arm926ejs_handle_cache_info_command, COMMAND_EXEC, "display information about target caches");
729         register_command(cmd_ctx, arm926ejs_cmd, "virt2phys", arm926ejs_handle_virt2phys_command, COMMAND_EXEC, "translate va to pa <va>");
730
731         register_command(cmd_ctx, arm926ejs_cmd, "mdw_phys", arm926ejs_handle_md_phys_command, COMMAND_EXEC, "display memory words <physical addr> [count]");
732         register_command(cmd_ctx, arm926ejs_cmd, "mdh_phys", arm926ejs_handle_md_phys_command, COMMAND_EXEC, "display memory half-words <physical addr> [count]");
733         register_command(cmd_ctx, arm926ejs_cmd, "mdb_phys", arm926ejs_handle_md_phys_command, COMMAND_EXEC, "display memory bytes <physical addr> [count]");
734
735         register_command(cmd_ctx, arm926ejs_cmd, "mww_phys", arm926ejs_handle_mw_phys_command, COMMAND_EXEC, "write memory word <physical addr> <value>");
736         register_command(cmd_ctx, arm926ejs_cmd, "mwh_phys", arm926ejs_handle_mw_phys_command, COMMAND_EXEC, "write memory half-word <physical addr> <value>");
737         register_command(cmd_ctx, arm926ejs_cmd, "mwb_phys", arm926ejs_handle_mw_phys_command, COMMAND_EXEC, "write memory byte <physical addr> <value>");
738
739         return retval;
740 }
741
742 int arm926ejs_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
743 {
744         int retval;
745         target_t *target = get_current_target(cmd_ctx);
746         armv4_5_common_t *armv4_5;
747         arm7_9_common_t *arm7_9;
748         arm9tdmi_common_t *arm9tdmi;
749         arm926ejs_common_t *arm926ejs;
750         int opcode_1;
751         int opcode_2;
752         int CRn;
753         int CRm;
754
755         if ((argc < 4) || (argc > 5))
756         {
757                 command_print(cmd_ctx, "usage: arm926ejs cp15 <opcode_1> <opcode_2> <CRn> <CRm> [value]");
758                 return ERROR_OK;
759         }
760
761         opcode_1 = strtoul(args[0], NULL, 0);
762         opcode_2 = strtoul(args[1], NULL, 0);
763         CRn = strtoul(args[2], NULL, 0);
764         CRm = strtoul(args[3], NULL, 0);
765
766         if (arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs) != ERROR_OK)
767         {
768                 command_print(cmd_ctx, "current target isn't an ARM926EJ-S target");
769                 return ERROR_OK;
770         }
771
772         if (target->state != TARGET_HALTED)
773         {
774                 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
775                 return ERROR_OK;
776         }
777
778         if (argc == 4)
779         {
780                 u32 value;
781                 if ((retval = arm926ejs->read_cp15(target, opcode_1, opcode_2, CRn, CRm, &value)) != ERROR_OK)
782                 {
783                         command_print(cmd_ctx, "couldn't access register");
784                         return ERROR_OK;
785                 }
786                 if ((retval = jtag_execute_queue()) != ERROR_OK)
787                 {
788                         return retval;
789                 }
790
791                 command_print(cmd_ctx, "%i %i %i %i: %8.8x", opcode_1, opcode_2, CRn, CRm, value);
792         }
793         else
794         {
795                 u32 value = strtoul(args[4], NULL, 0);
796                 if ((retval = arm926ejs->write_cp15(target, opcode_1, opcode_2, CRn, CRm, value)) != ERROR_OK)
797                 {
798                         command_print(cmd_ctx, "couldn't access register");
799                         return ERROR_OK;
800                 }
801                 command_print(cmd_ctx, "%i %i %i %i: %8.8x", opcode_1, opcode_2, CRn, CRm, value);
802         }
803
804         return ERROR_OK;
805 }
806
807 int arm926ejs_handle_cache_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
808 {
809         target_t *target = get_current_target(cmd_ctx);
810         armv4_5_common_t *armv4_5;
811         arm7_9_common_t *arm7_9;
812         arm9tdmi_common_t *arm9tdmi;
813         arm926ejs_common_t *arm926ejs;
814
815         if (arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs) != ERROR_OK)
816         {
817                 command_print(cmd_ctx, "current target isn't an ARM926EJ-S target");
818                 return ERROR_OK;
819         }
820
821         return armv4_5_handle_cache_info_command(cmd_ctx, &arm926ejs->armv4_5_mmu.armv4_5_cache);
822 }
823
824 int arm926ejs_handle_virt2phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
825 {
826         target_t *target = get_current_target(cmd_ctx);
827         armv4_5_common_t *armv4_5;
828         arm7_9_common_t *arm7_9;
829         arm9tdmi_common_t *arm9tdmi;
830         arm926ejs_common_t *arm926ejs;
831         arm_jtag_t *jtag_info;
832
833         if (arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs) != ERROR_OK)
834         {
835                 command_print(cmd_ctx, "current target isn't an ARM926EJ-S target");
836                 return ERROR_OK;
837         }
838
839         jtag_info = &arm7_9->jtag_info;
840
841         if (target->state != TARGET_HALTED)
842         {
843                 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
844                 return ERROR_OK;
845         }
846
847         return armv4_5_mmu_handle_virt2phys_command(cmd_ctx, cmd, args, argc, target, &arm926ejs->armv4_5_mmu);
848 }
849
850 int arm926ejs_handle_md_phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
851 {
852         target_t *target = get_current_target(cmd_ctx);
853         armv4_5_common_t *armv4_5;
854         arm7_9_common_t *arm7_9;
855         arm9tdmi_common_t *arm9tdmi;
856         arm926ejs_common_t *arm926ejs;
857         arm_jtag_t *jtag_info;
858
859         if (arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs) != ERROR_OK)
860         {
861                 command_print(cmd_ctx, "current target isn't an ARM926EJ-S target");
862                 return ERROR_OK;
863         }
864
865         jtag_info = &arm7_9->jtag_info;
866
867         if (target->state != TARGET_HALTED)
868         {
869                 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
870                 return ERROR_OK;
871         }
872
873         return armv4_5_mmu_handle_md_phys_command(cmd_ctx, cmd, args, argc, target, &arm926ejs->armv4_5_mmu);
874 }
875
876 int arm926ejs_handle_mw_phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
877 {
878         target_t *target = get_current_target(cmd_ctx);
879         armv4_5_common_t *armv4_5;
880         arm7_9_common_t *arm7_9;
881         arm9tdmi_common_t *arm9tdmi;
882         arm926ejs_common_t *arm926ejs;
883         arm_jtag_t *jtag_info;
884
885         if (arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs) != ERROR_OK)
886         {
887                 command_print(cmd_ctx, "current target isn't an ARM926EJ-S target");
888                 return ERROR_OK;
889         }
890
891         jtag_info = &arm7_9->jtag_info;
892
893         if (target->state != TARGET_HALTED)
894         {
895                 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
896                 return ERROR_OK;
897         }
898
899         return armv4_5_mmu_handle_mw_phys_command(cmd_ctx, cmd, args, argc, target, &arm926ejs->armv4_5_mmu);
900 }
901
902 static int arm926ejs_virt2phys(struct target_s *target, u32 virtual, u32 *physical)
903 {
904         int retval;
905         int type;
906         u32 cb;
907         int domain;
908         u32 ap;
909
910         armv4_5_common_t *armv4_5;
911         arm7_9_common_t *arm7_9;
912         arm9tdmi_common_t *arm9tdmi;
913         arm926ejs_common_t *arm926ejs;
914         retval= arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs);
915         if (retval != ERROR_OK)
916         {
917                 return retval;
918         }
919         u32 ret = armv4_5_mmu_translate_va(target, &arm926ejs->armv4_5_mmu, virtual, &type, &cb, &domain, &ap);
920         if (type == -1)
921         {
922                 return ret;
923         }
924         *physical = ret;
925         return ERROR_OK;
926 }
927
928 static int arm926ejs_mmu(struct target_s *target, int *enabled)
929 {
930         armv4_5_common_t *armv4_5 = target->arch_info;
931         arm926ejs_common_t *arm926ejs = armv4_5->arch_info;
932
933         if (target->state != TARGET_HALTED)
934         {
935                 LOG_ERROR("Target not halted");
936                 return ERROR_TARGET_INVALID;
937         }
938         *enabled = arm926ejs->armv4_5_mmu.mmu_enabled;
939         return ERROR_OK;
940 }