target/xtensa: avoid IHI for writes to non-executable memory
[openocd.git] / src / target / arm920t.c
blob53b4d9d15f3ac6240f81c7fef9b8e9a6de46fa57
1 // SPDX-License-Identifier: GPL-2.0-or-later
4 /***************************************************************************
5 * Copyright (C) 2005 by Dominic Rath *
6 * Dominic.Rath@gmx.de *
7 ***************************************************************************/
9 #ifdef HAVE_CONFIG_H
10 #include "config.h"
11 #endif
13 #include "arm920t.h"
14 #include <helper/time_support.h>
15 #include "target_type.h"
16 #include "register.h"
17 #include "arm_opcodes.h"
20 * For information about the ARM920T, see ARM DDI 0151C especially
21 * Chapter 9 about debug support, which shows how to manipulate each
22 * of the different scan chains:
24 * 0 ... ARM920 signals, e.g. to rest of SOC (unused here)
25 * 1 ... debugging; watchpoint and breakpoint status, etc; also
26 * MMU and cache access in conjunction with scan chain 15
27 * 2 ... EmbeddedICE
28 * 3 ... external boundary scan (SoC-specific, unused here)
29 * 4 ... access to cache tag RAM
30 * 6 ... ETM9
31 * 15 ... access coprocessor 15, "physical" or "interpreted" modes
32 * "interpreted" works with a few actual MRC/MCR instructions
33 * "physical" provides register-like behaviors. Section 9.6.7
34 * covers these details.
36 * The ARM922T is similar, but with smaller caches (8K each, vs 16K).
39 #if 0
40 #define _DEBUG_INSTRUCTION_EXECUTION_
41 #endif
43 /* Table 9-8 shows scan chain 15 format during physical access mode, using a
44 * dedicated 6-bit address space (encoded in bits 33:38). Writes use one
45 * JTAG scan, while reads use two.
47 * Table 9-9 lists the thirteen registers which support physical access.
48 * ARM920T_CP15_PHYS_ADDR() constructs the 6-bit reg_addr parameter passed
49 * to arm920t_read_cp15_physical() and arm920t_write_cp15_physical().
51 * x == bit[38]
52 * y == bits[37:34]
53 * z == bit[33]
55 #define ARM920T_CP15_PHYS_ADDR(x, y, z) ((x << 5) | (y << 1) << (z))
57 /* Registers supporting physical Read access (from table 9-9) */
58 #define CP15PHYS_CACHETYPE ARM920T_CP15_PHYS_ADDR(0, 0x0, 1)
59 #define CP15PHYS_ICACHE_IDX ARM920T_CP15_PHYS_ADDR(1, 0xd, 1)
60 #define CP15PHYS_DCACHE_IDX ARM920T_CP15_PHYS_ADDR(1, 0xe, 1)
61 /* NOTE: several more registers support only physical read access */
63 /* Registers supporting physical Read/Write access (from table 9-9) */
64 #define CP15PHYS_CTRL ARM920T_CP15_PHYS_ADDR(0, 0x1, 0)
65 #define CP15PHYS_PID ARM920T_CP15_PHYS_ADDR(0, 0xd, 0)
66 #define CP15PHYS_TESTSTATE ARM920T_CP15_PHYS_ADDR(0, 0xf, 0)
67 #define CP15PHYS_ICACHE ARM920T_CP15_PHYS_ADDR(1, 0x1, 1)
68 #define CP15PHYS_DCACHE ARM920T_CP15_PHYS_ADDR(1, 0x2, 1)
70 static int arm920t_read_cp15_physical(struct target *target,
71 int reg_addr, uint32_t *value)
73 struct arm920t_common *arm920t = target_to_arm920(target);
74 struct arm_jtag *jtag_info;
75 struct scan_field fields[4];
76 uint8_t access_type_buf = 1;
77 uint8_t reg_addr_buf = reg_addr & 0x3f;
78 uint8_t nr_w_buf = 0;
79 int retval;
81 jtag_info = &arm920t->arm7_9_common.jtag_info;
83 retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);
84 if (retval != ERROR_OK)
85 return retval;
86 retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE);
87 if (retval != ERROR_OK)
88 return retval;
90 fields[0].num_bits = 1;
91 fields[0].out_value = &access_type_buf;
92 fields[0].in_value = NULL;
94 fields[1].num_bits = 32;
95 fields[1].out_value = NULL;
96 fields[1].in_value = NULL;
98 fields[2].num_bits = 6;
99 fields[2].out_value = &reg_addr_buf;
100 fields[2].in_value = NULL;
102 fields[3].num_bits = 1;
103 fields[3].out_value = &nr_w_buf;
104 fields[3].in_value = NULL;
106 jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
108 fields[1].in_value = (uint8_t *)value;
110 jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
112 jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)value);
114 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
115 jtag_execute_queue();
116 LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value);
117 #endif
119 return ERROR_OK;
122 static int arm920t_write_cp15_physical(struct target *target,
123 int reg_addr, uint32_t value)
125 struct arm920t_common *arm920t = target_to_arm920(target);
126 struct arm_jtag *jtag_info;
127 struct scan_field fields[4];
128 uint8_t access_type_buf = 1;
129 uint8_t reg_addr_buf = reg_addr & 0x3f;
130 uint8_t nr_w_buf = 1;
131 uint8_t value_buf[4];
132 int retval;
134 jtag_info = &arm920t->arm7_9_common.jtag_info;
136 buf_set_u32(value_buf, 0, 32, value);
138 retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);
139 if (retval != ERROR_OK)
140 return retval;
141 retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE);
142 if (retval != ERROR_OK)
143 return retval;
145 fields[0].num_bits = 1;
146 fields[0].out_value = &access_type_buf;
147 fields[0].in_value = NULL;
149 fields[1].num_bits = 32;
150 fields[1].out_value = value_buf;
151 fields[1].in_value = NULL;
153 fields[2].num_bits = 6;
154 fields[2].out_value = &reg_addr_buf;
155 fields[2].in_value = NULL;
157 fields[3].num_bits = 1;
158 fields[3].out_value = &nr_w_buf;
159 fields[3].in_value = NULL;
161 jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
163 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
164 LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, value);
165 #endif
167 return ERROR_OK;
170 /* See table 9-10 for scan chain 15 format during interpreted access mode.
171 * If the TESTSTATE register is set for interpreted access, certain CP15
172 * MRC and MCR instructions may be executed through scan chain 15.
174 * Tables 9-11, 9-12, and 9-13 show which MRC and MCR instructions can be
175 * executed using scan chain 15 interpreted mode.
177 static int arm920t_execute_cp15(struct target *target, uint32_t cp15_opcode,
178 uint32_t arm_opcode)
180 int retval;
181 struct arm920t_common *arm920t = target_to_arm920(target);
182 struct arm_jtag *jtag_info;
183 struct scan_field fields[4];
184 uint8_t access_type_buf = 0; /* interpreted access */
185 uint8_t reg_addr_buf = 0x0;
186 uint8_t nr_w_buf = 0;
187 uint8_t cp15_opcode_buf[4];
189 jtag_info = &arm920t->arm7_9_common.jtag_info;
191 retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);
192 if (retval != ERROR_OK)
193 return retval;
194 retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE);
195 if (retval != ERROR_OK)
196 return retval;
198 buf_set_u32(cp15_opcode_buf, 0, 32, cp15_opcode);
200 fields[0].num_bits = 1;
201 fields[0].out_value = &access_type_buf;
202 fields[0].in_value = NULL;
204 fields[1].num_bits = 32;
205 fields[1].out_value = cp15_opcode_buf;
206 fields[1].in_value = NULL;
208 fields[2].num_bits = 6;
209 fields[2].out_value = &reg_addr_buf;
210 fields[2].in_value = NULL;
212 fields[3].num_bits = 1;
213 fields[3].out_value = &nr_w_buf;
214 fields[3].in_value = NULL;
216 jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
218 arm9tdmi_clock_out(jtag_info, arm_opcode, 0, NULL, 0);
219 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
220 retval = arm7_9_execute_sys_speed(target);
221 if (retval != ERROR_OK)
222 return retval;
224 retval = jtag_execute_queue();
225 if (retval != ERROR_OK) {
226 LOG_ERROR("failed executing JTAG queue");
227 return retval;
230 return ERROR_OK;
233 static int arm920t_read_cp15_interpreted(struct target *target,
234 uint32_t cp15_opcode, uint32_t address, uint32_t *value)
236 struct arm *arm = target_to_arm(target);
237 uint32_t *regs_p[16];
238 uint32_t regs[16];
239 uint32_t cp15c15 = 0x0;
240 struct reg *r = arm->core_cache->reg_list;
242 /* load address into R1 */
243 regs[1] = address;
244 arm9tdmi_write_core_regs(target, 0x2, regs);
246 /* read-modify-write CP15 test state register
247 * to enable interpreted access mode */
248 arm920t_read_cp15_physical(target, CP15PHYS_TESTSTATE, &cp15c15);
249 jtag_execute_queue();
250 cp15c15 |= 1; /* set interpret mode */
251 arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);
253 /* execute CP15 instruction and ARM load (reading from coprocessor) */
254 arm920t_execute_cp15(target, cp15_opcode, ARMV4_5_LDR(0, 1));
256 /* disable interpreted access mode */
257 cp15c15 &= ~1U; /* clear interpret mode */
258 arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);
260 /* retrieve value from R0 */
261 regs_p[0] = value;
262 arm9tdmi_read_core_regs(target, 0x1, regs_p);
263 jtag_execute_queue();
265 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
266 LOG_DEBUG("cp15_opcode: %8.8x, address: %8.8x, value: %8.8x",
267 cp15_opcode, address, *value);
268 #endif
270 if (!is_arm_mode(arm->core_mode)) {
271 LOG_ERROR("not a valid arm core mode - communication failure?");
272 return ERROR_FAIL;
275 r[0].dirty = true;
276 r[1].dirty = true;
278 return ERROR_OK;
281 static
282 int arm920t_write_cp15_interpreted(struct target *target,
283 uint32_t cp15_opcode, uint32_t value, uint32_t address)
285 uint32_t cp15c15 = 0x0;
286 struct arm *arm = target_to_arm(target);
287 uint32_t regs[16];
288 struct reg *r = arm->core_cache->reg_list;
290 /* load value, address into R0, R1 */
291 regs[0] = value;
292 regs[1] = address;
293 arm9tdmi_write_core_regs(target, 0x3, regs);
295 /* read-modify-write CP15 test state register
296 * to enable interpreted access mode */
297 arm920t_read_cp15_physical(target, CP15PHYS_TESTSTATE, &cp15c15);
298 jtag_execute_queue();
299 cp15c15 |= 1; /* set interpret mode */
300 arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);
302 /* execute CP15 instruction and ARM store (writing to coprocessor) */
303 arm920t_execute_cp15(target, cp15_opcode, ARMV4_5_STR(0, 1));
305 /* disable interpreted access mode */
306 cp15c15 &= ~1U; /* set interpret mode */
307 arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);
309 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
310 LOG_DEBUG("cp15_opcode: %8.8x, value: %8.8x, address: %8.8x",
311 cp15_opcode, value, address);
312 #endif
314 if (!is_arm_mode(arm->core_mode)) {
315 LOG_ERROR("not a valid arm core mode - communication failure?");
316 return ERROR_FAIL;
319 r[0].dirty = true;
320 r[1].dirty = true;
322 return ERROR_OK;
325 /* EXPORTED to FA256 */
326 int arm920t_get_ttb(struct target *target, uint32_t *result)
328 int retval;
329 uint32_t ttb = 0x0;
331 retval = arm920t_read_cp15_interpreted(target,
332 /* FIXME use opcode macro */
333 0xeebf0f51, 0x0, &ttb);
334 if (retval != ERROR_OK)
335 return retval;
337 *result = ttb;
338 return ERROR_OK;
341 /* EXPORTED to FA256 */
342 int arm920t_disable_mmu_caches(struct target *target, int mmu,
343 int d_u_cache, int i_cache)
345 uint32_t cp15_control;
346 int retval;
348 /* read cp15 control register */
349 retval = arm920t_read_cp15_physical(target, CP15PHYS_CTRL, &cp15_control);
350 if (retval != ERROR_OK)
351 return retval;
352 retval = jtag_execute_queue();
353 if (retval != ERROR_OK)
354 return retval;
356 if (mmu)
357 cp15_control &= ~0x1U;
359 if (d_u_cache)
360 cp15_control &= ~0x4U;
362 if (i_cache)
363 cp15_control &= ~0x1000U;
365 retval = arm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_control);
366 return retval;
369 /* EXPORTED to FA256 */
370 int arm920t_enable_mmu_caches(struct target *target, int mmu,
371 int d_u_cache, int i_cache)
373 uint32_t cp15_control;
374 int retval;
376 /* read cp15 control register */
377 retval = arm920t_read_cp15_physical(target, CP15PHYS_CTRL, &cp15_control);
378 if (retval != ERROR_OK)
379 return retval;
380 retval = jtag_execute_queue();
381 if (retval != ERROR_OK)
382 return retval;
384 if (mmu)
385 cp15_control |= 0x1U;
387 if (d_u_cache)
388 cp15_control |= 0x4U;
390 if (i_cache)
391 cp15_control |= 0x1000U;
393 retval = arm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_control);
394 return retval;
397 /* EXPORTED to FA256 */
398 int arm920t_post_debug_entry(struct target *target)
400 uint32_t cp15c15;
401 struct arm920t_common *arm920t = target_to_arm920(target);
402 int retval;
404 /* examine cp15 control reg */
405 retval = arm920t_read_cp15_physical(target,
406 CP15PHYS_CTRL, &arm920t->cp15_control_reg);
407 if (retval != ERROR_OK)
408 return retval;
409 retval = jtag_execute_queue();
410 if (retval != ERROR_OK)
411 return retval;
412 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32, arm920t->cp15_control_reg);
414 if (arm920t->armv4_5_mmu.armv4_5_cache.ctype == -1) {
415 uint32_t cache_type_reg;
416 /* identify caches */
417 retval = arm920t_read_cp15_physical(target,
418 CP15PHYS_CACHETYPE, &cache_type_reg);
419 if (retval != ERROR_OK)
420 return retval;
421 retval = jtag_execute_queue();
422 if (retval != ERROR_OK)
423 return retval;
424 armv4_5_identify_cache(cache_type_reg,
425 &arm920t->armv4_5_mmu.armv4_5_cache);
428 arm920t->armv4_5_mmu.mmu_enabled =
429 (arm920t->cp15_control_reg & 0x1U) ? 1 : 0;
430 arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled =
431 (arm920t->cp15_control_reg & 0x4U) ? 1 : 0;
432 arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled =
433 (arm920t->cp15_control_reg & 0x1000U) ? 1 : 0;
435 /* save i/d fault status and address register
436 * FIXME use opcode macros */
437 retval = arm920t_read_cp15_interpreted(target, 0xee150f10, 0x0, &arm920t->d_fsr);
438 if (retval != ERROR_OK)
439 return retval;
440 retval = arm920t_read_cp15_interpreted(target, 0xee150f30, 0x0, &arm920t->i_fsr);
441 if (retval != ERROR_OK)
442 return retval;
443 retval = arm920t_read_cp15_interpreted(target, 0xee160f10, 0x0, &arm920t->d_far);
444 if (retval != ERROR_OK)
445 return retval;
446 retval = arm920t_read_cp15_interpreted(target, 0xee160f30, 0x0, &arm920t->i_far);
447 if (retval != ERROR_OK)
448 return retval;
450 LOG_DEBUG("D FSR: 0x%8.8" PRIx32 ", D FAR: 0x%8.8" PRIx32
451 ", I FSR: 0x%8.8" PRIx32 ", I FAR: 0x%8.8" PRIx32,
452 arm920t->d_fsr, arm920t->d_far, arm920t->i_fsr, arm920t->i_far);
454 if (arm920t->preserve_cache) {
455 /* read-modify-write CP15 test state register
456 * to disable I/D-cache linefills */
457 retval = arm920t_read_cp15_physical(target,
458 CP15PHYS_TESTSTATE, &cp15c15);
459 if (retval != ERROR_OK)
460 return retval;
461 retval = jtag_execute_queue();
462 if (retval != ERROR_OK)
463 return retval;
464 cp15c15 |= 0x600;
465 retval = arm920t_write_cp15_physical(target,
466 CP15PHYS_TESTSTATE, cp15c15);
467 if (retval != ERROR_OK)
468 return retval;
470 return ERROR_OK;
473 /* EXPORTED to FA256 */
474 void arm920t_pre_restore_context(struct target *target)
476 uint32_t cp15c15 = 0;
477 struct arm920t_common *arm920t = target_to_arm920(target);
479 /* restore i/d fault status and address register */
480 arm920t_write_cp15_interpreted(target, 0xee050f10, arm920t->d_fsr, 0x0);
481 arm920t_write_cp15_interpreted(target, 0xee050f30, arm920t->i_fsr, 0x0);
482 arm920t_write_cp15_interpreted(target, 0xee060f10, arm920t->d_far, 0x0);
483 arm920t_write_cp15_interpreted(target, 0xee060f30, arm920t->i_far, 0x0);
485 /* read-modify-write CP15 test state register
486 * to reenable I/D-cache linefills */
487 if (arm920t->preserve_cache) {
488 arm920t_read_cp15_physical(target,
489 CP15PHYS_TESTSTATE, &cp15c15);
490 jtag_execute_queue();
491 cp15c15 &= ~0x600U;
492 arm920t_write_cp15_physical(target,
493 CP15PHYS_TESTSTATE, cp15c15);
497 static const char arm920_not[] = "target is not an ARM920";
499 static int arm920t_verify_pointer(struct command_invocation *cmd,
500 struct arm920t_common *arm920t)
502 if (arm920t->common_magic != ARM920T_COMMON_MAGIC) {
503 command_print(cmd, arm920_not);
504 return ERROR_TARGET_INVALID;
507 return ERROR_OK;
510 /** Logs summary of ARM920 state for a halted target. */
511 int arm920t_arch_state(struct target *target)
513 static const char *state[] = {
514 "disabled", "enabled"
517 struct arm920t_common *arm920t = target_to_arm920(target);
519 if (arm920t->common_magic != ARM920T_COMMON_MAGIC) {
520 LOG_ERROR("BUG: %s", arm920_not);
521 return ERROR_TARGET_INVALID;
524 arm_arch_state(target);
525 LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
526 state[arm920t->armv4_5_mmu.mmu_enabled],
527 state[arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],
528 state[arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled]);
530 return ERROR_OK;
533 static int arm920_mmu(struct target *target, int *enabled)
535 if (target->state != TARGET_HALTED) {
536 LOG_TARGET_ERROR(target, "not halted");
537 return ERROR_TARGET_NOT_HALTED;
540 *enabled = target_to_arm920(target)->armv4_5_mmu.mmu_enabled;
541 return ERROR_OK;
544 static int arm920_virt2phys(struct target *target,
545 target_addr_t virt, target_addr_t *phys)
547 uint32_t cb;
548 struct arm920t_common *arm920t = target_to_arm920(target);
550 uint32_t ret;
551 int retval = armv4_5_mmu_translate_va(target,
552 &arm920t->armv4_5_mmu, virt, &cb, &ret);
553 if (retval != ERROR_OK)
554 return retval;
555 *phys = ret;
556 return ERROR_OK;
559 /** Reads a buffer, in the specified word size, with current MMU settings. */
560 int arm920t_read_memory(struct target *target, target_addr_t address,
561 uint32_t size, uint32_t count, uint8_t *buffer)
563 int retval;
565 retval = arm7_9_read_memory(target, address, size, count, buffer);
567 return retval;
571 static int arm920t_read_phys_memory(struct target *target,
572 target_addr_t address, uint32_t size,
573 uint32_t count, uint8_t *buffer)
575 struct arm920t_common *arm920t = target_to_arm920(target);
577 return armv4_5_mmu_read_physical(target, &arm920t->armv4_5_mmu,
578 address, size, count, buffer);
581 static int arm920t_write_phys_memory(struct target *target,
582 target_addr_t address, uint32_t size,
583 uint32_t count, const uint8_t *buffer)
585 struct arm920t_common *arm920t = target_to_arm920(target);
587 return armv4_5_mmu_write_physical(target, &arm920t->armv4_5_mmu,
588 address, size, count, buffer);
591 /** Writes a buffer, in the specified word size, with current MMU settings. */
592 int arm920t_write_memory(struct target *target, target_addr_t address,
593 uint32_t size, uint32_t count, const uint8_t *buffer)
595 int retval;
596 const uint32_t cache_mask = ~0x1f; /* cache line size : 32 byte */
597 struct arm920t_common *arm920t = target_to_arm920(target);
599 /* FIX!!!! this should be cleaned up and made much more general. The
600 * plan is to write up and test on arm920t specifically and
601 * then generalize and clean up afterwards.
603 * Also it should be moved to the callbacks that handle breakpoints
604 * specifically and not the generic memory write fn's. See XScale code.
606 if (arm920t->armv4_5_mmu.mmu_enabled && (count == 1) &&
607 ((size == 2) || (size == 4))) {
608 /* special case the handling of single word writes to
609 * bypass MMU, to allow implementation of breakpoints
610 * in memory marked read only
611 * by MMU
613 uint32_t cb;
614 uint32_t pa;
617 * We need physical address and cb
619 retval = armv4_5_mmu_translate_va(target, &arm920t->armv4_5_mmu,
620 address, &cb, &pa);
621 if (retval != ERROR_OK)
622 return retval;
624 if (arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) {
625 if (cb & 0x1) {
626 LOG_DEBUG("D-Cache buffered, "
627 "drain write buffer");
629 * Buffered ?
630 * Drain write buffer - MCR p15,0,Rd,c7,c10,4
633 retval = arm920t_write_cp15_interpreted(target,
634 ARMV4_5_MCR(15, 0, 0, 7, 10, 4),
635 0x0, 0);
636 if (retval != ERROR_OK)
637 return retval;
640 if (cb == 0x3) {
642 * Write back memory ? -> clean cache
644 * There is no way to clean cache lines using
645 * cp15 scan chain, so copy the full cache
646 * line from cache to physical memory.
648 uint8_t data[32];
650 LOG_DEBUG("D-Cache in 'write back' mode, "
651 "flush cache line");
653 retval = target_read_memory(target,
654 address & cache_mask, 1,
655 sizeof(data), &data[0]);
656 if (retval != ERROR_OK)
657 return retval;
659 retval = armv4_5_mmu_write_physical(target,
660 &arm920t->armv4_5_mmu,
661 pa & cache_mask, 1,
662 sizeof(data), &data[0]);
663 if (retval != ERROR_OK)
664 return retval;
667 /* Cached ? */
668 if (cb & 0x2) {
670 * Cached ? -> Invalidate data cache using MVA
672 * MCR p15,0,Rd,c7,c6,1
674 LOG_DEBUG("D-Cache enabled, "
675 "invalidate cache line");
677 retval = arm920t_write_cp15_interpreted(target,
678 ARMV4_5_MCR(15, 0, 0, 7, 6, 1), 0x0,
679 address & cache_mask);
680 if (retval != ERROR_OK)
681 return retval;
685 /* write directly to physical memory,
686 * bypassing any read only MMU bits, etc.
688 retval = armv4_5_mmu_write_physical(target,
689 &arm920t->armv4_5_mmu, pa, size,
690 count, buffer);
691 if (retval != ERROR_OK)
692 return retval;
693 } else {
694 retval = arm7_9_write_memory(target, address, size, count, buffer);
695 if (retval != ERROR_OK)
696 return retval;
699 /* If ICache is enabled, we have to invalidate affected ICache lines
700 * the DCache is forced to write-through,
701 * so we don't have to clean it here
703 if (arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled) {
704 if (count <= 1) {
705 /* invalidate ICache single entry with MVA
706 * mcr 15, 0, r0, cr7, cr5, {1}
708 LOG_DEBUG("I-Cache enabled, "
709 "invalidating affected I-Cache line");
710 retval = arm920t_write_cp15_interpreted(target,
711 ARMV4_5_MCR(15, 0, 0, 7, 5, 1),
712 0x0, address & cache_mask);
713 if (retval != ERROR_OK)
714 return retval;
715 } else {
716 /* invalidate ICache
717 * mcr 15, 0, r0, cr7, cr5, {0}
719 retval = arm920t_write_cp15_interpreted(target,
720 ARMV4_5_MCR(15, 0, 0, 7, 5, 0),
721 0x0, 0x0);
722 if (retval != ERROR_OK)
723 return retval;
727 return ERROR_OK;
730 /* EXPORTED to FA256 */
731 int arm920t_soft_reset_halt(struct target *target)
733 int retval = ERROR_OK;
734 struct arm920t_common *arm920t = target_to_arm920(target);
735 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
736 struct arm *arm = &arm7_9->arm;
737 struct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
739 retval = target_halt(target);
740 if (retval != ERROR_OK)
741 return retval;
743 int64_t then = timeval_ms();
744 bool timeout;
745 while (!(timeout = ((timeval_ms()-then) > 1000))) {
746 if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0) {
747 embeddedice_read_reg(dbg_stat);
748 retval = jtag_execute_queue();
749 if (retval != ERROR_OK)
750 return retval;
751 } else
752 break;
753 if (debug_level >= 3) {
754 /* do not eat all CPU, time out after 1 se*/
755 alive_sleep(100);
756 } else
757 keep_alive();
759 if (timeout) {
760 LOG_ERROR("Failed to halt CPU after 1 sec");
761 return ERROR_TARGET_TIMEOUT;
764 target->state = TARGET_HALTED;
766 /* SVC, ARM state, IRQ and FIQ disabled */
767 uint32_t cpsr;
769 cpsr = buf_get_u32(arm->cpsr->value, 0, 32);
770 cpsr &= ~0xff;
771 cpsr |= 0xd3;
772 arm_set_cpsr(arm, cpsr);
773 arm->cpsr->dirty = true;
775 /* start fetching from 0x0 */
776 buf_set_u32(arm->pc->value, 0, 32, 0x0);
777 arm->pc->dirty = true;
778 arm->pc->valid = true;
780 arm920t_disable_mmu_caches(target, 1, 1, 1);
781 arm920t->armv4_5_mmu.mmu_enabled = 0;
782 arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;
783 arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;
785 return target_call_event_callbacks(target, TARGET_EVENT_HALTED);
788 /* FIXME remove forward decls */
789 static int arm920t_mrc(struct target *target, int cpnum,
790 uint32_t op1, uint32_t op2,
791 uint32_t crn, uint32_t crm,
792 uint32_t *value);
793 static int arm920t_mcr(struct target *target, int cpnum,
794 uint32_t op1, uint32_t op2,
795 uint32_t crn, uint32_t crm,
796 uint32_t value);
798 static int arm920t_init_arch_info(struct target *target,
799 struct arm920t_common *arm920t, struct jtag_tap *tap)
801 struct arm7_9_common *arm7_9 = &arm920t->arm7_9_common;
803 arm7_9->arm.mrc = arm920t_mrc;
804 arm7_9->arm.mcr = arm920t_mcr;
806 /* initialize arm7/arm9 specific info (including armv4_5) */
807 arm9tdmi_init_arch_info(target, arm7_9, tap);
809 arm920t->common_magic = ARM920T_COMMON_MAGIC;
811 arm7_9->post_debug_entry = arm920t_post_debug_entry;
812 arm7_9->pre_restore_context = arm920t_pre_restore_context;
813 arm7_9->write_memory = arm920t_write_memory;
815 arm920t->armv4_5_mmu.armv4_5_cache.ctype = -1;
816 arm920t->armv4_5_mmu.get_ttb = arm920t_get_ttb;
817 arm920t->armv4_5_mmu.read_memory = arm7_9_read_memory;
818 arm920t->armv4_5_mmu.write_memory = arm7_9_write_memory;
819 arm920t->armv4_5_mmu.disable_mmu_caches = arm920t_disable_mmu_caches;
820 arm920t->armv4_5_mmu.enable_mmu_caches = arm920t_enable_mmu_caches;
821 arm920t->armv4_5_mmu.has_tiny_pages = 1;
822 arm920t->armv4_5_mmu.mmu_enabled = 0;
824 /* disabling linefills leads to lockups, so keep them enabled for now
825 * this doesn't affect correctness, but might affect timing issues, if
826 * important data is evicted from the cache during the debug session
827 * */
828 arm920t->preserve_cache = 0;
830 /* override hw single-step capability from ARM9TDMI */
831 arm7_9->has_single_step = 1;
833 return ERROR_OK;
836 static int arm920t_target_create(struct target *target, Jim_Interp *interp)
838 struct arm920t_common *arm920t;
840 arm920t = calloc(1, sizeof(struct arm920t_common));
841 return arm920t_init_arch_info(target, arm920t, target->tap);
844 static void arm920t_deinit_target(struct target *target)
846 struct arm *arm = target_to_arm(target);
847 struct arm920t_common *arm920t = target_to_arm920(target);
849 arm7_9_deinit(target);
850 arm_free_reg_cache(arm);
851 free(arm920t);
854 COMMAND_HANDLER(arm920t_handle_read_cache_command)
856 int retval = ERROR_OK;
857 struct target *target = get_current_target(CMD_CTX);
858 struct arm920t_common *arm920t = target_to_arm920(target);
859 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
860 struct arm *arm = &arm7_9->arm;
861 uint32_t cp15c15;
862 uint32_t cp15_ctrl, cp15_ctrl_saved;
863 uint32_t regs[16];
864 uint32_t *regs_p[16];
865 uint32_t c15_c_d_ind, c15_c_i_ind;
866 int i;
867 FILE *output;
868 int segment, index_t;
869 struct reg *r;
871 retval = arm920t_verify_pointer(CMD, arm920t);
872 if (retval != ERROR_OK)
873 return retval;
875 if (CMD_ARGC != 1)
876 return ERROR_COMMAND_SYNTAX_ERROR;
878 output = fopen(CMD_ARGV[0], "w");
879 if (!output) {
880 LOG_DEBUG("error opening cache content file");
881 return ERROR_OK;
884 for (i = 0; i < 16; i++)
885 regs_p[i] = &regs[i];
887 /* disable MMU and Caches */
888 arm920t_read_cp15_physical(target, CP15PHYS_CTRL, &cp15_ctrl);
889 retval = jtag_execute_queue();
890 if (retval != ERROR_OK)
891 return retval;
892 cp15_ctrl_saved = cp15_ctrl;
893 cp15_ctrl &= ~(ARMV4_5_MMU_ENABLED
894 | ARMV4_5_D_U_CACHE_ENABLED | ARMV4_5_I_CACHE_ENABLED);
895 arm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_ctrl);
897 /* read CP15 test state register */
898 arm920t_read_cp15_physical(target, CP15PHYS_TESTSTATE, &cp15c15);
899 jtag_execute_queue();
901 /* read DCache content */
902 fprintf(output, "DCache:\n");
904 /* go through segments 0 to nsets (8 on ARM920T, 4 on ARM922T) */
905 for (segment = 0;
906 segment < arm920t->armv4_5_mmu.armv4_5_cache.d_u_size.nsets;
907 segment++) {
908 fprintf(output, "\nsegment: %i\n----------", segment);
910 /* Ra: r0 = SBZ(31:8):segment(7:5):SBZ(4:0) */
911 regs[0] = 0x0 | (segment << 5);
912 arm9tdmi_write_core_regs(target, 0x1, regs);
914 /* set interpret mode */
915 cp15c15 |= 0x1;
916 arm920t_write_cp15_physical(target,
917 CP15PHYS_TESTSTATE, cp15c15);
919 /* D CAM Read, loads current victim into C15.C.D.Ind */
920 arm920t_execute_cp15(target,
921 ARMV4_5_MCR(15, 2, 0, 15, 6, 2), ARMV4_5_LDR(1, 0));
923 /* read current victim */
924 arm920t_read_cp15_physical(target,
925 CP15PHYS_DCACHE_IDX, &c15_c_d_ind);
927 /* clear interpret mode */
928 cp15c15 &= ~0x1;
929 arm920t_write_cp15_physical(target,
930 CP15PHYS_TESTSTATE, cp15c15);
932 for (index_t = 0; index_t < 64; index_t++) {
933 /* Ra:
934 * r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0)
936 regs[0] = 0x0 | (segment << 5) | (index_t << 26);
937 arm9tdmi_write_core_regs(target, 0x1, regs);
939 /* set interpret mode */
940 cp15c15 |= 0x1;
941 arm920t_write_cp15_physical(target,
942 CP15PHYS_TESTSTATE, cp15c15);
944 /* Write DCache victim */
945 arm920t_execute_cp15(target,
946 ARMV4_5_MCR(15, 0, 0, 9, 1, 0), ARMV4_5_LDR(1, 0));
948 /* Read D RAM */
949 arm920t_execute_cp15(target,
950 ARMV4_5_MCR(15, 2, 0, 15, 10, 2),
951 ARMV4_5_LDMIA(0, 0x1fe, 0, 0));
953 /* Read D CAM */
954 arm920t_execute_cp15(target,
955 ARMV4_5_MCR(15, 2, 0, 15, 6, 2),
956 ARMV4_5_LDR(9, 0));
958 /* clear interpret mode */
959 cp15c15 &= ~0x1;
960 arm920t_write_cp15_physical(target,
961 CP15PHYS_TESTSTATE, cp15c15);
963 /* read D RAM and CAM content */
964 arm9tdmi_read_core_regs(target, 0x3fe, regs_p);
965 retval = jtag_execute_queue();
966 if (retval != ERROR_OK)
967 return retval;
969 /* mask LFSR[6] */
970 regs[9] &= 0xfffffffe;
971 fprintf(output, "\nsegment: %i, index: %i, CAM: 0x%8.8"
972 PRIx32 ", content (%s):\n",
973 segment, index_t, regs[9],
974 (regs[9] & 0x10) ? "valid" : "invalid");
976 for (i = 1; i < 9; i++) {
977 fprintf(output, "%i: 0x%8.8" PRIx32 "\n",
978 i-1, regs[i]);
983 /* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */
984 regs[0] = 0x0 | (segment << 5) | (c15_c_d_ind << 26);
985 arm9tdmi_write_core_regs(target, 0x1, regs);
987 /* set interpret mode */
988 cp15c15 |= 0x1;
989 arm920t_write_cp15_physical(target,
990 CP15PHYS_TESTSTATE, cp15c15);
992 /* Write DCache victim */
993 arm920t_execute_cp15(target,
994 ARMV4_5_MCR(15, 0, 0, 9, 1, 0), ARMV4_5_LDR(1, 0));
996 /* clear interpret mode */
997 cp15c15 &= ~0x1;
998 arm920t_write_cp15_physical(target,
999 CP15PHYS_TESTSTATE, cp15c15);
1002 /* read ICache content */
1003 fprintf(output, "ICache:\n");
1005 /* go through segments 0 to nsets (8 on ARM920T, 4 on ARM922T) */
1006 for (segment = 0;
1007 segment < arm920t->armv4_5_mmu.armv4_5_cache.d_u_size.nsets;
1008 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_t = 0; index_t < 64; index_t++) {
1034 /* Ra:
1035 * r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0)
1037 regs[0] = 0x0 | (segment << 5) | (index_t << 26);
1038 arm9tdmi_write_core_regs(target, 0x1, regs);
1040 /* set interpret mode */
1041 cp15c15 |= 0x1;
1042 arm920t_write_cp15_physical(target,
1043 CP15PHYS_TESTSTATE, cp15c15);
1045 /* Write ICache victim */
1046 arm920t_execute_cp15(target,
1047 ARMV4_5_MCR(15, 0, 0, 9, 1, 1), ARMV4_5_LDR(1, 0));
1049 /* Read I RAM */
1050 arm920t_execute_cp15(target,
1051 ARMV4_5_MCR(15, 2, 0, 15, 9, 2),
1052 ARMV4_5_LDMIA(0, 0x1fe, 0, 0));
1054 /* Read I CAM */
1055 arm920t_execute_cp15(target,
1056 ARMV4_5_MCR(15, 2, 0, 15, 5, 2),
1057 ARMV4_5_LDR(9, 0));
1059 /* clear interpret mode */
1060 cp15c15 &= ~0x1;
1061 arm920t_write_cp15_physical(target,
1062 CP15PHYS_TESTSTATE, cp15c15);
1064 /* read I RAM and CAM content */
1065 arm9tdmi_read_core_regs(target, 0x3fe, regs_p);
1066 retval = jtag_execute_queue();
1067 if (retval != ERROR_OK)
1068 return retval;
1070 /* mask LFSR[6] */
1071 regs[9] &= 0xfffffffe;
1072 fprintf(output, "\nsegment: %i, index: %i, "
1073 "CAM: 0x%8.8" PRIx32 ", content (%s):\n",
1074 segment, index_t, regs[9],
1075 (regs[9] & 0x10) ? "valid" : "invalid");
1077 for (i = 1; i < 9; i++) {
1078 fprintf(output, "%i: 0x%8.8" PRIx32 "\n",
1079 i-1, regs[i]);
1083 /* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */
1084 regs[0] = 0x0 | (segment << 5) | (c15_c_d_ind << 26);
1085 arm9tdmi_write_core_regs(target, 0x1, regs);
1087 /* set interpret mode */
1088 cp15c15 |= 0x1;
1089 arm920t_write_cp15_physical(target,
1090 CP15PHYS_TESTSTATE, cp15c15);
1092 /* Write ICache victim */
1093 arm920t_execute_cp15(target,
1094 ARMV4_5_MCR(15, 0, 0, 9, 1, 1), ARMV4_5_LDR(1, 0));
1096 /* clear interpret mode */
1097 cp15c15 &= ~0x1;
1098 arm920t_write_cp15_physical(target,
1099 CP15PHYS_TESTSTATE, cp15c15);
1102 /* restore CP15 MMU and Cache settings */
1103 arm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_ctrl_saved);
1105 command_print(CMD, "cache content successfully output to %s",
1106 CMD_ARGV[0]);
1108 fclose(output);
1110 if (!is_arm_mode(arm->core_mode)) {
1111 LOG_ERROR("not a valid arm core mode - communication failure?");
1112 return ERROR_FAIL;
1115 /* force writeback of the valid data */
1116 r = arm->core_cache->reg_list;
1117 r[0].dirty = r[0].valid;
1118 r[1].dirty = r[1].valid;
1119 r[2].dirty = r[2].valid;
1120 r[3].dirty = r[3].valid;
1121 r[4].dirty = r[4].valid;
1122 r[5].dirty = r[5].valid;
1123 r[6].dirty = r[6].valid;
1124 r[7].dirty = r[7].valid;
1126 r = arm_reg_current(arm, 8);
1127 r->dirty = r->valid;
1129 r = arm_reg_current(arm, 9);
1130 r->dirty = r->valid;
1132 return ERROR_OK;
1135 COMMAND_HANDLER(arm920t_handle_read_mmu_command)
1137 int retval = ERROR_OK;
1138 struct target *target = get_current_target(CMD_CTX);
1139 struct arm920t_common *arm920t = target_to_arm920(target);
1140 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
1141 struct arm *arm = &arm7_9->arm;
1142 uint32_t cp15c15;
1143 uint32_t cp15_ctrl, cp15_ctrl_saved;
1144 uint32_t regs[16];
1145 uint32_t *regs_p[16];
1146 int i;
1147 FILE *output;
1148 uint32_t d_lockdown, i_lockdown;
1149 struct arm920t_tlb_entry d_tlb[64], i_tlb[64];
1150 int victim;
1151 struct reg *r;
1153 retval = arm920t_verify_pointer(CMD, arm920t);
1154 if (retval != ERROR_OK)
1155 return retval;
1157 if (CMD_ARGC != 1)
1158 return ERROR_COMMAND_SYNTAX_ERROR;
1160 output = fopen(CMD_ARGV[0], "w");
1161 if (!output) {
1162 LOG_DEBUG("error opening mmu content file");
1163 return ERROR_OK;
1166 for (i = 0; i < 16; i++)
1167 regs_p[i] = &regs[i];
1169 /* disable MMU and Caches */
1170 arm920t_read_cp15_physical(target, CP15PHYS_CTRL, &cp15_ctrl);
1171 retval = jtag_execute_queue();
1172 if (retval != ERROR_OK)
1173 return retval;
1174 cp15_ctrl_saved = cp15_ctrl;
1175 cp15_ctrl &= ~(ARMV4_5_MMU_ENABLED
1176 | ARMV4_5_D_U_CACHE_ENABLED | ARMV4_5_I_CACHE_ENABLED);
1177 arm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_ctrl);
1179 /* read CP15 test state register */
1180 arm920t_read_cp15_physical(target, CP15PHYS_TESTSTATE, &cp15c15);
1181 retval = jtag_execute_queue();
1182 if (retval != ERROR_OK)
1183 return retval;
1185 /* prepare reading D TLB content
1186 * */
1188 /* set interpret mode */
1189 cp15c15 |= 0x1;
1190 arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);
1192 /* Read D TLB lockdown */
1193 arm920t_execute_cp15(target,
1194 ARMV4_5_MRC(15, 0, 0, 10, 0, 0), ARMV4_5_LDR(1, 0));
1196 /* clear interpret mode */
1197 cp15c15 &= ~0x1;
1198 arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);
1200 /* read D TLB lockdown stored to r1 */
1201 arm9tdmi_read_core_regs(target, 0x2, regs_p);
1202 retval = jtag_execute_queue();
1203 if (retval != ERROR_OK)
1204 return retval;
1205 d_lockdown = regs[1];
1207 for (victim = 0; victim < 64; victim += 8) {
1208 /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
1209 * base remains unchanged, victim goes through entries 0 to 63
1211 regs[1] = (d_lockdown & 0xfc000000) | (victim << 20);
1212 arm9tdmi_write_core_regs(target, 0x2, regs);
1214 /* set interpret mode */
1215 cp15c15 |= 0x1;
1216 arm920t_write_cp15_physical(target,
1217 CP15PHYS_TESTSTATE, cp15c15);
1219 /* Write D TLB lockdown */
1220 arm920t_execute_cp15(target,
1221 ARMV4_5_MCR(15, 0, 0, 10, 0, 0),
1222 ARMV4_5_STR(1, 0));
1224 /* Read D TLB CAM */
1225 arm920t_execute_cp15(target,
1226 ARMV4_5_MCR(15, 4, 0, 15, 6, 4),
1227 ARMV4_5_LDMIA(0, 0x3fc, 0, 0));
1229 /* clear interpret mode */
1230 cp15c15 &= ~0x1;
1231 arm920t_write_cp15_physical(target,
1232 CP15PHYS_TESTSTATE, cp15c15);
1234 /* read D TLB CAM content stored to r2-r9 */
1235 arm9tdmi_read_core_regs(target, 0x3fc, regs_p);
1236 retval = jtag_execute_queue();
1237 if (retval != ERROR_OK)
1238 return retval;
1240 for (i = 0; i < 8; i++)
1241 d_tlb[victim + i].cam = regs[i + 2];
1244 for (victim = 0; victim < 64; victim++) {
1245 /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
1246 * base remains unchanged, victim goes through entries 0 to 63
1248 regs[1] = (d_lockdown & 0xfc000000) | (victim << 20);
1249 arm9tdmi_write_core_regs(target, 0x2, regs);
1251 /* set interpret mode */
1252 cp15c15 |= 0x1;
1253 arm920t_write_cp15_physical(target,
1254 CP15PHYS_TESTSTATE, cp15c15);
1256 /* Write D TLB lockdown */
1257 arm920t_execute_cp15(target,
1258 ARMV4_5_MCR(15, 0, 0, 10, 0, 0), ARMV4_5_STR(1, 0));
1260 /* Read D TLB RAM1 */
1261 arm920t_execute_cp15(target,
1262 ARMV4_5_MCR(15, 4, 0, 15, 10, 4), ARMV4_5_LDR(2, 0));
1264 /* Read D TLB RAM2 */
1265 arm920t_execute_cp15(target,
1266 ARMV4_5_MCR(15, 4, 0, 15, 2, 5), ARMV4_5_LDR(3, 0));
1268 /* clear interpret mode */
1269 cp15c15 &= ~0x1;
1270 arm920t_write_cp15_physical(target,
1271 CP15PHYS_TESTSTATE, cp15c15);
1273 /* read D TLB RAM content stored to r2 and r3 */
1274 arm9tdmi_read_core_regs(target, 0xc, regs_p);
1275 retval = jtag_execute_queue();
1276 if (retval != ERROR_OK)
1277 return retval;
1279 d_tlb[victim].ram1 = regs[2];
1280 d_tlb[victim].ram2 = regs[3];
1283 /* restore D TLB lockdown */
1284 regs[1] = d_lockdown;
1285 arm9tdmi_write_core_regs(target, 0x2, regs);
1287 /* Write D TLB lockdown */
1288 arm920t_execute_cp15(target,
1289 ARMV4_5_MCR(15, 0, 0, 10, 0, 0), ARMV4_5_STR(1, 0));
1291 /* prepare reading I TLB content
1292 * */
1294 /* set interpret mode */
1295 cp15c15 |= 0x1;
1296 arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);
1298 /* Read I TLB lockdown */
1299 arm920t_execute_cp15(target,
1300 ARMV4_5_MRC(15, 0, 0, 10, 0, 1), ARMV4_5_LDR(1, 0));
1302 /* clear interpret mode */
1303 cp15c15 &= ~0x1;
1304 arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);
1306 /* read I TLB lockdown stored to r1 */
1307 arm9tdmi_read_core_regs(target, 0x2, regs_p);
1308 retval = jtag_execute_queue();
1309 if (retval != ERROR_OK)
1310 return retval;
1311 i_lockdown = regs[1];
1313 for (victim = 0; victim < 64; victim += 8) {
1314 /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
1315 * base remains unchanged, victim goes through entries 0 to 63
1317 regs[1] = (i_lockdown & 0xfc000000) | (victim << 20);
1318 arm9tdmi_write_core_regs(target, 0x2, regs);
1320 /* set interpret mode */
1321 cp15c15 |= 0x1;
1322 arm920t_write_cp15_physical(target,
1323 CP15PHYS_TESTSTATE, cp15c15);
1325 /* Write I TLB lockdown */
1326 arm920t_execute_cp15(target,
1327 ARMV4_5_MCR(15, 0, 0, 10, 0, 1),
1328 ARMV4_5_STR(1, 0));
1330 /* Read I TLB CAM */
1331 arm920t_execute_cp15(target,
1332 ARMV4_5_MCR(15, 4, 0, 15, 5, 4),
1333 ARMV4_5_LDMIA(0, 0x3fc, 0, 0));
1335 /* clear interpret mode */
1336 cp15c15 &= ~0x1;
1337 arm920t_write_cp15_physical(target,
1338 CP15PHYS_TESTSTATE, cp15c15);
1340 /* read I TLB CAM content stored to r2-r9 */
1341 arm9tdmi_read_core_regs(target, 0x3fc, regs_p);
1342 retval = jtag_execute_queue();
1343 if (retval != ERROR_OK)
1344 return retval;
1346 for (i = 0; i < 8; i++)
1347 i_tlb[i + victim].cam = regs[i + 2];
1350 for (victim = 0; victim < 64; victim++) {
1351 /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
1352 * base remains unchanged, victim goes through entries 0 to 63
1354 regs[1] = (d_lockdown & 0xfc000000) | (victim << 20);
1355 arm9tdmi_write_core_regs(target, 0x2, regs);
1357 /* set interpret mode */
1358 cp15c15 |= 0x1;
1359 arm920t_write_cp15_physical(target,
1360 CP15PHYS_TESTSTATE, cp15c15);
1362 /* Write I TLB lockdown */
1363 arm920t_execute_cp15(target,
1364 ARMV4_5_MCR(15, 0, 0, 10, 0, 1), ARMV4_5_STR(1, 0));
1366 /* Read I TLB RAM1 */
1367 arm920t_execute_cp15(target,
1368 ARMV4_5_MCR(15, 4, 0, 15, 9, 4), ARMV4_5_LDR(2, 0));
1370 /* Read I TLB RAM2 */
1371 arm920t_execute_cp15(target,
1372 ARMV4_5_MCR(15, 4, 0, 15, 1, 5), ARMV4_5_LDR(3, 0));
1374 /* clear interpret mode */
1375 cp15c15 &= ~0x1;
1376 arm920t_write_cp15_physical(target,
1377 CP15PHYS_TESTSTATE, cp15c15);
1379 /* read I TLB RAM content stored to r2 and r3 */
1380 arm9tdmi_read_core_regs(target, 0xc, regs_p);
1381 retval = jtag_execute_queue();
1382 if (retval != ERROR_OK)
1383 return retval;
1385 i_tlb[victim].ram1 = regs[2];
1386 i_tlb[victim].ram2 = regs[3];
1389 /* restore I TLB lockdown */
1390 regs[1] = i_lockdown;
1391 arm9tdmi_write_core_regs(target, 0x2, regs);
1393 /* Write I TLB lockdown */
1394 arm920t_execute_cp15(target,
1395 ARMV4_5_MCR(15, 0, 0, 10, 0, 1), ARMV4_5_STR(1, 0));
1397 /* restore CP15 MMU and Cache settings */
1398 arm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_ctrl_saved);
1400 /* output data to file */
1401 fprintf(output, "D TLB content:\n");
1402 for (i = 0; i < 64; i++) {
1403 fprintf(output, "%i: 0x%8.8" PRIx32 " 0x%8.8" PRIx32
1404 " 0x%8.8" PRIx32 " %s\n",
1405 i, d_tlb[i].cam, d_tlb[i].ram1, d_tlb[i].ram2,
1406 (d_tlb[i].cam & 0x20) ? "(valid)" : "(invalid)");
1409 fprintf(output, "\n\nI TLB content:\n");
1410 for (i = 0; i < 64; i++) {
1411 fprintf(output, "%i: 0x%8.8" PRIx32 " 0x%8.8" PRIx32
1412 " 0x%8.8" PRIx32 " %s\n",
1413 i, i_tlb[i].cam, i_tlb[i].ram1, i_tlb[i].ram2,
1414 (i_tlb[i].cam & 0x20) ? "(valid)" : "(invalid)");
1417 command_print(CMD, "mmu content successfully output to %s",
1418 CMD_ARGV[0]);
1420 fclose(output);
1422 if (!is_arm_mode(arm->core_mode)) {
1423 LOG_ERROR("not a valid arm core mode - communication failure?");
1424 return ERROR_FAIL;
1427 /* force writeback of the valid data */
1428 r = arm->core_cache->reg_list;
1429 r[0].dirty = r[0].valid;
1430 r[1].dirty = r[1].valid;
1431 r[2].dirty = r[2].valid;
1432 r[3].dirty = r[3].valid;
1433 r[4].dirty = r[4].valid;
1434 r[5].dirty = r[5].valid;
1435 r[6].dirty = r[6].valid;
1436 r[7].dirty = r[7].valid;
1438 r = arm_reg_current(arm, 8);
1439 r->dirty = r->valid;
1441 r = arm_reg_current(arm, 9);
1442 r->dirty = r->valid;
1444 return ERROR_OK;
1447 COMMAND_HANDLER(arm920t_handle_cp15_command)
1449 int retval;
1450 struct target *target = get_current_target(CMD_CTX);
1451 struct arm920t_common *arm920t = target_to_arm920(target);
1453 retval = arm920t_verify_pointer(CMD, arm920t);
1454 if (retval != ERROR_OK)
1455 return retval;
1457 if (target->state != TARGET_HALTED) {
1458 command_print(CMD, "Error: target must be stopped for "
1459 "\"%s\" command", CMD_NAME);
1460 return ERROR_TARGET_NOT_HALTED;
1463 /* one argument, read a register.
1464 * two arguments, write it.
1466 if (CMD_ARGC >= 1) {
1467 int address;
1468 COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], address);
1470 if (CMD_ARGC == 1) {
1471 uint32_t value;
1472 retval = arm920t_read_cp15_physical(target, address, &value);
1473 if (retval != ERROR_OK) {
1474 command_print(CMD,
1475 "couldn't access reg %i", address);
1476 return ERROR_OK;
1478 retval = jtag_execute_queue();
1479 if (retval != ERROR_OK)
1480 return retval;
1482 command_print(CMD, "%i: %8.8" PRIx32,
1483 address, value);
1484 } else if (CMD_ARGC == 2) {
1485 uint32_t value;
1486 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
1487 retval = arm920t_write_cp15_physical(target,
1488 address, value);
1489 if (retval != ERROR_OK) {
1490 command_print(CMD,
1491 "couldn't access reg %i", address);
1492 /* REVISIT why lie? "return retval"? */
1493 return ERROR_OK;
1495 command_print(CMD, "%i: %8.8" PRIx32,
1496 address, value);
1500 return ERROR_OK;
1503 COMMAND_HANDLER(arm920t_handle_cache_info_command)
1505 int retval;
1506 struct target *target = get_current_target(CMD_CTX);
1507 struct arm920t_common *arm920t = target_to_arm920(target);
1509 retval = arm920t_verify_pointer(CMD, arm920t);
1510 if (retval != ERROR_OK)
1511 return retval;
1513 return armv4_5_handle_cache_info_command(CMD,
1514 &arm920t->armv4_5_mmu.armv4_5_cache);
1518 static int arm920t_mrc(struct target *target, int cpnum,
1519 uint32_t op1, uint32_t op2,
1520 uint32_t crn, uint32_t crm,
1521 uint32_t *value)
1523 if (cpnum != 15) {
1524 LOG_ERROR("Only cp15 is supported");
1525 return ERROR_FAIL;
1528 /* read "to" r0 */
1529 return arm920t_read_cp15_interpreted(target,
1530 ARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2),
1531 0, value);
1534 static int arm920t_mcr(struct target *target, int cpnum,
1535 uint32_t op1, uint32_t op2,
1536 uint32_t crn, uint32_t crm,
1537 uint32_t value)
1539 if (cpnum != 15) {
1540 LOG_ERROR("Only cp15 is supported");
1541 return ERROR_FAIL;
1544 /* write "from" r0 */
1545 return arm920t_write_cp15_interpreted(target,
1546 ARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2),
1547 0, value);
1550 static const struct command_registration arm920t_exec_command_handlers[] = {
1552 .name = "cp15",
1553 .handler = arm920t_handle_cp15_command,
1554 .mode = COMMAND_EXEC,
1555 .help = "display/modify cp15 register",
1556 .usage = "regnum [value]",
1559 .name = "cache_info",
1560 .handler = arm920t_handle_cache_info_command,
1561 .mode = COMMAND_EXEC,
1562 .usage = "",
1563 .help = "display information about target caches",
1566 .name = "read_cache",
1567 .handler = arm920t_handle_read_cache_command,
1568 .mode = COMMAND_EXEC,
1569 .help = "dump I/D cache content to file",
1570 .usage = "filename",
1573 .name = "read_mmu",
1574 .handler = arm920t_handle_read_mmu_command,
1575 .mode = COMMAND_EXEC,
1576 .help = "dump I/D mmu content to file",
1577 .usage = "filename",
1579 COMMAND_REGISTRATION_DONE
1581 const struct command_registration arm920t_command_handlers[] = {
1583 .chain = arm9tdmi_command_handlers,
1586 .name = "arm920t",
1587 .mode = COMMAND_ANY,
1588 .help = "arm920t command group",
1589 .usage = "",
1590 .chain = arm920t_exec_command_handlers,
1592 COMMAND_REGISTRATION_DONE
1595 /** Holds methods for ARM920 targets. */
1596 struct target_type arm920t_target = {
1597 .name = "arm920t",
1599 .poll = arm7_9_poll,
1600 .arch_state = arm920t_arch_state,
1602 .target_request_data = arm7_9_target_request_data,
1604 .halt = arm7_9_halt,
1605 .resume = arm7_9_resume,
1606 .step = arm7_9_step,
1608 .assert_reset = arm7_9_assert_reset,
1609 .deassert_reset = arm7_9_deassert_reset,
1610 .soft_reset_halt = arm920t_soft_reset_halt,
1612 .get_gdb_arch = arm_get_gdb_arch,
1613 .get_gdb_reg_list = arm_get_gdb_reg_list,
1615 .read_memory = arm920t_read_memory,
1616 .write_memory = arm7_9_write_memory_opt,
1617 .read_phys_memory = arm920t_read_phys_memory,
1618 .write_phys_memory = arm920t_write_phys_memory,
1619 .mmu = arm920_mmu,
1620 .virt2phys = arm920_virt2phys,
1622 .checksum_memory = arm_checksum_memory,
1623 .blank_check_memory = arm_blank_check_memory,
1625 .run_algorithm = armv4_5_run_algorithm,
1627 .add_breakpoint = arm7_9_add_breakpoint,
1628 .remove_breakpoint = arm7_9_remove_breakpoint,
1629 .add_watchpoint = arm7_9_add_watchpoint,
1630 .remove_watchpoint = arm7_9_remove_watchpoint,
1632 .commands = arm920t_command_handlers,
1633 .target_create = arm920t_target_create,
1634 .init_target = arm9tdmi_init_target,
1635 .deinit_target = arm920t_deinit_target,
1636 .examine = arm7_9_examine,
1637 .check_reset = arm7_9_check_reset,