]> git.sur5r.net Git - openocd/blob - src/target/arm926ejs.c
6a076c1f902bc0f5cdb67b4a36dc2cf31eb4413d
[openocd] / src / target / arm926ejs.c
1 /***************************************************************************
2  *   Copyright (C) 2007 by Dominic Rath                                    *
3  *   Dominic.Rath@gmx.de                                                   *
4  *                                                                         *
5  *   Copyright (C) 2007,2008,2009 by Ã˜yvind Harboe                         *
6  *   oyvind.harboe@zylin.com                                               *
7  *                                                                         *
8  *   This program is free software; you can redistribute it and/or modify  *
9  *   it under the terms of the GNU General Public License as published by  *
10  *   the Free Software Foundation; either version 2 of the License, or     *
11  *   (at your option) any later version.                                   *
12  *                                                                         *
13  *   This program is distributed in the hope that it will be useful,       *
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
16  *   GNU General Public License for more details.                          *
17  *                                                                         *
18  *   You should have received a copy of the GNU General Public License     *
19  *   along with this program; if not, write to the                         *
20  *   Free Software Foundation, Inc.,                                       *
21  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
22  ***************************************************************************/
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include "arm926ejs.h"
29 #include <helper/time_support.h>
30 #include "target_type.h"
31 #include "register.h"
32 #include "arm_opcodes.h"
33
34
35 /*
36  * The ARM926 is built around the ARM9EJ-S core, and most JTAG docs
37  * are in the ARM9EJ-S Technical Reference Manual (ARM DDI 0222B) not
38  * the ARM926 manual (ARM DDI 0198E).  The scan chains are:
39  *
40  *   1 ... core debugging
41  *   2 ... EmbeddedICE
42  *   3 ... external boundary scan (SoC-specific, unused here)
43  *   6 ... ETM
44  *   15 ... coprocessor 15
45  */
46
47 #if 0
48 #define _DEBUG_INSTRUCTION_EXECUTION_
49 #endif
50
51 #define ARM926EJS_CP15_ADDR(opcode_1, opcode_2, CRn, CRm) ((opcode_1 << 11) | (opcode_2 << 8) | (CRn << 4) | (CRm << 0))
52
53 static int arm926ejs_cp15_read(struct target *target, uint32_t op1, uint32_t op2,
54                 uint32_t CRn, uint32_t CRm, uint32_t *value)
55 {
56         int retval = ERROR_OK;
57         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
58         struct arm_jtag *jtag_info = &arm7_9->jtag_info;
59         uint32_t address = ARM926EJS_CP15_ADDR(op1, op2, CRn, CRm);
60         struct scan_field fields[4];
61         uint8_t address_buf[2] = {0, 0};
62         uint8_t nr_w_buf = 0;
63         uint8_t access_t = 1;
64
65         buf_set_u32(address_buf, 0, 14, address);
66
67         retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);
68         if (retval != ERROR_OK)
69                 return retval;
70         retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_IDLE);
71         if (retval != ERROR_OK)
72                 return retval;
73
74         fields[0].num_bits = 32;
75         fields[0].out_value = NULL;
76         fields[0].in_value = (uint8_t *)value;
77
78         fields[1].num_bits = 1;
79         fields[1].out_value = &access_t;
80         fields[1].in_value = &access_t;
81
82         fields[2].num_bits = 14;
83         fields[2].out_value = address_buf;
84         fields[2].in_value = NULL;
85
86         fields[3].num_bits = 1;
87         fields[3].out_value = &nr_w_buf;
88         fields[3].in_value = NULL;
89
90         jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
91
92         long long then = timeval_ms();
93
94         for (;;) {
95                 /* rescan with NOP, to wait for the access to complete */
96                 access_t = 0;
97                 nr_w_buf = 0;
98                 jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
99
100                 jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)value);
101
102                 retval = jtag_execute_queue();
103                 if (retval != ERROR_OK)
104                         return retval;
105
106                 if (buf_get_u32(&access_t, 0, 1) == 1)
107                         break;
108
109                 /* 10ms timeout */
110                 if ((timeval_ms()-then) > 10) {
111                         LOG_ERROR("cp15 read operation timed out");
112                         return ERROR_FAIL;
113                 }
114         }
115
116 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
117         LOG_DEBUG("addr: 0x%x value: %8.8x", address, *value);
118 #endif
119
120         retval = arm_jtag_set_instr(jtag_info, 0xc, NULL, TAP_IDLE);
121         if (retval != ERROR_OK)
122                 return retval;
123
124         return ERROR_OK;
125 }
126
127 static int arm926ejs_mrc(struct target *target, int cpnum, uint32_t op1,
128                 uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t *value)
129 {
130         if (cpnum != 15) {
131                 LOG_ERROR("Only cp15 is supported");
132                 return ERROR_FAIL;
133         }
134         return arm926ejs_cp15_read(target, op1, op2, CRn, CRm, value);
135 }
136
137 static int arm926ejs_cp15_write(struct target *target, uint32_t op1, uint32_t op2,
138                 uint32_t CRn, uint32_t CRm, uint32_t value)
139 {
140         int retval = ERROR_OK;
141         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
142         struct arm_jtag *jtag_info = &arm7_9->jtag_info;
143         uint32_t address = ARM926EJS_CP15_ADDR(op1, op2, CRn, CRm);
144         struct scan_field fields[4];
145         uint8_t value_buf[4];
146         uint8_t address_buf[2] = {0, 0};
147         uint8_t nr_w_buf = 1;
148         uint8_t access_t = 1;
149
150         buf_set_u32(address_buf, 0, 14, address);
151         buf_set_u32(value_buf, 0, 32, value);
152
153         retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);
154         if (retval != ERROR_OK)
155                 return retval;
156         retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_IDLE);
157         if (retval != ERROR_OK)
158                 return retval;
159
160         fields[0].num_bits = 32;
161         fields[0].out_value = value_buf;
162         fields[0].in_value = NULL;
163
164         fields[1].num_bits = 1;
165         fields[1].out_value = &access_t;
166         fields[1].in_value = &access_t;
167
168         fields[2].num_bits = 14;
169         fields[2].out_value = address_buf;
170         fields[2].in_value = NULL;
171
172         fields[3].num_bits = 1;
173         fields[3].out_value = &nr_w_buf;
174         fields[3].in_value = NULL;
175
176         jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
177
178         long long then = timeval_ms();
179
180         for (;;) {
181                 /* rescan with NOP, to wait for the access to complete */
182                 access_t = 0;
183                 nr_w_buf = 0;
184                 jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
185                 retval = jtag_execute_queue();
186                 if (retval != ERROR_OK)
187                         return retval;
188
189                 if (buf_get_u32(&access_t, 0, 1) == 1)
190                         break;
191
192                 /* 10ms timeout */
193                 if ((timeval_ms()-then) > 10) {
194                         LOG_ERROR("cp15 write operation timed out");
195                         return ERROR_FAIL;
196                 }
197         }
198
199 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
200         LOG_DEBUG("addr: 0x%x value: %8.8x", address, value);
201 #endif
202
203         retval = arm_jtag_set_instr(jtag_info, 0xf, NULL, TAP_IDLE);
204         if (retval != ERROR_OK)
205                 return retval;
206
207         return ERROR_OK;
208 }
209
210 static int arm926ejs_mcr(struct target *target, int cpnum, uint32_t op1,
211                 uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t value)
212 {
213         if (cpnum != 15) {
214                 LOG_ERROR("Only cp15 is supported");
215                 return ERROR_FAIL;
216         }
217         return arm926ejs_cp15_write(target, op1, op2, CRn, CRm, value);
218 }
219
220 static int arm926ejs_examine_debug_reason(struct target *target)
221 {
222         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
223         struct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
224         int debug_reason;
225         int retval;
226
227         embeddedice_read_reg(dbg_stat);
228         retval = jtag_execute_queue();
229         if (retval != ERROR_OK)
230                 return retval;
231
232         /* Method-Of-Entry (MOE) field */
233         debug_reason = buf_get_u32(dbg_stat->value, 6, 4);
234
235         switch (debug_reason) {
236                 case 0:
237                         LOG_DEBUG("no *NEW* debug entry (?missed one?)");
238                         /* ... since last restart or debug reset ... */
239                         target->debug_reason = DBG_REASON_DBGRQ;
240                         break;
241                 case 1:
242                         LOG_DEBUG("breakpoint from EICE unit 0");
243                         target->debug_reason = DBG_REASON_BREAKPOINT;
244                         break;
245                 case 2:
246                         LOG_DEBUG("breakpoint from EICE unit 1");
247                         target->debug_reason = DBG_REASON_BREAKPOINT;
248                         break;
249                 case 3:
250                         LOG_DEBUG("soft breakpoint (BKPT instruction)");
251                         target->debug_reason = DBG_REASON_BREAKPOINT;
252                         break;
253                 case 4:
254                         LOG_DEBUG("vector catch breakpoint");
255                         target->debug_reason = DBG_REASON_BREAKPOINT;
256                         break;
257                 case 5:
258                         LOG_DEBUG("external breakpoint");
259                         target->debug_reason = DBG_REASON_BREAKPOINT;
260                         break;
261                 case 6:
262                         LOG_DEBUG("watchpoint from EICE unit 0");
263                         target->debug_reason = DBG_REASON_WATCHPOINT;
264                         break;
265                 case 7:
266                         LOG_DEBUG("watchpoint from EICE unit 1");
267                         target->debug_reason = DBG_REASON_WATCHPOINT;
268                         break;
269                 case 8:
270                         LOG_DEBUG("external watchpoint");
271                         target->debug_reason = DBG_REASON_WATCHPOINT;
272                         break;
273                 case 9:
274                         LOG_DEBUG("internal debug request");
275                         target->debug_reason = DBG_REASON_DBGRQ;
276                         break;
277                 case 10:
278                         LOG_DEBUG("external debug request");
279                         target->debug_reason = DBG_REASON_DBGRQ;
280                         break;
281                 case 11:
282                         LOG_DEBUG("debug re-entry from system speed access");
283                         /* This is normal when connecting to something that's
284                          * already halted, or in some related code paths, but
285                          * otherwise is surprising (and presumably wrong).
286                          */
287                         switch (target->debug_reason) {
288                         case DBG_REASON_DBGRQ:
289                                 break;
290                         default:
291                                 LOG_ERROR("unexpected -- debug re-entry");
292                                 /* FALLTHROUGH */
293                         case DBG_REASON_UNDEFINED:
294                                 target->debug_reason = DBG_REASON_DBGRQ;
295                                 break;
296                         }
297                         break;
298                 case 12:
299                         /* FIX!!!! here be dragons!!! We need to fail here so
300                          * the target will interpreted as halted but we won't
301                          * try to talk to it right now... a resume + halt seems
302                          * to sync things up again. Please send an email to
303                          * openocd development mailing list if you have hardware
304                          * to donate to look into this problem....
305                          */
306                         LOG_WARNING("WARNING: mystery debug reason MOE = 0xc. Try issuing a resume + halt.");
307                         target->debug_reason = DBG_REASON_DBGRQ;
308                         break;
309                 default:
310                         LOG_WARNING("WARNING: unknown debug reason: 0x%x", debug_reason);
311                         /* Oh agony! should we interpret this as a halt request or
312                          * that the target stopped on it's own accord?
313                          */
314                         target->debug_reason = DBG_REASON_DBGRQ;
315                         /* if we fail here, we won't talk to the target and it will
316                          * be reported to be in the halted state */
317                         break;
318         }
319
320         return ERROR_OK;
321 }
322
323 static int arm926ejs_get_ttb(struct target *target, uint32_t *result)
324 {
325         struct arm926ejs_common *arm926ejs = target_to_arm926(target);
326         int retval;
327         uint32_t ttb = 0x0;
328
329         retval = arm926ejs->read_cp15(target, 0, 0, 2, 0, &ttb);
330         if (retval != ERROR_OK)
331                 return retval;
332
333         *result = ttb;
334
335         return ERROR_OK;
336 }
337
338 static int arm926ejs_disable_mmu_caches(struct target *target, int mmu,
339                 int d_u_cache, int i_cache)
340 {
341         struct arm926ejs_common *arm926ejs = target_to_arm926(target);
342         uint32_t cp15_control;
343         int retval;
344
345         /* read cp15 control register */
346         retval = arm926ejs->read_cp15(target, 0, 0, 1, 0, &cp15_control);
347         if (retval != ERROR_OK)
348                 return retval;
349         retval = jtag_execute_queue();
350         if (retval != ERROR_OK)
351                 return retval;
352
353         if (mmu) {
354                 /* invalidate TLB */
355                 retval = arm926ejs->write_cp15(target, 0, 0, 8, 7, 0x0);
356                 if (retval != ERROR_OK)
357                         return retval;
358
359                 cp15_control &= ~0x1U;
360         }
361
362         if (d_u_cache) {
363                 uint32_t debug_override;
364                 /* read-modify-write CP15 debug override register
365                  * to enable "test and clean all" */
366                 retval = arm926ejs->read_cp15(target, 0, 0, 15, 0, &debug_override);
367                 if (retval != ERROR_OK)
368                         return retval;
369                 debug_override |= 0x80000;
370                 retval = arm926ejs->write_cp15(target, 0, 0, 15, 0, debug_override);
371                 if (retval != ERROR_OK)
372                         return retval;
373
374                 /* clean and invalidate DCache */
375                 retval = arm926ejs->write_cp15(target, 0, 0, 7, 5, 0x0);
376                 if (retval != ERROR_OK)
377                         return retval;
378
379                 /* write CP15 debug override register
380                  * to disable "test and clean all" */
381                 debug_override &= ~0x80000;
382                 retval = arm926ejs->write_cp15(target, 0, 0, 15, 0, debug_override);
383                 if (retval != ERROR_OK)
384                         return retval;
385
386                 cp15_control &= ~0x4U;
387         }
388
389         if (i_cache) {
390                 /* invalidate ICache */
391                 retval = arm926ejs->write_cp15(target, 0, 0, 7, 5, 0x0);
392                 if (retval != ERROR_OK)
393                         return retval;
394
395                 cp15_control &= ~0x1000U;
396         }
397
398         retval = arm926ejs->write_cp15(target, 0, 0, 1, 0, cp15_control);
399         return retval;
400 }
401
402 static int arm926ejs_enable_mmu_caches(struct target *target, int mmu,
403                 int d_u_cache, int i_cache)
404 {
405         struct arm926ejs_common *arm926ejs = target_to_arm926(target);
406         uint32_t cp15_control;
407         int retval;
408
409         /* read cp15 control register */
410         retval = arm926ejs->read_cp15(target, 0, 0, 1, 0, &cp15_control);
411         if (retval != ERROR_OK)
412                 return retval;
413         retval = jtag_execute_queue();
414         if (retval != ERROR_OK)
415                 return retval;
416
417         if (mmu)
418                 cp15_control |= 0x1U;
419
420         if (d_u_cache)
421                 cp15_control |= 0x4U;
422
423         if (i_cache)
424                 cp15_control |= 0x1000U;
425
426         retval = arm926ejs->write_cp15(target, 0, 0, 1, 0, cp15_control);
427         return retval;
428 }
429
430 static int arm926ejs_post_debug_entry(struct target *target)
431 {
432         struct arm926ejs_common *arm926ejs = target_to_arm926(target);
433         int retval;
434
435         /* examine cp15 control reg */
436         retval = arm926ejs->read_cp15(target, 0, 0, 1, 0, &arm926ejs->cp15_control_reg);
437         if (retval != ERROR_OK)
438                 return retval;
439         retval = jtag_execute_queue();
440         if (retval != ERROR_OK)
441                 return retval;
442         LOG_DEBUG("cp15_control_reg: %8.8" PRIx32 "", arm926ejs->cp15_control_reg);
443
444         if (arm926ejs->armv4_5_mmu.armv4_5_cache.ctype == -1) {
445                 uint32_t cache_type_reg;
446                 /* identify caches */
447                 retval = arm926ejs->read_cp15(target, 0, 1, 0, 0, &cache_type_reg);
448                 if (retval != ERROR_OK)
449                         return retval;
450                 retval = jtag_execute_queue();
451                 if (retval != ERROR_OK)
452                         return retval;
453                 armv4_5_identify_cache(cache_type_reg, &arm926ejs->armv4_5_mmu.armv4_5_cache);
454         }
455
456         arm926ejs->armv4_5_mmu.mmu_enabled = (arm926ejs->cp15_control_reg & 0x1U) ? 1 : 0;
457         arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = (arm926ejs->cp15_control_reg & 0x4U) ? 1 : 0;
458         arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled = (arm926ejs->cp15_control_reg & 0x1000U) ? 1 : 0;
459
460         /* save i/d fault status and address register */
461         retval = arm926ejs->read_cp15(target, 0, 0, 5, 0, &arm926ejs->d_fsr);
462         if (retval != ERROR_OK)
463                 return retval;
464         retval = arm926ejs->read_cp15(target, 0, 1, 5, 0, &arm926ejs->i_fsr);
465         if (retval != ERROR_OK)
466                 return retval;
467         retval = arm926ejs->read_cp15(target, 0, 0, 6, 0, &arm926ejs->d_far);
468         if (retval != ERROR_OK)
469                 return retval;
470
471         LOG_DEBUG("D FSR: 0x%8.8" PRIx32 ", D FAR: 0x%8.8" PRIx32 ", I FSR: 0x%8.8" PRIx32 "",
472                 arm926ejs->d_fsr, arm926ejs->d_far, arm926ejs->i_fsr);
473
474         uint32_t cache_dbg_ctrl;
475
476         /* read-modify-write CP15 cache debug control register
477          * to disable I/D-cache linefills and force WT */
478         retval = arm926ejs->read_cp15(target, 7, 0, 15, 0, &cache_dbg_ctrl);
479         if (retval != ERROR_OK)
480                 return retval;
481         cache_dbg_ctrl |= 0x7;
482         retval = arm926ejs->write_cp15(target, 7, 0, 15, 0, cache_dbg_ctrl);
483         return retval;
484 }
485
486 static void arm926ejs_pre_restore_context(struct target *target)
487 {
488         struct arm926ejs_common *arm926ejs = target_to_arm926(target);
489
490         /* restore i/d fault status and address register */
491         arm926ejs->write_cp15(target, 0, 0, 5, 0, arm926ejs->d_fsr);
492         arm926ejs->write_cp15(target, 0, 1, 5, 0, arm926ejs->i_fsr);
493         arm926ejs->write_cp15(target, 0, 0, 6, 0, arm926ejs->d_far);
494
495         uint32_t cache_dbg_ctrl;
496
497         /* read-modify-write CP15 cache debug control register
498          * to reenable I/D-cache linefills and disable WT */
499         arm926ejs->read_cp15(target, 7, 0, 15, 0, &cache_dbg_ctrl);
500         cache_dbg_ctrl &= ~0x7;
501         arm926ejs->write_cp15(target, 7, 0, 15, 0, cache_dbg_ctrl);
502 }
503
504 static const char arm926_not[] = "target is not an ARM926";
505
506 static int arm926ejs_verify_pointer(struct command_context *cmd_ctx,
507                 struct arm926ejs_common *arm926)
508 {
509         if (arm926->common_magic != ARM926EJS_COMMON_MAGIC) {
510                 command_print(cmd_ctx, arm926_not);
511                 return ERROR_TARGET_INVALID;
512         }
513         return ERROR_OK;
514 }
515
516 /** Logs summary of ARM926 state for a halted target. */
517 int arm926ejs_arch_state(struct target *target)
518 {
519         static const char *state[] = {
520                 "disabled", "enabled"
521         };
522
523         struct arm926ejs_common *arm926ejs = target_to_arm926(target);
524
525         if (arm926ejs->common_magic != ARM926EJS_COMMON_MAGIC) {
526                 LOG_ERROR("BUG: %s", arm926_not);
527                 return ERROR_TARGET_INVALID;
528         }
529
530         arm_arch_state(target);
531         LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
532                          state[arm926ejs->armv4_5_mmu.mmu_enabled],
533                          state[arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],
534                          state[arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled]);
535
536         return ERROR_OK;
537 }
538
539 int arm926ejs_soft_reset_halt(struct target *target)
540 {
541         int retval = ERROR_OK;
542         struct arm926ejs_common *arm926ejs = target_to_arm926(target);
543         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
544         struct arm *arm = &arm7_9->arm;
545         struct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
546
547         retval = target_halt(target);
548         if (retval != ERROR_OK)
549                 return retval;
550
551         long long then = timeval_ms();
552         int timeout;
553         while (!(timeout = ((timeval_ms()-then) > 1000))) {
554                 if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0) {
555                         embeddedice_read_reg(dbg_stat);
556                         retval = jtag_execute_queue();
557                         if (retval != ERROR_OK)
558                                 return retval;
559                 } else
560                         break;
561                 if (debug_level >= 1) {
562                         /* do not eat all CPU, time out after 1 se*/
563                         alive_sleep(100);
564                 } else
565                         keep_alive();
566         }
567         if (timeout) {
568                 LOG_ERROR("Failed to halt CPU after 1 sec");
569                 return ERROR_TARGET_TIMEOUT;
570         }
571
572         target->state = TARGET_HALTED;
573
574         /* SVC, ARM state, IRQ and FIQ disabled */
575         uint32_t cpsr;
576
577         cpsr = buf_get_u32(arm->cpsr->value, 0, 32);
578         cpsr &= ~0xff;
579         cpsr |= 0xd3;
580         arm_set_cpsr(arm, cpsr);
581         arm->cpsr->dirty = 1;
582
583         /* start fetching from 0x0 */
584         buf_set_u32(arm->pc->value, 0, 32, 0x0);
585         arm->pc->dirty = 1;
586         arm->pc->valid = 1;
587
588         retval = arm926ejs_disable_mmu_caches(target, 1, 1, 1);
589         if (retval != ERROR_OK)
590                 return retval;
591         arm926ejs->armv4_5_mmu.mmu_enabled = 0;
592         arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;
593         arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;
594
595         return target_call_event_callbacks(target, TARGET_EVENT_HALTED);
596 }
597
598 /** Writes a buffer, in the specified word size, with current MMU settings. */
599 int arm926ejs_write_memory(struct target *target, uint32_t address,
600                 uint32_t size, uint32_t count, const uint8_t *buffer)
601 {
602         int retval;
603         struct arm926ejs_common *arm926ejs = target_to_arm926(target);
604
605         /* FIX!!!! this should be cleaned up and made much more general. The
606          * plan is to write up and test on arm926ejs specifically and
607          * then generalize and clean up afterwards.
608          *
609          *
610          * Also it should be moved to the callbacks that handle breakpoints
611          * specifically and not the generic memory write fn's. See XScale code.
612          **/
613         if (arm926ejs->armv4_5_mmu.mmu_enabled && (count == 1) && ((size == 2) || (size == 4))) {
614                 /* special case the handling of single word writes to bypass MMU
615                  * to allow implementation of breakpoints in memory marked read only
616                  * by MMU */
617                 if (arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) {
618                         /* flush and invalidate data cache
619                          *
620                          * MCR p15,0,p,c7,c10,1 - clean cache line using virtual address
621                          *
622                          */
623                         retval = arm926ejs->write_cp15(target, 0, 1, 7, 10, address&~0x3);
624                         if (retval != ERROR_OK)
625                                 return retval;
626                 }
627
628                 uint32_t pa;
629                 retval = target->type->virt2phys(target, address, &pa);
630                 if (retval != ERROR_OK)
631                         return retval;
632
633                 /* write directly to physical memory bypassing any read only MMU bits, etc. */
634                 retval = armv4_5_mmu_write_physical(target, &arm926ejs->armv4_5_mmu, pa, size, count, buffer);
635                 if (retval != ERROR_OK)
636                         return retval;
637         } else {
638                 retval = arm7_9_write_memory(target, address, size, count, buffer);
639                 if (retval != ERROR_OK)
640                         return retval;
641         }
642
643         /* If ICache is enabled, we have to invalidate affected ICache lines
644          * the DCache is forced to write-through, so we don't have to clean it here
645          */
646         if (arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled) {
647                 if (count <= 1) {
648                         /* invalidate ICache single entry with MVA */
649                         arm926ejs->write_cp15(target, 0, 1, 7, 5, address);
650                 } else {
651                         /* invalidate ICache */
652                         arm926ejs->write_cp15(target, 0, 0, 7, 5, address);
653                 }
654         }
655
656         return retval;
657 }
658
659 static int arm926ejs_write_phys_memory(struct target *target,
660                 uint32_t address, uint32_t size,
661                 uint32_t count, const uint8_t *buffer)
662 {
663         struct arm926ejs_common *arm926ejs = target_to_arm926(target);
664
665         return armv4_5_mmu_write_physical(target, &arm926ejs->armv4_5_mmu,
666                         address, size, count, buffer);
667 }
668
669 static int arm926ejs_read_phys_memory(struct target *target,
670                 uint32_t address, uint32_t size,
671                 uint32_t count, uint8_t *buffer)
672 {
673         struct arm926ejs_common *arm926ejs = target_to_arm926(target);
674
675         return armv4_5_mmu_read_physical(target, &arm926ejs->armv4_5_mmu,
676                         address, size, count, buffer);
677 }
678
679 int arm926ejs_init_arch_info(struct target *target, struct arm926ejs_common *arm926ejs,
680                 struct jtag_tap *tap)
681 {
682         struct arm7_9_common *arm7_9 = &arm926ejs->arm7_9_common;
683
684         arm7_9->arm.mrc = arm926ejs_mrc;
685         arm7_9->arm.mcr = arm926ejs_mcr;
686
687         /* initialize arm7/arm9 specific info (including armv4_5) */
688         arm9tdmi_init_arch_info(target, arm7_9, tap);
689
690         arm926ejs->common_magic = ARM926EJS_COMMON_MAGIC;
691
692         arm7_9->post_debug_entry = arm926ejs_post_debug_entry;
693         arm7_9->pre_restore_context = arm926ejs_pre_restore_context;
694
695         arm926ejs->read_cp15 = arm926ejs_cp15_read;
696         arm926ejs->write_cp15 = arm926ejs_cp15_write;
697         arm926ejs->armv4_5_mmu.armv4_5_cache.ctype = -1;
698         arm926ejs->armv4_5_mmu.get_ttb = arm926ejs_get_ttb;
699         arm926ejs->armv4_5_mmu.read_memory = arm7_9_read_memory;
700         arm926ejs->armv4_5_mmu.write_memory = arm7_9_write_memory;
701         arm926ejs->armv4_5_mmu.disable_mmu_caches = arm926ejs_disable_mmu_caches;
702         arm926ejs->armv4_5_mmu.enable_mmu_caches = arm926ejs_enable_mmu_caches;
703         arm926ejs->armv4_5_mmu.has_tiny_pages = 1;
704         arm926ejs->armv4_5_mmu.mmu_enabled = 0;
705
706         arm7_9->examine_debug_reason = arm926ejs_examine_debug_reason;
707
708         /* The ARM926EJ-S implements the ARMv5TE architecture which
709          * has the BKPT instruction, so we don't have to use a watchpoint comparator
710          */
711         arm7_9->arm_bkpt = ARMV5_BKPT(0x0);
712         arm7_9->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
713
714         return ERROR_OK;
715 }
716
717 static int arm926ejs_target_create(struct target *target, Jim_Interp *interp)
718 {
719         struct arm926ejs_common *arm926ejs = calloc(1, sizeof(struct arm926ejs_common));
720
721         /* ARM9EJ-S core always reports 0x1 in Capture-IR */
722         target->tap->ir_capture_mask = 0x0f;
723
724         return arm926ejs_init_arch_info(target, arm926ejs, target->tap);
725 }
726
727 COMMAND_HANDLER(arm926ejs_handle_cache_info_command)
728 {
729         int retval;
730         struct target *target = get_current_target(CMD_CTX);
731         struct arm926ejs_common *arm926ejs = target_to_arm926(target);
732
733         retval = arm926ejs_verify_pointer(CMD_CTX, arm926ejs);
734         if (retval != ERROR_OK)
735                 return retval;
736
737         return armv4_5_handle_cache_info_command(CMD_CTX, &arm926ejs->armv4_5_mmu.armv4_5_cache);
738 }
739
740 static int arm926ejs_virt2phys(struct target *target, uint32_t virtual, uint32_t *physical)
741 {
742         uint32_t cb;
743         struct arm926ejs_common *arm926ejs = target_to_arm926(target);
744
745         uint32_t ret;
746         int retval = armv4_5_mmu_translate_va(target, &arm926ejs->armv4_5_mmu,
747                         virtual, &cb, &ret);
748         if (retval != ERROR_OK)
749                 return retval;
750         *physical = ret;
751         return ERROR_OK;
752 }
753
754 static int arm926ejs_mmu(struct target *target, int *enabled)
755 {
756         struct arm926ejs_common *arm926ejs = target_to_arm926(target);
757
758         if (target->state != TARGET_HALTED) {
759                 LOG_ERROR("Target not halted");
760                 return ERROR_TARGET_INVALID;
761         }
762         *enabled = arm926ejs->armv4_5_mmu.mmu_enabled;
763         return ERROR_OK;
764 }
765
766 static const struct command_registration arm926ejs_exec_command_handlers[] = {
767         {
768                 .name = "cache_info",
769                 .handler = arm926ejs_handle_cache_info_command,
770                 .mode = COMMAND_EXEC,
771                 .usage = "",
772                 .help = "display information about target caches",
773
774         },
775         COMMAND_REGISTRATION_DONE
776 };
777 const struct command_registration arm926ejs_command_handlers[] = {
778         {
779                 .chain = arm9tdmi_command_handlers,
780         },
781         {
782                 .name = "arm926ejs",
783                 .mode = COMMAND_ANY,
784                 .help = "arm926ejs command group",
785                 .usage = "",
786                 .chain = arm926ejs_exec_command_handlers,
787         },
788         COMMAND_REGISTRATION_DONE
789 };
790
791 /** Holds methods for ARM926 targets. */
792 struct target_type arm926ejs_target = {
793         .name = "arm926ejs",
794
795         .poll = arm7_9_poll,
796         .arch_state = arm926ejs_arch_state,
797
798         .target_request_data = arm7_9_target_request_data,
799
800         .halt = arm7_9_halt,
801         .resume = arm7_9_resume,
802         .step = arm7_9_step,
803
804         .assert_reset = arm7_9_assert_reset,
805         .deassert_reset = arm7_9_deassert_reset,
806         .soft_reset_halt = arm926ejs_soft_reset_halt,
807
808         .get_gdb_reg_list = arm_get_gdb_reg_list,
809
810         .read_memory = arm7_9_read_memory,
811         .write_memory = arm926ejs_write_memory,
812         .bulk_write_memory = arm7_9_bulk_write_memory,
813
814         .checksum_memory = arm_checksum_memory,
815         .blank_check_memory = arm_blank_check_memory,
816
817         .run_algorithm = armv4_5_run_algorithm,
818
819         .add_breakpoint = arm7_9_add_breakpoint,
820         .remove_breakpoint = arm7_9_remove_breakpoint,
821         .add_watchpoint = arm7_9_add_watchpoint,
822         .remove_watchpoint = arm7_9_remove_watchpoint,
823
824         .commands = arm926ejs_command_handlers,
825         .target_create = arm926ejs_target_create,
826         .init_target = arm9tdmi_init_target,
827         .examine = arm7_9_examine,
828         .check_reset = arm7_9_check_reset,
829         .virt2phys = arm926ejs_virt2phys,
830         .mmu = arm926ejs_mmu,
831
832         .read_phys_memory = arm926ejs_read_phys_memory,
833         .write_phys_memory = arm926ejs_write_phys_memory,
834 };