arm mmu: error propagation added for address translation
[openocd/dnglaze.git] / src / target / arm920t.c
blob317519607e3c051d9b3e5ef98fd7081d7c70cb10
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
24 #include "arm920t.h"
25 #include <helper/time_support.h>
26 #include "target_type.h"
27 #include "register.h"
28 #include "arm_opcodes.h"
32 * For information about the ARM920T, see ARM DDI 0151C especially
33 * Chapter 9 about debug support, which shows how to manipulate each
34 * of the different scan chains:
36 * 0 ... ARM920 signals, e.g. to rest of SOC (unused here)
37 * 1 ... debugging; watchpoint and breakpoint status, etc; also
38 * MMU and cache access in conjunction with scan chain 15
39 * 2 ... EmbeddedICE
40 * 3 ... external boundary scan (SoC-specific, unused here)
41 * 4 ... access to cache tag RAM
42 * 6 ... ETM9
43 * 15 ... access coprocessor 15, "physical" or "interpreted" modes
44 * "interpreted" works with a few actual MRC/MCR instructions
45 * "physical" provides register-like behaviors. Section 9.6.7
46 * covers these details.
48 * The ARM922T is similar, but with smaller caches (8K each, vs 16K).
51 #if 0
52 #define _DEBUG_INSTRUCTION_EXECUTION_
53 #endif
55 /* Table 9-8 shows scan chain 15 format during physical access mode, using a
56 * dedicated 6-bit address space (encoded in bits 33:38). Writes use one
57 * JTAG scan, while reads use two.
59 * Table 9-9 lists the thirteen registers which support physical access.
60 * ARM920T_CP15_PHYS_ADDR() constructs the 6-bit reg_addr parameter passed
61 * to arm920t_read_cp15_physical() and arm920t_write_cp15_physical().
63 * x == bit[38]
64 * y == bits[37:34]
65 * z == bit[33]
67 #define ARM920T_CP15_PHYS_ADDR(x, y, z) ((x << 5) | (y << 1) << (z))
69 /* Registers supporting physical Read access (from table 9-9) */
70 #define CP15PHYS_CACHETYPE ARM920T_CP15_PHYS_ADDR(0, 0x0, 1)
71 #define CP15PHYS_ICACHE_IDX ARM920T_CP15_PHYS_ADDR(1, 0xd, 1)
72 #define CP15PHYS_DCACHE_IDX ARM920T_CP15_PHYS_ADDR(1, 0xe, 1)
73 /* NOTE: several more registers support only physical read access */
75 /* Registers supporting physical Read/Write access (from table 9-9) */
76 #define CP15PHYS_CTRL ARM920T_CP15_PHYS_ADDR(0, 0x1, 0)
77 #define CP15PHYS_PID ARM920T_CP15_PHYS_ADDR(0, 0xd, 0)
78 #define CP15PHYS_TESTSTATE ARM920T_CP15_PHYS_ADDR(0, 0xf, 0)
79 #define CP15PHYS_ICACHE ARM920T_CP15_PHYS_ADDR(1, 0x1, 1)
80 #define CP15PHYS_DCACHE ARM920T_CP15_PHYS_ADDR(1, 0x2, 1)
82 static int arm920t_read_cp15_physical(struct target *target,
83 int reg_addr, uint32_t *value)
85 struct arm920t_common *arm920t = target_to_arm920(target);
86 struct arm_jtag *jtag_info;
87 struct scan_field fields[4];
88 uint8_t access_type_buf = 1;
89 uint8_t reg_addr_buf = reg_addr & 0x3f;
90 uint8_t nr_w_buf = 0;
92 jtag_info = &arm920t->arm7_9_common.jtag_info;
94 arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);
95 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_IDLE);
97 fields[0].num_bits = 1;
98 fields[0].out_value = &access_type_buf;
99 fields[0].in_value = NULL;
101 fields[1].num_bits = 32;
102 fields[1].out_value = NULL;
103 fields[1].in_value = NULL;
105 fields[2].num_bits = 6;
106 fields[2].out_value = &reg_addr_buf;
107 fields[2].in_value = NULL;
109 fields[3].num_bits = 1;
110 fields[3].out_value = &nr_w_buf;
111 fields[3].in_value = NULL;
113 jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
115 fields[1].in_value = (uint8_t *)value;
117 jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
119 jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)value);
121 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
122 jtag_execute_queue();
123 LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value);
124 #endif
126 return ERROR_OK;
129 static int arm920t_write_cp15_physical(struct target *target,
130 int reg_addr, uint32_t value)
132 struct arm920t_common *arm920t = target_to_arm920(target);
133 struct arm_jtag *jtag_info;
134 struct scan_field fields[4];
135 uint8_t access_type_buf = 1;
136 uint8_t reg_addr_buf = reg_addr & 0x3f;
137 uint8_t nr_w_buf = 1;
138 uint8_t value_buf[4];
140 jtag_info = &arm920t->arm7_9_common.jtag_info;
142 buf_set_u32(value_buf, 0, 32, value);
144 arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);
145 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_IDLE);
147 fields[0].num_bits = 1;
148 fields[0].out_value = &access_type_buf;
149 fields[0].in_value = NULL;
151 fields[1].num_bits = 32;
152 fields[1].out_value = value_buf;
153 fields[1].in_value = NULL;
155 fields[2].num_bits = 6;
156 fields[2].out_value = &reg_addr_buf;
157 fields[2].in_value = NULL;
159 fields[3].num_bits = 1;
160 fields[3].out_value = &nr_w_buf;
161 fields[3].in_value = NULL;
163 jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
165 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
166 LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, value);
167 #endif
169 return ERROR_OK;
172 /* See table 9-10 for scan chain 15 format during interpreted access mode.
173 * If the TESTSTATE register is set for interpreted access, certain CP15
174 * MRC and MCR instructions may be executed through scan chain 15.
176 * Tables 9-11, 9-12, and 9-13 show which MRC and MCR instructions can be
177 * executed using scan chain 15 interpreted mode.
179 static int arm920t_execute_cp15(struct target *target, uint32_t cp15_opcode,
180 uint32_t arm_opcode)
182 int retval;
183 struct arm920t_common *arm920t = target_to_arm920(target);
184 struct arm_jtag *jtag_info;
185 struct scan_field fields[4];
186 uint8_t access_type_buf = 0; /* interpreted access */
187 uint8_t reg_addr_buf = 0x0;
188 uint8_t nr_w_buf = 0;
189 uint8_t cp15_opcode_buf[4];
191 jtag_info = &arm920t->arm7_9_common.jtag_info;
193 arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);
194 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_IDLE);
196 buf_set_u32(cp15_opcode_buf, 0, 32, cp15_opcode);
198 fields[0].num_bits = 1;
199 fields[0].out_value = &access_type_buf;
200 fields[0].in_value = NULL;
202 fields[1].num_bits = 32;
203 fields[1].out_value = cp15_opcode_buf;
204 fields[1].in_value = NULL;
206 fields[2].num_bits = 6;
207 fields[2].out_value = &reg_addr_buf;
208 fields[2].in_value = NULL;
210 fields[3].num_bits = 1;
211 fields[3].out_value = &nr_w_buf;
212 fields[3].in_value = NULL;
214 jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
216 arm9tdmi_clock_out(jtag_info, arm_opcode, 0, NULL, 0);
217 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
218 retval = arm7_9_execute_sys_speed(target);
219 if (retval != ERROR_OK)
220 return retval;
222 if ((retval = jtag_execute_queue()) != ERROR_OK)
224 LOG_ERROR("failed executing JTAG queue");
225 return retval;
228 return ERROR_OK;
231 static int arm920t_read_cp15_interpreted(struct target *target,
232 uint32_t cp15_opcode, uint32_t address, uint32_t *value)
234 struct arm *armv4_5 = target_to_arm(target);
235 uint32_t* regs_p[1];
236 uint32_t regs[2];
237 uint32_t cp15c15 = 0x0;
238 struct reg *r = armv4_5->core_cache->reg_list;
240 /* load address into R1 */
241 regs[1] = address;
242 arm9tdmi_write_core_regs(target, 0x2, regs);
244 /* read-modify-write CP15 test state register
245 * to enable interpreted access mode */
246 arm920t_read_cp15_physical(target, CP15PHYS_TESTSTATE, &cp15c15);
247 jtag_execute_queue();
248 cp15c15 |= 1; /* set interpret mode */
249 arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);
251 /* execute CP15 instruction and ARM load (reading from coprocessor) */
252 arm920t_execute_cp15(target, cp15_opcode, ARMV4_5_LDR(0, 1));
254 /* disable interpreted access mode */
255 cp15c15 &= ~1U; /* clear interpret mode */
256 arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);
258 /* retrieve value from R0 */
259 regs_p[0] = value;
260 arm9tdmi_read_core_regs(target, 0x1, regs_p);
261 jtag_execute_queue();
263 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
264 LOG_DEBUG("cp15_opcode: %8.8x, address: %8.8x, value: %8.8x",
265 cp15_opcode, address, *value);
266 #endif
268 if (!is_arm_mode(armv4_5->core_mode))
269 return ERROR_FAIL;
271 r[0].dirty = 1;
272 r[1].dirty = 1;
274 return ERROR_OK;
277 static
278 int arm920t_write_cp15_interpreted(struct target *target,
279 uint32_t cp15_opcode, uint32_t value, uint32_t address)
281 uint32_t cp15c15 = 0x0;
282 struct arm *armv4_5 = target_to_arm(target);
283 uint32_t regs[2];
284 struct reg *r = armv4_5->core_cache->reg_list;
286 /* load value, address into R0, R1 */
287 regs[0] = value;
288 regs[1] = address;
289 arm9tdmi_write_core_regs(target, 0x3, regs);
291 /* read-modify-write CP15 test state register
292 * to enable interpreted access mode */
293 arm920t_read_cp15_physical(target, CP15PHYS_TESTSTATE, &cp15c15);
294 jtag_execute_queue();
295 cp15c15 |= 1; /* set interpret mode */
296 arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);
298 /* execute CP15 instruction and ARM store (writing to coprocessor) */
299 arm920t_execute_cp15(target, cp15_opcode, ARMV4_5_STR(0, 1));
301 /* disable interpreted access mode */
302 cp15c15 &= ~1U; /* set interpret mode */
303 arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);
305 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
306 LOG_DEBUG("cp15_opcode: %8.8x, value: %8.8x, address: %8.8x",
307 cp15_opcode, value, address);
308 #endif
310 if (!is_arm_mode(armv4_5->core_mode))
311 return ERROR_FAIL;
313 r[0].dirty = 1;
314 r[1].dirty = 1;
316 return ERROR_OK;
319 // EXPORTED to FA256
320 uint32_t arm920t_get_ttb(struct target *target)
322 int retval;
323 uint32_t ttb = 0x0;
325 if ((retval = arm920t_read_cp15_interpreted(target,
326 /* FIXME use opcode macro */
327 0xeebf0f51, 0x0, &ttb)) != ERROR_OK)
328 return retval;
330 return ttb;
333 // EXPORTED to FA256
334 void arm920t_disable_mmu_caches(struct target *target, int mmu,
335 int d_u_cache, int i_cache)
337 uint32_t cp15_control;
339 /* read cp15 control register */
340 arm920t_read_cp15_physical(target, CP15PHYS_CTRL, &cp15_control);
341 jtag_execute_queue();
343 if (mmu)
344 cp15_control &= ~0x1U;
346 if (d_u_cache)
347 cp15_control &= ~0x4U;
349 if (i_cache)
350 cp15_control &= ~0x1000U;
352 arm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_control);
355 // EXPORTED to FA256
356 void arm920t_enable_mmu_caches(struct target *target, int mmu,
357 int d_u_cache, int i_cache)
359 uint32_t cp15_control;
361 /* read cp15 control register */
362 arm920t_read_cp15_physical(target, CP15PHYS_CTRL, &cp15_control);
363 jtag_execute_queue();
365 if (mmu)
366 cp15_control |= 0x1U;
368 if (d_u_cache)
369 cp15_control |= 0x4U;
371 if (i_cache)
372 cp15_control |= 0x1000U;
374 arm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_control);
377 // EXPORTED to FA256
378 void arm920t_post_debug_entry(struct target *target)
380 uint32_t cp15c15;
381 struct arm920t_common *arm920t = target_to_arm920(target);
383 /* examine cp15 control reg */
384 arm920t_read_cp15_physical(target,
385 CP15PHYS_CTRL, &arm920t->cp15_control_reg);
386 jtag_execute_queue();
387 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32, arm920t->cp15_control_reg);
389 if (arm920t->armv4_5_mmu.armv4_5_cache.ctype == -1)
391 uint32_t cache_type_reg;
392 /* identify caches */
393 arm920t_read_cp15_physical(target,
394 CP15PHYS_CACHETYPE, &cache_type_reg);
395 jtag_execute_queue();
396 armv4_5_identify_cache(cache_type_reg,
397 &arm920t->armv4_5_mmu.armv4_5_cache);
400 arm920t->armv4_5_mmu.mmu_enabled =
401 (arm920t->cp15_control_reg & 0x1U) ? 1 : 0;
402 arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled =
403 (arm920t->cp15_control_reg & 0x4U) ? 1 : 0;
404 arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled =
405 (arm920t->cp15_control_reg & 0x1000U) ? 1 : 0;
407 /* save i/d fault status and address register */
408 /* FIXME use opcode macros */
409 arm920t_read_cp15_interpreted(target, 0xee150f10, 0x0, &arm920t->d_fsr);
410 arm920t_read_cp15_interpreted(target, 0xee150f30, 0x0, &arm920t->i_fsr);
411 arm920t_read_cp15_interpreted(target, 0xee160f10, 0x0, &arm920t->d_far);
412 arm920t_read_cp15_interpreted(target, 0xee160f30, 0x0, &arm920t->i_far);
414 LOG_DEBUG("D FSR: 0x%8.8" PRIx32 ", D FAR: 0x%8.8" PRIx32
415 ", I FSR: 0x%8.8" PRIx32 ", I FAR: 0x%8.8" PRIx32,
416 arm920t->d_fsr, arm920t->d_far, arm920t->i_fsr, arm920t->i_far);
418 if (arm920t->preserve_cache)
420 /* read-modify-write CP15 test state register
421 * to disable I/D-cache linefills */
422 arm920t_read_cp15_physical(target,
423 CP15PHYS_TESTSTATE, &cp15c15);
424 jtag_execute_queue();
425 cp15c15 |= 0x600;
426 arm920t_write_cp15_physical(target,
427 CP15PHYS_TESTSTATE, cp15c15);
431 // EXPORTED to FA256
432 void arm920t_pre_restore_context(struct target *target)
434 uint32_t cp15c15;
435 struct arm920t_common *arm920t = target_to_arm920(target);
437 /* restore i/d fault status and address register */
438 arm920t_write_cp15_interpreted(target, 0xee050f10, arm920t->d_fsr, 0x0);
439 arm920t_write_cp15_interpreted(target, 0xee050f30, arm920t->i_fsr, 0x0);
440 arm920t_write_cp15_interpreted(target, 0xee060f10, arm920t->d_far, 0x0);
441 arm920t_write_cp15_interpreted(target, 0xee060f30, arm920t->i_far, 0x0);
443 /* read-modify-write CP15 test state register
444 * to reenable I/D-cache linefills */
445 if (arm920t->preserve_cache)
447 arm920t_read_cp15_physical(target,
448 CP15PHYS_TESTSTATE, &cp15c15);
449 jtag_execute_queue();
450 cp15c15 &= ~0x600U;
451 arm920t_write_cp15_physical(target,
452 CP15PHYS_TESTSTATE, cp15c15);
456 static const char arm920_not[] = "target is not an ARM920";
458 static int arm920t_verify_pointer(struct command_context *cmd_ctx,
459 struct arm920t_common *arm920t)
461 if (arm920t->common_magic != ARM920T_COMMON_MAGIC) {
462 command_print(cmd_ctx, arm920_not);
463 return ERROR_TARGET_INVALID;
466 return ERROR_OK;
469 /** Logs summary of ARM920 state for a halted target. */
470 int arm920t_arch_state(struct target *target)
472 static const char *state[] =
474 "disabled", "enabled"
477 struct arm920t_common *arm920t = target_to_arm920(target);
478 struct arm *armv4_5;
480 if (arm920t->common_magic != ARM920T_COMMON_MAGIC)
482 LOG_ERROR("BUG: %s", arm920_not);
483 return ERROR_TARGET_INVALID;
486 armv4_5 = &arm920t->arm7_9_common.armv4_5_common;
488 arm_arch_state(target);
489 LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
490 state[arm920t->armv4_5_mmu.mmu_enabled],
491 state[arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],
492 state[arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled]);
494 return ERROR_OK;
497 static int arm920_mmu(struct target *target, int *enabled)
499 if (target->state != TARGET_HALTED) {
500 LOG_ERROR("%s: target not halted", __func__);
501 return ERROR_TARGET_INVALID;
504 *enabled = target_to_arm920(target)->armv4_5_mmu.mmu_enabled;
505 return ERROR_OK;
508 static int arm920_virt2phys(struct target *target,
509 uint32_t virt, uint32_t *phys)
511 int type;
512 uint32_t cb;
513 int domain;
514 uint32_t ap;
515 struct arm920t_common *arm920t = target_to_arm920(target);
517 uint32_t ret;
518 int retval = armv4_5_mmu_translate_va(target,
519 &arm920t->armv4_5_mmu, virt, &type, &cb, &domain, &ap, &ret);
520 if (retval != ERROR_OK)
521 return retval;
522 if (type == -1)
524 return ret;
526 *phys = ret;
527 return ERROR_OK;
530 /** Reads a buffer, in the specified word size, with current MMU settings. */
531 int arm920t_read_memory(struct target *target, uint32_t address,
532 uint32_t size, uint32_t count, uint8_t *buffer)
534 int retval;
536 retval = arm7_9_read_memory(target, address, size, count, buffer);
538 return retval;
542 static int arm920t_read_phys_memory(struct target *target,
543 uint32_t address, uint32_t size,
544 uint32_t count, uint8_t *buffer)
546 struct arm920t_common *arm920t = target_to_arm920(target);
548 return armv4_5_mmu_read_physical(target, &arm920t->armv4_5_mmu,
549 address, size, count, buffer);
552 static int arm920t_write_phys_memory(struct target *target,
553 uint32_t address, uint32_t size,
554 uint32_t count, uint8_t *buffer)
556 struct arm920t_common *arm920t = target_to_arm920(target);
558 return armv4_5_mmu_write_physical(target, &arm920t->armv4_5_mmu,
559 address, size, count, buffer);
563 /** Writes a buffer, in the specified word size, with current MMU settings. */
564 int arm920t_write_memory(struct target *target, uint32_t address,
565 uint32_t size, uint32_t count, uint8_t *buffer)
567 int retval;
568 const uint32_t cache_mask = ~0x1f; /* cache line size : 32 byte */
569 struct arm920t_common *arm920t = target_to_arm920(target);
571 /* FIX!!!! this should be cleaned up and made much more general. The
572 * plan is to write up and test on arm920t specifically and
573 * then generalize and clean up afterwards.
575 * Also it should be moved to the callbacks that handle breakpoints
576 * specifically and not the generic memory write fn's. See XScale code.
578 if (arm920t->armv4_5_mmu.mmu_enabled && (count == 1) &&
579 ((size==2) || (size==4)))
581 /* special case the handling of single word writes to
582 * bypass MMU, to allow implementation of breakpoints
583 * in memory marked read only
584 * by MMU
586 int type;
587 uint32_t cb;
588 int domain;
589 uint32_t ap;
590 uint32_t pa;
593 * We need physical address and cb
595 int retval = armv4_5_mmu_translate_va(target, &arm920t->armv4_5_mmu,
596 address, &type, &cb, &domain, &ap, &pa);
597 if (retval != ERROR_OK)
598 return retval;
599 if (type == -1)
600 return pa;
602 if (arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled)
604 if (cb & 0x1)
606 LOG_DEBUG("D-Cache buffered, "
607 "drain write buffer");
609 * Buffered ?
610 * Drain write buffer - MCR p15,0,Rd,c7,c10,4
613 retval = arm920t_write_cp15_interpreted(target,
614 ARMV4_5_MCR(15, 0, 0, 7, 10, 4),
615 0x0, 0);
616 if (retval != ERROR_OK)
617 return retval;
620 if (cb == 0x3)
623 * Write back memory ? -> clean cache
625 * There is no way to clean cache lines using
626 * cp15 scan chain, so copy the full cache
627 * line from cache to physical memory.
629 uint8_t data[32];
631 LOG_DEBUG("D-Cache in 'write back' mode, "
632 "flush cache line");
634 retval = target_read_memory(target,
635 address & cache_mask, 1,
636 sizeof(data), &data[0]);
637 if (retval != ERROR_OK)
638 return retval;
640 retval = armv4_5_mmu_write_physical(target,
641 &arm920t->armv4_5_mmu,
642 pa & cache_mask, 1,
643 sizeof(data), &data[0]);
644 if (retval != ERROR_OK)
645 return retval;
648 /* Cached ? */
649 if (cb & 0x2)
652 * Cached ? -> Invalidate data cache using MVA
654 * MCR p15,0,Rd,c7,c6,1
656 LOG_DEBUG("D-Cache enabled, "
657 "invalidate cache line");
659 retval = arm920t_write_cp15_interpreted(target,
660 ARMV4_5_MCR(15, 0, 0, 7, 6, 1), 0x0,
661 address & cache_mask);
662 if (retval != ERROR_OK)
663 return retval;
667 /* write directly to physical memory,
668 * bypassing any read only MMU bits, etc.
670 retval = armv4_5_mmu_write_physical(target,
671 &arm920t->armv4_5_mmu, pa, size,
672 count, buffer);
673 if (retval != ERROR_OK)
674 return retval;
675 } else
677 if ((retval = arm7_9_write_memory(target, address,
678 size, count, buffer)) != ERROR_OK)
679 return retval;
682 /* If ICache is enabled, we have to invalidate affected ICache lines
683 * the DCache is forced to write-through,
684 * so we don't have to clean it here
686 if (arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled)
688 if (count <= 1)
690 /* invalidate ICache single entry with MVA
691 * mcr 15, 0, r0, cr7, cr5, {1}
693 LOG_DEBUG("I-Cache enabled, "
694 "invalidating affected I-Cache line");
695 retval = arm920t_write_cp15_interpreted(target,
696 ARMV4_5_MCR(15, 0, 0, 7, 5, 1),
697 0x0, address & cache_mask);
698 if (retval != ERROR_OK)
699 return retval;
701 else
703 /* invalidate ICache
704 * mcr 15, 0, r0, cr7, cr5, {0}
706 retval = arm920t_write_cp15_interpreted(target,
707 ARMV4_5_MCR(15, 0, 0, 7, 5, 0),
708 0x0, 0x0);
709 if (retval != ERROR_OK)
710 return retval;
714 return retval;
717 // EXPORTED to FA256
718 int arm920t_soft_reset_halt(struct target *target)
720 int retval = ERROR_OK;
721 struct arm920t_common *arm920t = target_to_arm920(target);
722 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
723 struct arm *armv4_5 = &arm7_9->armv4_5_common;
724 struct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
726 if ((retval = target_halt(target)) != ERROR_OK)
728 return retval;
731 long long then = timeval_ms();
732 int timeout;
733 while (!(timeout = ((timeval_ms()-then) > 1000)))
735 if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1)
736 == 0)
738 embeddedice_read_reg(dbg_stat);
739 if ((retval = jtag_execute_queue()) != ERROR_OK)
741 return retval;
743 } else
745 break;
747 if (debug_level >= 3)
749 /* do not eat all CPU, time out after 1 se*/
750 alive_sleep(100);
751 } else
753 keep_alive();
756 if (timeout)
758 LOG_ERROR("Failed to halt CPU after 1 sec");
759 return ERROR_TARGET_TIMEOUT;
762 target->state = TARGET_HALTED;
764 /* SVC, ARM state, IRQ and FIQ disabled */
765 uint32_t cpsr;
767 cpsr = buf_get_u32(armv4_5->cpsr->value, 0, 32);
768 cpsr &= ~0xff;
769 cpsr |= 0xd3;
770 arm_set_cpsr(armv4_5, cpsr);
771 armv4_5->cpsr->dirty = 1;
773 /* start fetching from 0x0 */
774 buf_set_u32(armv4_5->pc->value, 0, 32, 0x0);
775 armv4_5->pc->dirty = 1;
776 armv4_5->pc->valid = 1;
778 arm920t_disable_mmu_caches(target, 1, 1, 1);
779 arm920t->armv4_5_mmu.mmu_enabled = 0;
780 arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;
781 arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;
783 return target_call_event_callbacks(target, TARGET_EVENT_HALTED);
786 /* FIXME remove forward decls */
787 static int arm920t_mrc(struct target *target, int cpnum,
788 uint32_t op1, uint32_t op2,
789 uint32_t CRn, uint32_t CRm,
790 uint32_t *value);
791 static int arm920t_mcr(struct target *target, int cpnum,
792 uint32_t op1, uint32_t op2,
793 uint32_t CRn, uint32_t CRm,
794 uint32_t value);
796 static int arm920t_init_arch_info(struct target *target,
797 struct arm920t_common *arm920t, struct jtag_tap *tap)
799 struct arm7_9_common *arm7_9 = &arm920t->arm7_9_common;
801 arm7_9->armv4_5_common.mrc = arm920t_mrc;
802 arm7_9->armv4_5_common.mcr = arm920t_mcr;
804 /* initialize arm7/arm9 specific info (including armv4_5) */
805 arm9tdmi_init_arch_info(target, arm7_9, tap);
807 arm920t->common_magic = ARM920T_COMMON_MAGIC;
809 arm7_9->post_debug_entry = arm920t_post_debug_entry;
810 arm7_9->pre_restore_context = arm920t_pre_restore_context;
812 arm920t->armv4_5_mmu.armv4_5_cache.ctype = -1;
813 arm920t->armv4_5_mmu.get_ttb = arm920t_get_ttb;
814 arm920t->armv4_5_mmu.read_memory = arm7_9_read_memory;
815 arm920t->armv4_5_mmu.write_memory = arm7_9_write_memory;
816 arm920t->armv4_5_mmu.disable_mmu_caches = arm920t_disable_mmu_caches;
817 arm920t->armv4_5_mmu.enable_mmu_caches = arm920t_enable_mmu_caches;
818 arm920t->armv4_5_mmu.has_tiny_pages = 1;
819 arm920t->armv4_5_mmu.mmu_enabled = 0;
821 /* disabling linefills leads to lockups, so keep them enabled for now
822 * this doesn't affect correctness, but might affect timing issues, if
823 * important data is evicted from the cache during the debug session
824 * */
825 arm920t->preserve_cache = 0;
827 /* override hw single-step capability from ARM9TDMI */
828 arm7_9->has_single_step = 1;
830 return ERROR_OK;
833 static int arm920t_target_create(struct target *target, Jim_Interp *interp)
835 struct arm920t_common *arm920t;
837 arm920t = calloc(1,sizeof(struct arm920t_common));
838 return arm920t_init_arch_info(target, arm920t, target->tap);
841 COMMAND_HANDLER(arm920t_handle_read_cache_command)
843 int retval = ERROR_OK;
844 struct target *target = get_current_target(CMD_CTX);
845 struct arm920t_common *arm920t = target_to_arm920(target);
846 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
847 struct arm *armv4_5 = &arm7_9->armv4_5_common;
848 uint32_t cp15c15;
849 uint32_t cp15_ctrl, cp15_ctrl_saved;
850 uint32_t regs[16];
851 uint32_t *regs_p[16];
852 uint32_t C15_C_D_Ind, C15_C_I_Ind;
853 int i;
854 FILE *output;
855 struct arm920t_cache_line d_cache[8][64], i_cache[8][64];
856 int segment, index;
857 struct reg *r;
859 retval = arm920t_verify_pointer(CMD_CTX, arm920t);
860 if (retval != ERROR_OK)
861 return retval;
863 if (CMD_ARGC != 1)
865 command_print(CMD_CTX, "usage: arm920t read_cache <filename>");
866 return ERROR_OK;
869 if ((output = fopen(CMD_ARGV[0], "w")) == NULL)
871 LOG_DEBUG("error opening cache content file");
872 return ERROR_OK;
875 for (i = 0; i < 16; i++)
876 regs_p[i] = &regs[i];
878 /* disable MMU and Caches */
879 arm920t_read_cp15_physical(target, CP15PHYS_CTRL, &cp15_ctrl);
880 if ((retval = jtag_execute_queue()) != ERROR_OK)
882 return retval;
884 cp15_ctrl_saved = cp15_ctrl;
885 cp15_ctrl &= ~(ARMV4_5_MMU_ENABLED
886 | ARMV4_5_D_U_CACHE_ENABLED | ARMV4_5_I_CACHE_ENABLED);
887 arm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_ctrl);
889 /* read CP15 test state register */
890 arm920t_read_cp15_physical(target, CP15PHYS_TESTSTATE, &cp15c15);
891 jtag_execute_queue();
893 /* read DCache content */
894 fprintf(output, "DCache:\n");
896 /* go through segments 0 to nsets (8 on ARM920T, 4 on ARM922T) */
897 for (segment = 0;
898 segment < arm920t->armv4_5_mmu.armv4_5_cache.d_u_size.nsets;
899 segment++)
901 fprintf(output, "\nsegment: %i\n----------", segment);
903 /* Ra: r0 = SBZ(31:8):segment(7:5):SBZ(4:0) */
904 regs[0] = 0x0 | (segment << 5);
905 arm9tdmi_write_core_regs(target, 0x1, regs);
907 /* set interpret mode */
908 cp15c15 |= 0x1;
909 arm920t_write_cp15_physical(target,
910 CP15PHYS_TESTSTATE, cp15c15);
912 /* D CAM Read, loads current victim into C15.C.D.Ind */
913 arm920t_execute_cp15(target,
914 ARMV4_5_MCR(15,2,0,15,6,2), ARMV4_5_LDR(1, 0));
916 /* read current victim */
917 arm920t_read_cp15_physical(target,
918 CP15PHYS_DCACHE_IDX, &C15_C_D_Ind);
920 /* clear interpret mode */
921 cp15c15 &= ~0x1;
922 arm920t_write_cp15_physical(target,
923 CP15PHYS_TESTSTATE, cp15c15);
925 for (index = 0; index < 64; index++)
927 /* Ra:
928 * r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0)
930 regs[0] = 0x0 | (segment << 5) | (index << 26);
931 arm9tdmi_write_core_regs(target, 0x1, regs);
933 /* set interpret mode */
934 cp15c15 |= 0x1;
935 arm920t_write_cp15_physical(target,
936 CP15PHYS_TESTSTATE, cp15c15);
938 /* Write DCache victim */
939 arm920t_execute_cp15(target,
940 ARMV4_5_MCR(15,0,0,9,1,0), ARMV4_5_LDR(1, 0));
942 /* Read D RAM */
943 arm920t_execute_cp15(target,
944 ARMV4_5_MCR(15,2,0,15,10,2),
945 ARMV4_5_LDMIA(0, 0x1fe, 0, 0));
947 /* Read D CAM */
948 arm920t_execute_cp15(target,
949 ARMV4_5_MCR(15,2,0,15,6,2),
950 ARMV4_5_LDR(9, 0));
952 /* clear interpret mode */
953 cp15c15 &= ~0x1;
954 arm920t_write_cp15_physical(target,
955 CP15PHYS_TESTSTATE, cp15c15);
957 /* read D RAM and CAM content */
958 arm9tdmi_read_core_regs(target, 0x3fe, regs_p);
959 if ((retval = jtag_execute_queue()) != ERROR_OK)
961 return retval;
964 d_cache[segment][index].cam = regs[9];
966 /* mask LFSR[6] */
967 regs[9] &= 0xfffffffe;
968 fprintf(output, "\nsegment: %i, index: %i, CAM: 0x%8.8"
969 PRIx32 ", content (%s):\n",
970 segment, index, regs[9],
971 (regs[9] & 0x10) ? "valid" : "invalid");
973 for (i = 1; i < 9; i++)
975 d_cache[segment][index].data[i] = regs[i];
976 fprintf(output, "%i: 0x%8.8" PRIx32 "\n",
977 i-1, regs[i]);
982 /* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */
983 regs[0] = 0x0 | (segment << 5) | (C15_C_D_Ind << 26);
984 arm9tdmi_write_core_regs(target, 0x1, regs);
986 /* set interpret mode */
987 cp15c15 |= 0x1;
988 arm920t_write_cp15_physical(target,
989 CP15PHYS_TESTSTATE, cp15c15);
991 /* Write DCache victim */
992 arm920t_execute_cp15(target,
993 ARMV4_5_MCR(15,0,0,9,1,0), ARMV4_5_LDR(1, 0));
995 /* clear interpret mode */
996 cp15c15 &= ~0x1;
997 arm920t_write_cp15_physical(target,
998 CP15PHYS_TESTSTATE, cp15c15);
1001 /* read ICache content */
1002 fprintf(output, "ICache:\n");
1004 /* go through segments 0 to nsets (8 on ARM920T, 4 on ARM922T) */
1005 for (segment = 0;
1006 segment < arm920t->armv4_5_mmu.armv4_5_cache.d_u_size.nsets;
1007 segment++)
1009 fprintf(output, "segment: %i\n----------", segment);
1011 /* Ra: r0 = SBZ(31:8):segment(7:5):SBZ(4:0) */
1012 regs[0] = 0x0 | (segment << 5);
1013 arm9tdmi_write_core_regs(target, 0x1, regs);
1015 /* set interpret mode */
1016 cp15c15 |= 0x1;
1017 arm920t_write_cp15_physical(target,
1018 CP15PHYS_TESTSTATE, cp15c15);
1020 /* I CAM Read, loads current victim into C15.C.I.Ind */
1021 arm920t_execute_cp15(target,
1022 ARMV4_5_MCR(15,2,0,15,5,2), ARMV4_5_LDR(1, 0));
1024 /* read current victim */
1025 arm920t_read_cp15_physical(target, CP15PHYS_ICACHE_IDX,
1026 &C15_C_I_Ind);
1028 /* clear interpret mode */
1029 cp15c15 &= ~0x1;
1030 arm920t_write_cp15_physical(target,
1031 CP15PHYS_TESTSTATE, cp15c15);
1033 for (index = 0; index < 64; index++)
1035 /* Ra:
1036 * r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0)
1038 regs[0] = 0x0 | (segment << 5) | (index << 26);
1039 arm9tdmi_write_core_regs(target, 0x1, regs);
1041 /* set interpret mode */
1042 cp15c15 |= 0x1;
1043 arm920t_write_cp15_physical(target,
1044 CP15PHYS_TESTSTATE, cp15c15);
1046 /* Write ICache victim */
1047 arm920t_execute_cp15(target,
1048 ARMV4_5_MCR(15,0,0,9,1,1), ARMV4_5_LDR(1, 0));
1050 /* Read I RAM */
1051 arm920t_execute_cp15(target,
1052 ARMV4_5_MCR(15,2,0,15,9,2),
1053 ARMV4_5_LDMIA(0, 0x1fe, 0, 0));
1055 /* Read I CAM */
1056 arm920t_execute_cp15(target,
1057 ARMV4_5_MCR(15,2,0,15,5,2),
1058 ARMV4_5_LDR(9, 0));
1060 /* clear interpret mode */
1061 cp15c15 &= ~0x1;
1062 arm920t_write_cp15_physical(target,
1063 CP15PHYS_TESTSTATE, cp15c15);
1065 /* read I RAM and CAM content */
1066 arm9tdmi_read_core_regs(target, 0x3fe, regs_p);
1067 if ((retval = jtag_execute_queue()) != ERROR_OK)
1069 return retval;
1072 i_cache[segment][index].cam = regs[9];
1074 /* mask LFSR[6] */
1075 regs[9] &= 0xfffffffe;
1076 fprintf(output, "\nsegment: %i, index: %i, "
1077 "CAM: 0x%8.8" PRIx32 ", content (%s):\n",
1078 segment, index, regs[9],
1079 (regs[9] & 0x10) ? "valid" : "invalid");
1081 for (i = 1; i < 9; i++)
1083 i_cache[segment][index].data[i] = regs[i];
1084 fprintf(output, "%i: 0x%8.8" PRIx32 "\n",
1085 i-1, regs[i]);
1089 /* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */
1090 regs[0] = 0x0 | (segment << 5) | (C15_C_D_Ind << 26);
1091 arm9tdmi_write_core_regs(target, 0x1, regs);
1093 /* set interpret mode */
1094 cp15c15 |= 0x1;
1095 arm920t_write_cp15_physical(target,
1096 CP15PHYS_TESTSTATE, cp15c15);
1098 /* Write ICache victim */
1099 arm920t_execute_cp15(target,
1100 ARMV4_5_MCR(15,0,0,9,1,1), ARMV4_5_LDR(1, 0));
1102 /* clear interpret mode */
1103 cp15c15 &= ~0x1;
1104 arm920t_write_cp15_physical(target,
1105 CP15PHYS_TESTSTATE, cp15c15);
1108 /* restore CP15 MMU and Cache settings */
1109 arm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_ctrl_saved);
1111 command_print(CMD_CTX, "cache content successfully output to %s",
1112 CMD_ARGV[0]);
1114 fclose(output);
1116 if (!is_arm_mode(armv4_5->core_mode))
1117 return ERROR_FAIL;
1119 /* force writeback of the valid data */
1120 r = armv4_5->core_cache->reg_list;
1121 r[0].dirty = r[0].valid;
1122 r[1].dirty = r[1].valid;
1123 r[2].dirty = r[2].valid;
1124 r[3].dirty = r[3].valid;
1125 r[4].dirty = r[4].valid;
1126 r[5].dirty = r[5].valid;
1127 r[6].dirty = r[6].valid;
1128 r[7].dirty = r[7].valid;
1130 r = arm_reg_current(armv4_5, 8);
1131 r->dirty = r->valid;
1133 r = arm_reg_current(armv4_5, 9);
1134 r->dirty = r->valid;
1136 return ERROR_OK;
1139 COMMAND_HANDLER(arm920t_handle_read_mmu_command)
1141 int retval = ERROR_OK;
1142 struct target *target = get_current_target(CMD_CTX);
1143 struct arm920t_common *arm920t = target_to_arm920(target);
1144 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
1145 struct arm *armv4_5 = &arm7_9->armv4_5_common;
1146 uint32_t cp15c15;
1147 uint32_t cp15_ctrl, cp15_ctrl_saved;
1148 uint32_t regs[16];
1149 uint32_t *regs_p[16];
1150 int i;
1151 FILE *output;
1152 uint32_t Dlockdown, Ilockdown;
1153 struct arm920t_tlb_entry d_tlb[64], i_tlb[64];
1154 int victim;
1155 struct reg *r;
1157 retval = arm920t_verify_pointer(CMD_CTX, arm920t);
1158 if (retval != ERROR_OK)
1159 return retval;
1161 if (CMD_ARGC != 1)
1163 command_print(CMD_CTX, "usage: arm920t read_mmu <filename>");
1164 return ERROR_OK;
1167 if ((output = fopen(CMD_ARGV[0], "w")) == NULL)
1169 LOG_DEBUG("error opening mmu content file");
1170 return ERROR_OK;
1173 for (i = 0; i < 16; i++)
1174 regs_p[i] = &regs[i];
1176 /* disable MMU and Caches */
1177 arm920t_read_cp15_physical(target, CP15PHYS_CTRL, &cp15_ctrl);
1178 if ((retval = jtag_execute_queue()) != ERROR_OK)
1180 return retval;
1182 cp15_ctrl_saved = cp15_ctrl;
1183 cp15_ctrl &= ~(ARMV4_5_MMU_ENABLED
1184 | ARMV4_5_D_U_CACHE_ENABLED | ARMV4_5_I_CACHE_ENABLED);
1185 arm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_ctrl);
1187 /* read CP15 test state register */
1188 arm920t_read_cp15_physical(target, CP15PHYS_TESTSTATE, &cp15c15);
1189 if ((retval = jtag_execute_queue()) != ERROR_OK)
1191 return retval;
1194 /* prepare reading D TLB content
1195 * */
1197 /* set interpret mode */
1198 cp15c15 |= 0x1;
1199 arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);
1201 /* Read D TLB lockdown */
1202 arm920t_execute_cp15(target,
1203 ARMV4_5_MRC(15,0,0,10,0,0), ARMV4_5_LDR(1, 0));
1205 /* clear interpret mode */
1206 cp15c15 &= ~0x1;
1207 arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);
1209 /* read D TLB lockdown stored to r1 */
1210 arm9tdmi_read_core_regs(target, 0x2, regs_p);
1211 if ((retval = jtag_execute_queue()) != ERROR_OK)
1213 return retval;
1215 Dlockdown = regs[1];
1217 for (victim = 0; victim < 64; victim += 8)
1219 /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
1220 * base remains unchanged, victim goes through entries 0 to 63
1222 regs[1] = (Dlockdown & 0xfc000000) | (victim << 20);
1223 arm9tdmi_write_core_regs(target, 0x2, regs);
1225 /* set interpret mode */
1226 cp15c15 |= 0x1;
1227 arm920t_write_cp15_physical(target,
1228 CP15PHYS_TESTSTATE, cp15c15);
1230 /* Write D TLB lockdown */
1231 arm920t_execute_cp15(target,
1232 ARMV4_5_MCR(15,0,0,10,0,0),
1233 ARMV4_5_STR(1, 0));
1235 /* Read D TLB CAM */
1236 arm920t_execute_cp15(target,
1237 ARMV4_5_MCR(15,4,0,15,6,4),
1238 ARMV4_5_LDMIA(0, 0x3fc, 0, 0));
1240 /* clear interpret mode */
1241 cp15c15 &= ~0x1;
1242 arm920t_write_cp15_physical(target,
1243 CP15PHYS_TESTSTATE, cp15c15);
1245 /* read D TLB CAM content stored to r2-r9 */
1246 arm9tdmi_read_core_regs(target, 0x3fc, regs_p);
1247 if ((retval = jtag_execute_queue()) != ERROR_OK)
1249 return retval;
1252 for (i = 0; i < 8; i++)
1253 d_tlb[victim + i].cam = regs[i + 2];
1256 for (victim = 0; victim < 64; victim++)
1258 /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
1259 * base remains unchanged, victim goes through entries 0 to 63
1261 regs[1] = (Dlockdown & 0xfc000000) | (victim << 20);
1262 arm9tdmi_write_core_regs(target, 0x2, regs);
1264 /* set interpret mode */
1265 cp15c15 |= 0x1;
1266 arm920t_write_cp15_physical(target,
1267 CP15PHYS_TESTSTATE, cp15c15);
1269 /* Write D TLB lockdown */
1270 arm920t_execute_cp15(target,
1271 ARMV4_5_MCR(15,0,0,10,0,0), ARMV4_5_STR(1, 0));
1273 /* Read D TLB RAM1 */
1274 arm920t_execute_cp15(target,
1275 ARMV4_5_MCR(15,4,0,15,10,4), ARMV4_5_LDR(2,0));
1277 /* Read D TLB RAM2 */
1278 arm920t_execute_cp15(target,
1279 ARMV4_5_MCR(15,4,0,15,2,5), ARMV4_5_LDR(3,0));
1281 /* clear interpret mode */
1282 cp15c15 &= ~0x1;
1283 arm920t_write_cp15_physical(target,
1284 CP15PHYS_TESTSTATE, cp15c15);
1286 /* read D TLB RAM content stored to r2 and r3 */
1287 arm9tdmi_read_core_regs(target, 0xc, regs_p);
1288 if ((retval = jtag_execute_queue()) != ERROR_OK)
1290 return retval;
1293 d_tlb[victim].ram1 = regs[2];
1294 d_tlb[victim].ram2 = regs[3];
1297 /* restore D TLB lockdown */
1298 regs[1] = Dlockdown;
1299 arm9tdmi_write_core_regs(target, 0x2, regs);
1301 /* Write D TLB lockdown */
1302 arm920t_execute_cp15(target,
1303 ARMV4_5_MCR(15,0,0,10,0,0), ARMV4_5_STR(1, 0));
1305 /* prepare reading I TLB content
1306 * */
1308 /* set interpret mode */
1309 cp15c15 |= 0x1;
1310 arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);
1312 /* Read I TLB lockdown */
1313 arm920t_execute_cp15(target,
1314 ARMV4_5_MRC(15,0,0,10,0,1), ARMV4_5_LDR(1, 0));
1316 /* clear interpret mode */
1317 cp15c15 &= ~0x1;
1318 arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);
1320 /* read I TLB lockdown stored to r1 */
1321 arm9tdmi_read_core_regs(target, 0x2, regs_p);
1322 if ((retval = jtag_execute_queue()) != ERROR_OK)
1324 return retval;
1326 Ilockdown = regs[1];
1328 for (victim = 0; victim < 64; victim += 8)
1330 /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
1331 * base remains unchanged, victim goes through entries 0 to 63
1333 regs[1] = (Ilockdown & 0xfc000000) | (victim << 20);
1334 arm9tdmi_write_core_regs(target, 0x2, regs);
1336 /* set interpret mode */
1337 cp15c15 |= 0x1;
1338 arm920t_write_cp15_physical(target,
1339 CP15PHYS_TESTSTATE, cp15c15);
1341 /* Write I TLB lockdown */
1342 arm920t_execute_cp15(target,
1343 ARMV4_5_MCR(15,0,0,10,0,1),
1344 ARMV4_5_STR(1, 0));
1346 /* Read I TLB CAM */
1347 arm920t_execute_cp15(target,
1348 ARMV4_5_MCR(15,4,0,15,5,4),
1349 ARMV4_5_LDMIA(0, 0x3fc, 0, 0));
1351 /* clear interpret mode */
1352 cp15c15 &= ~0x1;
1353 arm920t_write_cp15_physical(target,
1354 CP15PHYS_TESTSTATE, cp15c15);
1356 /* read I TLB CAM content stored to r2-r9 */
1357 arm9tdmi_read_core_regs(target, 0x3fc, regs_p);
1358 if ((retval = jtag_execute_queue()) != ERROR_OK)
1360 return retval;
1363 for (i = 0; i < 8; i++)
1364 i_tlb[i + victim].cam = regs[i + 2];
1367 for (victim = 0; victim < 64; victim++)
1369 /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
1370 * base remains unchanged, victim goes through entries 0 to 63
1372 regs[1] = (Dlockdown & 0xfc000000) | (victim << 20);
1373 arm9tdmi_write_core_regs(target, 0x2, regs);
1375 /* set interpret mode */
1376 cp15c15 |= 0x1;
1377 arm920t_write_cp15_physical(target,
1378 CP15PHYS_TESTSTATE, cp15c15);
1380 /* Write I TLB lockdown */
1381 arm920t_execute_cp15(target,
1382 ARMV4_5_MCR(15,0,0,10,0,1), ARMV4_5_STR(1, 0));
1384 /* Read I TLB RAM1 */
1385 arm920t_execute_cp15(target,
1386 ARMV4_5_MCR(15,4,0,15,9,4), ARMV4_5_LDR(2,0));
1388 /* Read I TLB RAM2 */
1389 arm920t_execute_cp15(target,
1390 ARMV4_5_MCR(15,4,0,15,1,5), ARMV4_5_LDR(3,0));
1392 /* clear interpret mode */
1393 cp15c15 &= ~0x1;
1394 arm920t_write_cp15_physical(target,
1395 CP15PHYS_TESTSTATE, cp15c15);
1397 /* read I TLB RAM content stored to r2 and r3 */
1398 arm9tdmi_read_core_regs(target, 0xc, regs_p);
1399 if ((retval = jtag_execute_queue()) != ERROR_OK)
1401 return retval;
1404 i_tlb[victim].ram1 = regs[2];
1405 i_tlb[victim].ram2 = regs[3];
1408 /* restore I TLB lockdown */
1409 regs[1] = Ilockdown;
1410 arm9tdmi_write_core_regs(target, 0x2, regs);
1412 /* Write I TLB lockdown */
1413 arm920t_execute_cp15(target,
1414 ARMV4_5_MCR(15,0,0,10,0,1), ARMV4_5_STR(1, 0));
1416 /* restore CP15 MMU and Cache settings */
1417 arm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_ctrl_saved);
1419 /* output data to file */
1420 fprintf(output, "D TLB content:\n");
1421 for (i = 0; i < 64; i++)
1423 fprintf(output, "%i: 0x%8.8" PRIx32 " 0x%8.8" PRIx32
1424 " 0x%8.8" PRIx32 " %s\n",
1425 i, d_tlb[i].cam, d_tlb[i].ram1, d_tlb[i].ram2,
1426 (d_tlb[i].cam & 0x20) ? "(valid)" : "(invalid)");
1429 fprintf(output, "\n\nI TLB content:\n");
1430 for (i = 0; i < 64; i++)
1432 fprintf(output, "%i: 0x%8.8" PRIx32 " 0x%8.8" PRIx32
1433 " 0x%8.8" PRIx32 " %s\n",
1434 i, i_tlb[i].cam, i_tlb[i].ram1, i_tlb[i].ram2,
1435 (i_tlb[i].cam & 0x20) ? "(valid)" : "(invalid)");
1438 command_print(CMD_CTX, "mmu content successfully output to %s",
1439 CMD_ARGV[0]);
1441 fclose(output);
1443 if (!is_arm_mode(armv4_5->core_mode))
1444 return ERROR_FAIL;
1446 /* force writeback of the valid data */
1447 r = armv4_5->core_cache->reg_list;
1448 r[0].dirty = r[0].valid;
1449 r[1].dirty = r[1].valid;
1450 r[2].dirty = r[2].valid;
1451 r[3].dirty = r[3].valid;
1452 r[4].dirty = r[4].valid;
1453 r[5].dirty = r[5].valid;
1454 r[6].dirty = r[6].valid;
1455 r[7].dirty = r[7].valid;
1457 r = arm_reg_current(armv4_5, 8);
1458 r->dirty = r->valid;
1460 r = arm_reg_current(armv4_5, 9);
1461 r->dirty = r->valid;
1463 return ERROR_OK;
1466 COMMAND_HANDLER(arm920t_handle_cp15_command)
1468 int retval;
1469 struct target *target = get_current_target(CMD_CTX);
1470 struct arm920t_common *arm920t = target_to_arm920(target);
1472 retval = arm920t_verify_pointer(CMD_CTX, arm920t);
1473 if (retval != ERROR_OK)
1474 return retval;
1476 if (target->state != TARGET_HALTED)
1478 command_print(CMD_CTX, "target must be stopped for "
1479 "\"%s\" command", CMD_NAME);
1480 return ERROR_OK;
1483 /* one argument, read a register.
1484 * two arguments, write it.
1486 if (CMD_ARGC >= 1)
1488 int address;
1489 COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], address);
1491 if (CMD_ARGC == 1)
1493 uint32_t value;
1494 if ((retval = arm920t_read_cp15_physical(target,
1495 address, &value)) != ERROR_OK)
1497 command_print(CMD_CTX,
1498 "couldn't access reg %i", address);
1499 return ERROR_OK;
1501 if ((retval = jtag_execute_queue()) != ERROR_OK)
1503 return retval;
1506 command_print(CMD_CTX, "%i: %8.8" PRIx32,
1507 address, value);
1509 else if (CMD_ARGC == 2)
1511 uint32_t value;
1512 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
1513 retval = arm920t_write_cp15_physical(target,
1514 address, value);
1515 if (retval != ERROR_OK)
1517 command_print(CMD_CTX,
1518 "couldn't access reg %i", address);
1519 /* REVISIT why lie? "return retval"? */
1520 return ERROR_OK;
1522 command_print(CMD_CTX, "%i: %8.8" PRIx32,
1523 address, value);
1527 return ERROR_OK;
1530 COMMAND_HANDLER(arm920t_handle_cp15i_command)
1532 int retval;
1533 struct target *target = get_current_target(CMD_CTX);
1534 struct arm920t_common *arm920t = target_to_arm920(target);
1536 retval = arm920t_verify_pointer(CMD_CTX, arm920t);
1537 if (retval != ERROR_OK)
1538 return retval;
1541 if (target->state != TARGET_HALTED)
1543 command_print(CMD_CTX, "target must be stopped for "
1544 "\"%s\" command", CMD_NAME);
1545 return ERROR_OK;
1548 /* one argument, read a register.
1549 * two arguments, write it.
1551 if (CMD_ARGC >= 1)
1553 uint32_t opcode;
1554 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], opcode);
1556 if (CMD_ARGC == 1)
1558 uint32_t value;
1559 retval = arm920t_read_cp15_interpreted(target,
1560 opcode, 0x0, &value);
1561 if (retval != ERROR_OK)
1563 command_print(CMD_CTX,
1564 "couldn't execute %8.8" PRIx32,
1565 opcode);
1566 /* REVISIT why lie? "return retval"? */
1567 return ERROR_OK;
1570 command_print(CMD_CTX, "%8.8" PRIx32 ": %8.8" PRIx32,
1571 opcode, value);
1573 else if (CMD_ARGC == 2)
1575 uint32_t value;
1576 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
1577 retval = arm920t_write_cp15_interpreted(target,
1578 opcode, value, 0);
1579 if (retval != ERROR_OK)
1581 command_print(CMD_CTX,
1582 "couldn't execute %8.8" PRIx32,
1583 opcode);
1584 /* REVISIT why lie? "return retval"? */
1585 return ERROR_OK;
1587 command_print(CMD_CTX, "%8.8" PRIx32 ": %8.8" PRIx32,
1588 opcode, value);
1590 else if (CMD_ARGC == 3)
1592 uint32_t value;
1593 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
1594 uint32_t address;
1595 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], address);
1596 retval = arm920t_write_cp15_interpreted(target,
1597 opcode, value, address);
1598 if (retval != ERROR_OK)
1600 command_print(CMD_CTX,
1601 "couldn't execute %8.8" PRIx32, opcode);
1602 /* REVISIT why lie? "return retval"? */
1603 return ERROR_OK;
1605 command_print(CMD_CTX, "%8.8" PRIx32 ": %8.8" PRIx32
1606 " %8.8" PRIx32, opcode, value, address);
1609 else
1611 command_print(CMD_CTX,
1612 "usage: arm920t cp15i <opcode> [value] [address]");
1615 return ERROR_OK;
1618 COMMAND_HANDLER(arm920t_handle_cache_info_command)
1620 int retval;
1621 struct target *target = get_current_target(CMD_CTX);
1622 struct arm920t_common *arm920t = target_to_arm920(target);
1624 retval = arm920t_verify_pointer(CMD_CTX, arm920t);
1625 if (retval != ERROR_OK)
1626 return retval;
1628 return armv4_5_handle_cache_info_command(CMD_CTX,
1629 &arm920t->armv4_5_mmu.armv4_5_cache);
1633 static int arm920t_mrc(struct target *target, int cpnum,
1634 uint32_t op1, uint32_t op2,
1635 uint32_t CRn, uint32_t CRm,
1636 uint32_t *value)
1638 if (cpnum!=15)
1640 LOG_ERROR("Only cp15 is supported");
1641 return ERROR_FAIL;
1644 /* read "to" r0 */
1645 return arm920t_read_cp15_interpreted(target,
1646 ARMV4_5_MRC(cpnum, op1, 0, CRn, CRm, op2),
1647 0, value);
1650 static int arm920t_mcr(struct target *target, int cpnum,
1651 uint32_t op1, uint32_t op2,
1652 uint32_t CRn, uint32_t CRm,
1653 uint32_t value)
1655 if (cpnum!=15)
1657 LOG_ERROR("Only cp15 is supported");
1658 return ERROR_FAIL;
1661 /* write "from" r0 */
1662 return arm920t_write_cp15_interpreted(target,
1663 ARMV4_5_MCR(cpnum, op1, 0, CRn, CRm, op2),
1664 0, value);
1667 static const struct command_registration arm920t_exec_command_handlers[] = {
1669 .name = "cp15",
1670 .handler = arm920t_handle_cp15_command,
1671 .mode = COMMAND_EXEC,
1672 .help = "display/modify cp15 register",
1673 .usage = "regnum [value]",
1676 .name = "cp15i",
1677 .handler = arm920t_handle_cp15i_command,
1678 .mode = COMMAND_EXEC,
1679 /* prefer using less error-prone "arm mcr" or "arm mrc" */
1680 .help = "display/modify cp15 register using ARM opcode"
1681 " (DEPRECATED)",
1682 .usage = "instruction [value [address]]",
1685 .name = "cache_info",
1686 .handler = arm920t_handle_cache_info_command,
1687 .mode = COMMAND_EXEC,
1688 .help = "display information about target caches",
1691 .name = "read_cache",
1692 .handler = arm920t_handle_read_cache_command,
1693 .mode = COMMAND_EXEC,
1694 .help = "dump I/D cache content to file",
1695 .usage = "filename",
1698 .name = "read_mmu",
1699 .handler = arm920t_handle_read_mmu_command,
1700 .mode = COMMAND_EXEC,
1701 .help = "dump I/D mmu content to file",
1702 .usage = "filename",
1704 COMMAND_REGISTRATION_DONE
1706 const struct command_registration arm920t_command_handlers[] = {
1708 .chain = arm9tdmi_command_handlers,
1711 .name = "arm920t",
1712 .mode = COMMAND_ANY,
1713 .help = "arm920t command group",
1714 .chain = arm920t_exec_command_handlers,
1716 COMMAND_REGISTRATION_DONE
1719 /** Holds methods for ARM920 targets. */
1720 struct target_type arm920t_target =
1722 .name = "arm920t",
1724 .poll = arm7_9_poll,
1725 .arch_state = arm920t_arch_state,
1727 .target_request_data = arm7_9_target_request_data,
1729 .halt = arm7_9_halt,
1730 .resume = arm7_9_resume,
1731 .step = arm7_9_step,
1733 .assert_reset = arm7_9_assert_reset,
1734 .deassert_reset = arm7_9_deassert_reset,
1735 .soft_reset_halt = arm920t_soft_reset_halt,
1737 .get_gdb_reg_list = arm_get_gdb_reg_list,
1739 .read_memory = arm920t_read_memory,
1740 .write_memory = arm920t_write_memory,
1741 .read_phys_memory = arm920t_read_phys_memory,
1742 .write_phys_memory = arm920t_write_phys_memory,
1743 .mmu = arm920_mmu,
1744 .virt2phys = arm920_virt2phys,
1746 .bulk_write_memory = arm7_9_bulk_write_memory,
1748 .checksum_memory = arm_checksum_memory,
1749 .blank_check_memory = arm_blank_check_memory,
1751 .run_algorithm = armv4_5_run_algorithm,
1753 .add_breakpoint = arm7_9_add_breakpoint,
1754 .remove_breakpoint = arm7_9_remove_breakpoint,
1755 .add_watchpoint = arm7_9_add_watchpoint,
1756 .remove_watchpoint = arm7_9_remove_watchpoint,
1758 .commands = arm920t_command_handlers,
1759 .target_create = arm920t_target_create,
1760 .init_target = arm9tdmi_init_target,
1761 .examine = arm7_9_examine,
1762 .check_reset = arm7_9_check_reset,