[RFC] target: Move bulk_write_memory to arm7_9
[openocd.git] / src / target / arm920t.c
1
2 /***************************************************************************
3 * Copyright (C) 2005 by Dominic Rath *
4 * Dominic.Rath@gmx.de *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
20 ***************************************************************************/
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include "arm920t.h"
27 #include <helper/time_support.h>
28 #include "target_type.h"
29 #include "register.h"
30 #include "arm_opcodes.h"
31
32 /*
33 * For information about the ARM920T, see ARM DDI 0151C especially
34 * Chapter 9 about debug support, which shows how to manipulate each
35 * of the different scan chains:
36 *
37 * 0 ... ARM920 signals, e.g. to rest of SOC (unused here)
38 * 1 ... debugging; watchpoint and breakpoint status, etc; also
39 * MMU and cache access in conjunction with scan chain 15
40 * 2 ... EmbeddedICE
41 * 3 ... external boundary scan (SoC-specific, unused here)
42 * 4 ... access to cache tag RAM
43 * 6 ... ETM9
44 * 15 ... access coprocessor 15, "physical" or "interpreted" modes
45 * "interpreted" works with a few actual MRC/MCR instructions
46 * "physical" provides register-like behaviors. Section 9.6.7
47 * covers these details.
48 *
49 * The ARM922T is similar, but with smaller caches (8K each, vs 16K).
50 */
51
52 #if 0
53 #define _DEBUG_INSTRUCTION_EXECUTION_
54 #endif
55
56 /* Table 9-8 shows scan chain 15 format during physical access mode, using a
57 * dedicated 6-bit address space (encoded in bits 33:38). Writes use one
58 * JTAG scan, while reads use two.
59 *
60 * Table 9-9 lists the thirteen registers which support physical access.
61 * ARM920T_CP15_PHYS_ADDR() constructs the 6-bit reg_addr parameter passed
62 * to arm920t_read_cp15_physical() and arm920t_write_cp15_physical().
63 *
64 * x == bit[38]
65 * y == bits[37:34]
66 * z == bit[33]
67 */
68 #define ARM920T_CP15_PHYS_ADDR(x, y, z) ((x << 5) | (y << 1) << (z))
69
70 /* Registers supporting physical Read access (from table 9-9) */
71 #define CP15PHYS_CACHETYPE ARM920T_CP15_PHYS_ADDR(0, 0x0, 1)
72 #define CP15PHYS_ICACHE_IDX ARM920T_CP15_PHYS_ADDR(1, 0xd, 1)
73 #define CP15PHYS_DCACHE_IDX ARM920T_CP15_PHYS_ADDR(1, 0xe, 1)
74 /* NOTE: several more registers support only physical read access */
75
76 /* Registers supporting physical Read/Write access (from table 9-9) */
77 #define CP15PHYS_CTRL ARM920T_CP15_PHYS_ADDR(0, 0x1, 0)
78 #define CP15PHYS_PID ARM920T_CP15_PHYS_ADDR(0, 0xd, 0)
79 #define CP15PHYS_TESTSTATE ARM920T_CP15_PHYS_ADDR(0, 0xf, 0)
80 #define CP15PHYS_ICACHE ARM920T_CP15_PHYS_ADDR(1, 0x1, 1)
81 #define CP15PHYS_DCACHE ARM920T_CP15_PHYS_ADDR(1, 0x2, 1)
82
83 static int arm920t_read_cp15_physical(struct target *target,
84 int reg_addr, uint32_t *value)
85 {
86 struct arm920t_common *arm920t = target_to_arm920(target);
87 struct arm_jtag *jtag_info;
88 struct scan_field fields[4];
89 uint8_t access_type_buf = 1;
90 uint8_t reg_addr_buf = reg_addr & 0x3f;
91 uint8_t nr_w_buf = 0;
92 int retval;
93
94 jtag_info = &arm920t->arm7_9_common.jtag_info;
95
96 retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);
97 if (retval != ERROR_OK)
98 return retval;
99 retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_IDLE);
100 if (retval != ERROR_OK)
101 return retval;
102
103 fields[0].num_bits = 1;
104 fields[0].out_value = &access_type_buf;
105 fields[0].in_value = NULL;
106
107 fields[1].num_bits = 32;
108 fields[1].out_value = NULL;
109 fields[1].in_value = NULL;
110
111 fields[2].num_bits = 6;
112 fields[2].out_value = &reg_addr_buf;
113 fields[2].in_value = NULL;
114
115 fields[3].num_bits = 1;
116 fields[3].out_value = &nr_w_buf;
117 fields[3].in_value = NULL;
118
119 jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
120
121 fields[1].in_value = (uint8_t *)value;
122
123 jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
124
125 jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)value);
126
127 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
128 jtag_execute_queue();
129 LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value);
130 #endif
131
132 return ERROR_OK;
133 }
134
135 static int arm920t_write_cp15_physical(struct target *target,
136 int reg_addr, uint32_t value)
137 {
138 struct arm920t_common *arm920t = target_to_arm920(target);
139 struct arm_jtag *jtag_info;
140 struct scan_field fields[4];
141 uint8_t access_type_buf = 1;
142 uint8_t reg_addr_buf = reg_addr & 0x3f;
143 uint8_t nr_w_buf = 1;
144 uint8_t value_buf[4];
145 int retval;
146
147 jtag_info = &arm920t->arm7_9_common.jtag_info;
148
149 buf_set_u32(value_buf, 0, 32, value);
150
151 retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);
152 if (retval != ERROR_OK)
153 return retval;
154 retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_IDLE);
155 if (retval != ERROR_OK)
156 return retval;
157
158 fields[0].num_bits = 1;
159 fields[0].out_value = &access_type_buf;
160 fields[0].in_value = NULL;
161
162 fields[1].num_bits = 32;
163 fields[1].out_value = value_buf;
164 fields[1].in_value = NULL;
165
166 fields[2].num_bits = 6;
167 fields[2].out_value = &reg_addr_buf;
168 fields[2].in_value = NULL;
169
170 fields[3].num_bits = 1;
171 fields[3].out_value = &nr_w_buf;
172 fields[3].in_value = NULL;
173
174 jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
175
176 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
177 LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, value);
178 #endif
179
180 return ERROR_OK;
181 }
182
183 /* See table 9-10 for scan chain 15 format during interpreted access mode.
184 * If the TESTSTATE register is set for interpreted access, certain CP15
185 * MRC and MCR instructions may be executed through scan chain 15.
186 *
187 * Tables 9-11, 9-12, and 9-13 show which MRC and MCR instructions can be
188 * executed using scan chain 15 interpreted mode.
189 */
190 static int arm920t_execute_cp15(struct target *target, uint32_t cp15_opcode,
191 uint32_t arm_opcode)
192 {
193 int retval;
194 struct arm920t_common *arm920t = target_to_arm920(target);
195 struct arm_jtag *jtag_info;
196 struct scan_field fields[4];
197 uint8_t access_type_buf = 0; /* interpreted access */
198 uint8_t reg_addr_buf = 0x0;
199 uint8_t nr_w_buf = 0;
200 uint8_t cp15_opcode_buf[4];
201
202 jtag_info = &arm920t->arm7_9_common.jtag_info;
203
204 retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);
205 if (retval != ERROR_OK)
206 return retval;
207 retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_IDLE);
208 if (retval != ERROR_OK)
209 return retval;
210
211 buf_set_u32(cp15_opcode_buf, 0, 32, cp15_opcode);
212
213 fields[0].num_bits = 1;
214 fields[0].out_value = &access_type_buf;
215 fields[0].in_value = NULL;
216
217 fields[1].num_bits = 32;
218 fields[1].out_value = cp15_opcode_buf;
219 fields[1].in_value = NULL;
220
221 fields[2].num_bits = 6;
222 fields[2].out_value = &reg_addr_buf;
223 fields[2].in_value = NULL;
224
225 fields[3].num_bits = 1;
226 fields[3].out_value = &nr_w_buf;
227 fields[3].in_value = NULL;
228
229 jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
230
231 arm9tdmi_clock_out(jtag_info, arm_opcode, 0, NULL, 0);
232 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
233 retval = arm7_9_execute_sys_speed(target);
234 if (retval != ERROR_OK)
235 return retval;
236
237 retval = jtag_execute_queue();
238 if (retval != ERROR_OK) {
239 LOG_ERROR("failed executing JTAG queue");
240 return retval;
241 }
242
243 return ERROR_OK;
244 }
245
246 static int arm920t_read_cp15_interpreted(struct target *target,
247 uint32_t cp15_opcode, uint32_t address, uint32_t *value)
248 {
249 struct arm *arm = target_to_arm(target);
250 uint32_t *regs_p[1];
251 uint32_t regs[2];
252 uint32_t cp15c15 = 0x0;
253 struct reg *r = arm->core_cache->reg_list;
254
255 /* load address into R1 */
256 regs[1] = address;
257 arm9tdmi_write_core_regs(target, 0x2, regs);
258
259 /* read-modify-write CP15 test state register
260 * to enable interpreted access mode */
261 arm920t_read_cp15_physical(target, CP15PHYS_TESTSTATE, &cp15c15);
262 jtag_execute_queue();
263 cp15c15 |= 1; /* set interpret mode */
264 arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);
265
266 /* execute CP15 instruction and ARM load (reading from coprocessor) */
267 arm920t_execute_cp15(target, cp15_opcode, ARMV4_5_LDR(0, 1));
268
269 /* disable interpreted access mode */
270 cp15c15 &= ~1U; /* clear interpret mode */
271 arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);
272
273 /* retrieve value from R0 */
274 regs_p[0] = value;
275 arm9tdmi_read_core_regs(target, 0x1, regs_p);
276 jtag_execute_queue();
277
278 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
279 LOG_DEBUG("cp15_opcode: %8.8x, address: %8.8x, value: %8.8x",
280 cp15_opcode, address, *value);
281 #endif
282
283 if (!is_arm_mode(arm->core_mode)) {
284 LOG_ERROR("not a valid arm core mode - communication failure?");
285 return ERROR_FAIL;
286 }
287
288 r[0].dirty = 1;
289 r[1].dirty = 1;
290
291 return ERROR_OK;
292 }
293
294 static
295 int arm920t_write_cp15_interpreted(struct target *target,
296 uint32_t cp15_opcode, uint32_t value, uint32_t address)
297 {
298 uint32_t cp15c15 = 0x0;
299 struct arm *arm = target_to_arm(target);
300 uint32_t regs[2];
301 struct reg *r = arm->core_cache->reg_list;
302
303 /* load value, address into R0, R1 */
304 regs[0] = value;
305 regs[1] = address;
306 arm9tdmi_write_core_regs(target, 0x3, regs);
307
308 /* read-modify-write CP15 test state register
309 * to enable interpreted access mode */
310 arm920t_read_cp15_physical(target, CP15PHYS_TESTSTATE, &cp15c15);
311 jtag_execute_queue();
312 cp15c15 |= 1; /* set interpret mode */
313 arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);
314
315 /* execute CP15 instruction and ARM store (writing to coprocessor) */
316 arm920t_execute_cp15(target, cp15_opcode, ARMV4_5_STR(0, 1));
317
318 /* disable interpreted access mode */
319 cp15c15 &= ~1U; /* set interpret mode */
320 arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);
321
322 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
323 LOG_DEBUG("cp15_opcode: %8.8x, value: %8.8x, address: %8.8x",
324 cp15_opcode, value, address);
325 #endif
326
327 if (!is_arm_mode(arm->core_mode)) {
328 LOG_ERROR("not a valid arm core mode - communication failure?");
329 return ERROR_FAIL;
330 }
331
332 r[0].dirty = 1;
333 r[1].dirty = 1;
334
335 return ERROR_OK;
336 }
337
338 /* EXPORTED to FA256 */
339 int arm920t_get_ttb(struct target *target, uint32_t *result)
340 {
341 int retval;
342 uint32_t ttb = 0x0;
343
344 retval = arm920t_read_cp15_interpreted(target,
345 /* FIXME use opcode macro */
346 0xeebf0f51, 0x0, &ttb);
347 if (retval != ERROR_OK)
348 return retval;
349
350 *result = ttb;
351 return ERROR_OK;
352 }
353
354 /* EXPORTED to FA256 */
355 int arm920t_disable_mmu_caches(struct target *target, int mmu,
356 int d_u_cache, int i_cache)
357 {
358 uint32_t cp15_control;
359 int retval;
360
361 /* read cp15 control register */
362 retval = arm920t_read_cp15_physical(target, CP15PHYS_CTRL, &cp15_control);
363 if (retval != ERROR_OK)
364 return retval;
365 retval = jtag_execute_queue();
366 if (retval != ERROR_OK)
367 return retval;
368
369 if (mmu)
370 cp15_control &= ~0x1U;
371
372 if (d_u_cache)
373 cp15_control &= ~0x4U;
374
375 if (i_cache)
376 cp15_control &= ~0x1000U;
377
378 retval = arm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_control);
379 return retval;
380 }
381
382 /* EXPORTED to FA256 */
383 int arm920t_enable_mmu_caches(struct target *target, int mmu,
384 int d_u_cache, int i_cache)
385 {
386 uint32_t cp15_control;
387 int retval;
388
389 /* read cp15 control register */
390 retval = arm920t_read_cp15_physical(target, CP15PHYS_CTRL, &cp15_control);
391 if (retval != ERROR_OK)
392 return retval;
393 retval = jtag_execute_queue();
394 if (retval != ERROR_OK)
395 return retval;
396
397 if (mmu)
398 cp15_control |= 0x1U;
399
400 if (d_u_cache)
401 cp15_control |= 0x4U;
402
403 if (i_cache)
404 cp15_control |= 0x1000U;
405
406 retval = arm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_control);
407 return retval;
408 }
409
410 /* EXPORTED to FA256 */
411 int arm920t_post_debug_entry(struct target *target)
412 {
413 uint32_t cp15c15;
414 struct arm920t_common *arm920t = target_to_arm920(target);
415 int retval;
416
417 /* examine cp15 control reg */
418 retval = arm920t_read_cp15_physical(target,
419 CP15PHYS_CTRL, &arm920t->cp15_control_reg);
420 if (retval != ERROR_OK)
421 return retval;
422 retval = jtag_execute_queue();
423 if (retval != ERROR_OK)
424 return retval;
425 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32, arm920t->cp15_control_reg);
426
427 if (arm920t->armv4_5_mmu.armv4_5_cache.ctype == -1) {
428 uint32_t cache_type_reg;
429 /* identify caches */
430 retval = arm920t_read_cp15_physical(target,
431 CP15PHYS_CACHETYPE, &cache_type_reg);
432 if (retval != ERROR_OK)
433 return retval;
434 retval = jtag_execute_queue();
435 if (retval != ERROR_OK)
436 return retval;
437 armv4_5_identify_cache(cache_type_reg,
438 &arm920t->armv4_5_mmu.armv4_5_cache);
439 }
440
441 arm920t->armv4_5_mmu.mmu_enabled =
442 (arm920t->cp15_control_reg & 0x1U) ? 1 : 0;
443 arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled =
444 (arm920t->cp15_control_reg & 0x4U) ? 1 : 0;
445 arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled =
446 (arm920t->cp15_control_reg & 0x1000U) ? 1 : 0;
447
448 /* save i/d fault status and address register
449 * FIXME use opcode macros */
450 retval = arm920t_read_cp15_interpreted(target, 0xee150f10, 0x0, &arm920t->d_fsr);
451 if (retval != ERROR_OK)
452 return retval;
453 retval = arm920t_read_cp15_interpreted(target, 0xee150f30, 0x0, &arm920t->i_fsr);
454 if (retval != ERROR_OK)
455 return retval;
456 retval = arm920t_read_cp15_interpreted(target, 0xee160f10, 0x0, &arm920t->d_far);
457 if (retval != ERROR_OK)
458 return retval;
459 retval = arm920t_read_cp15_interpreted(target, 0xee160f30, 0x0, &arm920t->i_far);
460 if (retval != ERROR_OK)
461 return retval;
462
463 LOG_DEBUG("D FSR: 0x%8.8" PRIx32 ", D FAR: 0x%8.8" PRIx32
464 ", I FSR: 0x%8.8" PRIx32 ", I FAR: 0x%8.8" PRIx32,
465 arm920t->d_fsr, arm920t->d_far, arm920t->i_fsr, arm920t->i_far);
466
467 if (arm920t->preserve_cache) {
468 /* read-modify-write CP15 test state register
469 * to disable I/D-cache linefills */
470 retval = arm920t_read_cp15_physical(target,
471 CP15PHYS_TESTSTATE, &cp15c15);
472 if (retval != ERROR_OK)
473 return retval;
474 retval = jtag_execute_queue();
475 if (retval != ERROR_OK)
476 return retval;
477 cp15c15 |= 0x600;
478 retval = arm920t_write_cp15_physical(target,
479 CP15PHYS_TESTSTATE, cp15c15);
480 if (retval != ERROR_OK)
481 return retval;
482 }
483 return ERROR_OK;
484 }
485
486 /* EXPORTED to FA256 */
487 void arm920t_pre_restore_context(struct target *target)
488 {
489 uint32_t cp15c15;
490 struct arm920t_common *arm920t = target_to_arm920(target);
491
492 /* restore i/d fault status and address register */
493 arm920t_write_cp15_interpreted(target, 0xee050f10, arm920t->d_fsr, 0x0);
494 arm920t_write_cp15_interpreted(target, 0xee050f30, arm920t->i_fsr, 0x0);
495 arm920t_write_cp15_interpreted(target, 0xee060f10, arm920t->d_far, 0x0);
496 arm920t_write_cp15_interpreted(target, 0xee060f30, arm920t->i_far, 0x0);
497
498 /* read-modify-write CP15 test state register
499 * to reenable I/D-cache linefills */
500 if (arm920t->preserve_cache) {
501 arm920t_read_cp15_physical(target,
502 CP15PHYS_TESTSTATE, &cp15c15);
503 jtag_execute_queue();
504 cp15c15 &= ~0x600U;
505 arm920t_write_cp15_physical(target,
506 CP15PHYS_TESTSTATE, cp15c15);
507 }
508 }
509
510 static const char arm920_not[] = "target is not an ARM920";
511
512 static int arm920t_verify_pointer(struct command_context *cmd_ctx,
513 struct arm920t_common *arm920t)
514 {
515 if (arm920t->common_magic != ARM920T_COMMON_MAGIC) {
516 command_print(cmd_ctx, arm920_not);
517 return ERROR_TARGET_INVALID;
518 }
519
520 return ERROR_OK;
521 }
522
523 /** Logs summary of ARM920 state for a halted target. */
524 int arm920t_arch_state(struct target *target)
525 {
526 static const char *state[] = {
527 "disabled", "enabled"
528 };
529
530 struct arm920t_common *arm920t = target_to_arm920(target);
531
532 if (arm920t->common_magic != ARM920T_COMMON_MAGIC) {
533 LOG_ERROR("BUG: %s", arm920_not);
534 return ERROR_TARGET_INVALID;
535 }
536
537 arm_arch_state(target);
538 LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
539 state[arm920t->armv4_5_mmu.mmu_enabled],
540 state[arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],
541 state[arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled]);
542
543 return ERROR_OK;
544 }
545
546 static int arm920_mmu(struct target *target, int *enabled)
547 {
548 if (target->state != TARGET_HALTED) {
549 LOG_ERROR("%s: target not halted", __func__);
550 return ERROR_TARGET_INVALID;
551 }
552
553 *enabled = target_to_arm920(target)->armv4_5_mmu.mmu_enabled;
554 return ERROR_OK;
555 }
556
557 static int arm920_virt2phys(struct target *target,
558 uint32_t virt, uint32_t *phys)
559 {
560 uint32_t cb;
561 struct arm920t_common *arm920t = target_to_arm920(target);
562
563 uint32_t ret;
564 int retval = armv4_5_mmu_translate_va(target,
565 &arm920t->armv4_5_mmu, virt, &cb, &ret);
566 if (retval != ERROR_OK)
567 return retval;
568 *phys = ret;
569 return ERROR_OK;
570 }
571
572 /** Reads a buffer, in the specified word size, with current MMU settings. */
573 int arm920t_read_memory(struct target *target, uint32_t address,
574 uint32_t size, uint32_t count, uint8_t *buffer)
575 {
576 int retval;
577
578 retval = arm7_9_read_memory(target, address, size, count, buffer);
579
580 return retval;
581 }
582
583
584 static int arm920t_read_phys_memory(struct target *target,
585 uint32_t address, uint32_t size,
586 uint32_t count, uint8_t *buffer)
587 {
588 struct arm920t_common *arm920t = target_to_arm920(target);
589
590 return armv4_5_mmu_read_physical(target, &arm920t->armv4_5_mmu,
591 address, size, count, buffer);
592 }
593
594 static int arm920t_write_phys_memory(struct target *target,
595 uint32_t address, uint32_t size,
596 uint32_t count, const uint8_t *buffer)
597 {
598 struct arm920t_common *arm920t = target_to_arm920(target);
599
600 return armv4_5_mmu_write_physical(target, &arm920t->armv4_5_mmu,
601 address, size, count, buffer);
602 }
603
604 /** Writes a buffer, in the specified word size, with current MMU settings. */
605 int arm920t_write_memory(struct target *target, uint32_t address,
606 uint32_t size, uint32_t count, const uint8_t *buffer)
607 {
608 int retval;
609 const uint32_t cache_mask = ~0x1f; /* cache line size : 32 byte */
610 struct arm920t_common *arm920t = target_to_arm920(target);
611
612 /* FIX!!!! this should be cleaned up and made much more general. The
613 * plan is to write up and test on arm920t specifically and
614 * then generalize and clean up afterwards.
615 *
616 * Also it should be moved to the callbacks that handle breakpoints
617 * specifically and not the generic memory write fn's. See XScale code.
618 */
619 if (arm920t->armv4_5_mmu.mmu_enabled && (count == 1) &&
620 ((size == 2) || (size == 4))) {
621 /* special case the handling of single word writes to
622 * bypass MMU, to allow implementation of breakpoints
623 * in memory marked read only
624 * by MMU
625 */
626 uint32_t cb;
627 uint32_t pa;
628
629 /*
630 * We need physical address and cb
631 */
632 retval = armv4_5_mmu_translate_va(target, &arm920t->armv4_5_mmu,
633 address, &cb, &pa);
634 if (retval != ERROR_OK)
635 return retval;
636
637 if (arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) {
638 if (cb & 0x1) {
639 LOG_DEBUG("D-Cache buffered, "
640 "drain write buffer");
641 /*
642 * Buffered ?
643 * Drain write buffer - MCR p15,0,Rd,c7,c10,4
644 */
645
646 retval = arm920t_write_cp15_interpreted(target,
647 ARMV4_5_MCR(15, 0, 0, 7, 10, 4),
648 0x0, 0);
649 if (retval != ERROR_OK)
650 return retval;
651 }
652
653 if (cb == 0x3) {
654 /*
655 * Write back memory ? -> clean cache
656 *
657 * There is no way to clean cache lines using
658 * cp15 scan chain, so copy the full cache
659 * line from cache to physical memory.
660 */
661 uint8_t data[32];
662
663 LOG_DEBUG("D-Cache in 'write back' mode, "
664 "flush cache line");
665
666 retval = target_read_memory(target,
667 address & cache_mask, 1,
668 sizeof(data), &data[0]);
669 if (retval != ERROR_OK)
670 return retval;
671
672 retval = armv4_5_mmu_write_physical(target,
673 &arm920t->armv4_5_mmu,
674 pa & cache_mask, 1,
675 sizeof(data), &data[0]);
676 if (retval != ERROR_OK)
677 return retval;
678 }
679
680 /* Cached ? */
681 if (cb & 0x2) {
682 /*
683 * Cached ? -> Invalidate data cache using MVA
684 *
685 * MCR p15,0,Rd,c7,c6,1
686 */
687 LOG_DEBUG("D-Cache enabled, "
688 "invalidate cache line");
689
690 retval = arm920t_write_cp15_interpreted(target,
691 ARMV4_5_MCR(15, 0, 0, 7, 6, 1), 0x0,
692 address & cache_mask);
693 if (retval != ERROR_OK)
694 return retval;
695 }
696 }
697
698 /* write directly to physical memory,
699 * bypassing any read only MMU bits, etc.
700 */
701 retval = armv4_5_mmu_write_physical(target,
702 &arm920t->armv4_5_mmu, pa, size,
703 count, buffer);
704 if (retval != ERROR_OK)
705 return retval;
706 } else {
707 retval = arm7_9_write_memory(target, address, size, count, buffer);
708 if (retval != ERROR_OK)
709 return retval;
710 }
711
712 /* If ICache is enabled, we have to invalidate affected ICache lines
713 * the DCache is forced to write-through,
714 * so we don't have to clean it here
715 */
716 if (arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled) {
717 if (count <= 1) {
718 /* invalidate ICache single entry with MVA
719 * mcr 15, 0, r0, cr7, cr5, {1}
720 */
721 LOG_DEBUG("I-Cache enabled, "
722 "invalidating affected I-Cache line");
723 retval = arm920t_write_cp15_interpreted(target,
724 ARMV4_5_MCR(15, 0, 0, 7, 5, 1),
725 0x0, address & cache_mask);
726 if (retval != ERROR_OK)
727 return retval;
728 } else {
729 /* invalidate ICache
730 * mcr 15, 0, r0, cr7, cr5, {0}
731 */
732 retval = arm920t_write_cp15_interpreted(target,
733 ARMV4_5_MCR(15, 0, 0, 7, 5, 0),
734 0x0, 0x0);
735 if (retval != ERROR_OK)
736 return retval;
737 }
738 }
739
740 return ERROR_OK;
741 }
742
743 int arm920t_write_memory_opt(struct target *target, uint32_t address,
744 uint32_t size, uint32_t count, const uint8_t *buffer)
745 {
746 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
747
748 if (size == 4 && count > 32 && arm7_9->bulk_write_memory)
749 return arm7_9->bulk_write_memory(target, address, count, buffer);
750 else
751 return arm920t_write_memory(target, address, size, count, buffer);
752 }
753
754 /* EXPORTED to FA256 */
755 int arm920t_soft_reset_halt(struct target *target)
756 {
757 int retval = ERROR_OK;
758 struct arm920t_common *arm920t = target_to_arm920(target);
759 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
760 struct arm *arm = &arm7_9->arm;
761 struct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
762
763 retval = target_halt(target);
764 if (retval != ERROR_OK)
765 return retval;
766
767 long long then = timeval_ms();
768 int timeout;
769 while (!(timeout = ((timeval_ms()-then) > 1000))) {
770 if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0) {
771 embeddedice_read_reg(dbg_stat);
772 retval = jtag_execute_queue();
773 if (retval != ERROR_OK)
774 return retval;
775 } else
776 break;
777 if (debug_level >= 3) {
778 /* do not eat all CPU, time out after 1 se*/
779 alive_sleep(100);
780 } else
781 keep_alive();
782 }
783 if (timeout) {
784 LOG_ERROR("Failed to halt CPU after 1 sec");
785 return ERROR_TARGET_TIMEOUT;
786 }
787
788 target->state = TARGET_HALTED;
789
790 /* SVC, ARM state, IRQ and FIQ disabled */
791 uint32_t cpsr;
792
793 cpsr = buf_get_u32(arm->cpsr->value, 0, 32);
794 cpsr &= ~0xff;
795 cpsr |= 0xd3;
796 arm_set_cpsr(arm, cpsr);
797 arm->cpsr->dirty = 1;
798
799 /* start fetching from 0x0 */
800 buf_set_u32(arm->pc->value, 0, 32, 0x0);
801 arm->pc->dirty = 1;
802 arm->pc->valid = 1;
803
804 arm920t_disable_mmu_caches(target, 1, 1, 1);
805 arm920t->armv4_5_mmu.mmu_enabled = 0;
806 arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;
807 arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;
808
809 return target_call_event_callbacks(target, TARGET_EVENT_HALTED);
810 }
811
812 /* FIXME remove forward decls */
813 static int arm920t_mrc(struct target *target, int cpnum,
814 uint32_t op1, uint32_t op2,
815 uint32_t CRn, uint32_t CRm,
816 uint32_t *value);
817 static int arm920t_mcr(struct target *target, int cpnum,
818 uint32_t op1, uint32_t op2,
819 uint32_t CRn, uint32_t CRm,
820 uint32_t value);
821
822 static int arm920t_init_arch_info(struct target *target,
823 struct arm920t_common *arm920t, struct jtag_tap *tap)
824 {
825 struct arm7_9_common *arm7_9 = &arm920t->arm7_9_common;
826
827 arm7_9->arm.mrc = arm920t_mrc;
828 arm7_9->arm.mcr = arm920t_mcr;
829
830 /* initialize arm7/arm9 specific info (including armv4_5) */
831 arm9tdmi_init_arch_info(target, arm7_9, tap);
832
833 arm920t->common_magic = ARM920T_COMMON_MAGIC;
834
835 arm7_9->post_debug_entry = arm920t_post_debug_entry;
836 arm7_9->pre_restore_context = arm920t_pre_restore_context;
837
838 arm920t->armv4_5_mmu.armv4_5_cache.ctype = -1;
839 arm920t->armv4_5_mmu.get_ttb = arm920t_get_ttb;
840 arm920t->armv4_5_mmu.read_memory = arm7_9_read_memory;
841 arm920t->armv4_5_mmu.write_memory = arm7_9_write_memory;
842 arm920t->armv4_5_mmu.disable_mmu_caches = arm920t_disable_mmu_caches;
843 arm920t->armv4_5_mmu.enable_mmu_caches = arm920t_enable_mmu_caches;
844 arm920t->armv4_5_mmu.has_tiny_pages = 1;
845 arm920t->armv4_5_mmu.mmu_enabled = 0;
846
847 /* disabling linefills leads to lockups, so keep them enabled for now
848 * this doesn't affect correctness, but might affect timing issues, if
849 * important data is evicted from the cache during the debug session
850 * */
851 arm920t->preserve_cache = 0;
852
853 /* override hw single-step capability from ARM9TDMI */
854 arm7_9->has_single_step = 1;
855
856 return ERROR_OK;
857 }
858
859 static int arm920t_target_create(struct target *target, Jim_Interp *interp)
860 {
861 struct arm920t_common *arm920t;
862
863 arm920t = calloc(1, sizeof(struct arm920t_common));
864 return arm920t_init_arch_info(target, arm920t, target->tap);
865 }
866
867 COMMAND_HANDLER(arm920t_handle_read_cache_command)
868 {
869 int retval = ERROR_OK;
870 struct target *target = get_current_target(CMD_CTX);
871 struct arm920t_common *arm920t = target_to_arm920(target);
872 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
873 struct arm *arm = &arm7_9->arm;
874 uint32_t cp15c15;
875 uint32_t cp15_ctrl, cp15_ctrl_saved;
876 uint32_t regs[16];
877 uint32_t *regs_p[16];
878 uint32_t C15_C_D_Ind, C15_C_I_Ind;
879 int i;
880 FILE *output;
881 int segment, index_t;
882 struct reg *r;
883
884 retval = arm920t_verify_pointer(CMD_CTX, arm920t);
885 if (retval != ERROR_OK)
886 return retval;
887
888 if (CMD_ARGC != 1)
889 return ERROR_COMMAND_SYNTAX_ERROR;
890
891 output = fopen(CMD_ARGV[0], "w");
892 if (output == NULL) {
893 LOG_DEBUG("error opening cache content file");
894 return ERROR_OK;
895 }
896
897 for (i = 0; i < 16; i++)
898 regs_p[i] = &regs[i];
899
900 /* disable MMU and Caches */
901 arm920t_read_cp15_physical(target, CP15PHYS_CTRL, &cp15_ctrl);
902 retval = jtag_execute_queue();
903 if (retval != ERROR_OK)
904 return retval;
905 cp15_ctrl_saved = cp15_ctrl;
906 cp15_ctrl &= ~(ARMV4_5_MMU_ENABLED
907 | ARMV4_5_D_U_CACHE_ENABLED | ARMV4_5_I_CACHE_ENABLED);
908 arm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_ctrl);
909
910 /* read CP15 test state register */
911 arm920t_read_cp15_physical(target, CP15PHYS_TESTSTATE, &cp15c15);
912 jtag_execute_queue();
913
914 /* read DCache content */
915 fprintf(output, "DCache:\n");
916
917 /* go through segments 0 to nsets (8 on ARM920T, 4 on ARM922T) */
918 for (segment = 0;
919 segment < arm920t->armv4_5_mmu.armv4_5_cache.d_u_size.nsets;
920 segment++) {
921 fprintf(output, "\nsegment: %i\n----------", segment);
922
923 /* Ra: r0 = SBZ(31:8):segment(7:5):SBZ(4:0) */
924 regs[0] = 0x0 | (segment << 5);
925 arm9tdmi_write_core_regs(target, 0x1, regs);
926
927 /* set interpret mode */
928 cp15c15 |= 0x1;
929 arm920t_write_cp15_physical(target,
930 CP15PHYS_TESTSTATE, cp15c15);
931
932 /* D CAM Read, loads current victim into C15.C.D.Ind */
933 arm920t_execute_cp15(target,
934 ARMV4_5_MCR(15, 2, 0, 15, 6, 2), ARMV4_5_LDR(1, 0));
935
936 /* read current victim */
937 arm920t_read_cp15_physical(target,
938 CP15PHYS_DCACHE_IDX, &C15_C_D_Ind);
939
940 /* clear interpret mode */
941 cp15c15 &= ~0x1;
942 arm920t_write_cp15_physical(target,
943 CP15PHYS_TESTSTATE, cp15c15);
944
945 for (index_t = 0; index_t < 64; index_t++) {
946 /* Ra:
947 * r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0)
948 */
949 regs[0] = 0x0 | (segment << 5) | (index_t << 26);
950 arm9tdmi_write_core_regs(target, 0x1, regs);
951
952 /* set interpret mode */
953 cp15c15 |= 0x1;
954 arm920t_write_cp15_physical(target,
955 CP15PHYS_TESTSTATE, cp15c15);
956
957 /* Write DCache victim */
958 arm920t_execute_cp15(target,
959 ARMV4_5_MCR(15, 0, 0, 9, 1, 0), ARMV4_5_LDR(1, 0));
960
961 /* Read D RAM */
962 arm920t_execute_cp15(target,
963 ARMV4_5_MCR(15, 2, 0, 15, 10, 2),
964 ARMV4_5_LDMIA(0, 0x1fe, 0, 0));
965
966 /* Read D CAM */
967 arm920t_execute_cp15(target,
968 ARMV4_5_MCR(15, 2, 0, 15, 6, 2),
969 ARMV4_5_LDR(9, 0));
970
971 /* clear interpret mode */
972 cp15c15 &= ~0x1;
973 arm920t_write_cp15_physical(target,
974 CP15PHYS_TESTSTATE, cp15c15);
975
976 /* read D RAM and CAM content */
977 arm9tdmi_read_core_regs(target, 0x3fe, regs_p);
978 retval = jtag_execute_queue();
979 if (retval != ERROR_OK)
980 return retval;
981
982 /* mask LFSR[6] */
983 regs[9] &= 0xfffffffe;
984 fprintf(output, "\nsegment: %i, index: %i, CAM: 0x%8.8"
985 PRIx32 ", content (%s):\n",
986 segment, index_t, regs[9],
987 (regs[9] & 0x10) ? "valid" : "invalid");
988
989 for (i = 1; i < 9; i++) {
990 fprintf(output, "%i: 0x%8.8" PRIx32 "\n",
991 i-1, regs[i]);
992 }
993
994 }
995
996 /* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */
997 regs[0] = 0x0 | (segment << 5) | (C15_C_D_Ind << 26);
998 arm9tdmi_write_core_regs(target, 0x1, regs);
999
1000 /* set interpret mode */
1001 cp15c15 |= 0x1;
1002 arm920t_write_cp15_physical(target,
1003 CP15PHYS_TESTSTATE, cp15c15);
1004
1005 /* Write DCache victim */
1006 arm920t_execute_cp15(target,
1007 ARMV4_5_MCR(15, 0, 0, 9, 1, 0), ARMV4_5_LDR(1, 0));
1008
1009 /* clear interpret mode */
1010 cp15c15 &= ~0x1;
1011 arm920t_write_cp15_physical(target,
1012 CP15PHYS_TESTSTATE, cp15c15);
1013 }
1014
1015 /* read ICache content */
1016 fprintf(output, "ICache:\n");
1017
1018 /* go through segments 0 to nsets (8 on ARM920T, 4 on ARM922T) */
1019 for (segment = 0;
1020 segment < arm920t->armv4_5_mmu.armv4_5_cache.d_u_size.nsets;
1021 segment++) {
1022 fprintf(output, "segment: %i\n----------", segment);
1023
1024 /* Ra: r0 = SBZ(31:8):segment(7:5):SBZ(4:0) */
1025 regs[0] = 0x0 | (segment << 5);
1026 arm9tdmi_write_core_regs(target, 0x1, regs);
1027
1028 /* set interpret mode */
1029 cp15c15 |= 0x1;
1030 arm920t_write_cp15_physical(target,
1031 CP15PHYS_TESTSTATE, cp15c15);
1032
1033 /* I CAM Read, loads current victim into C15.C.I.Ind */
1034 arm920t_execute_cp15(target,
1035 ARMV4_5_MCR(15, 2, 0, 15, 5, 2), ARMV4_5_LDR(1, 0));
1036
1037 /* read current victim */
1038 arm920t_read_cp15_physical(target, CP15PHYS_ICACHE_IDX,
1039 &C15_C_I_Ind);
1040
1041 /* clear interpret mode */
1042 cp15c15 &= ~0x1;
1043 arm920t_write_cp15_physical(target,
1044 CP15PHYS_TESTSTATE, cp15c15);
1045
1046 for (index_t = 0; index_t < 64; index_t++) {
1047 /* Ra:
1048 * r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0)
1049 */
1050 regs[0] = 0x0 | (segment << 5) | (index_t << 26);
1051 arm9tdmi_write_core_regs(target, 0x1, regs);
1052
1053 /* set interpret mode */
1054 cp15c15 |= 0x1;
1055 arm920t_write_cp15_physical(target,
1056 CP15PHYS_TESTSTATE, cp15c15);
1057
1058 /* Write ICache victim */
1059 arm920t_execute_cp15(target,
1060 ARMV4_5_MCR(15, 0, 0, 9, 1, 1), ARMV4_5_LDR(1, 0));
1061
1062 /* Read I RAM */
1063 arm920t_execute_cp15(target,
1064 ARMV4_5_MCR(15, 2, 0, 15, 9, 2),
1065 ARMV4_5_LDMIA(0, 0x1fe, 0, 0));
1066
1067 /* Read I CAM */
1068 arm920t_execute_cp15(target,
1069 ARMV4_5_MCR(15, 2, 0, 15, 5, 2),
1070 ARMV4_5_LDR(9, 0));
1071
1072 /* clear interpret mode */
1073 cp15c15 &= ~0x1;
1074 arm920t_write_cp15_physical(target,
1075 CP15PHYS_TESTSTATE, cp15c15);
1076
1077 /* read I RAM and CAM content */
1078 arm9tdmi_read_core_regs(target, 0x3fe, regs_p);
1079 retval = jtag_execute_queue();
1080 if (retval != ERROR_OK)
1081 return retval;
1082
1083 /* mask LFSR[6] */
1084 regs[9] &= 0xfffffffe;
1085 fprintf(output, "\nsegment: %i, index: %i, "
1086 "CAM: 0x%8.8" PRIx32 ", content (%s):\n",
1087 segment, index_t, regs[9],
1088 (regs[9] & 0x10) ? "valid" : "invalid");
1089
1090 for (i = 1; i < 9; i++) {
1091 fprintf(output, "%i: 0x%8.8" PRIx32 "\n",
1092 i-1, regs[i]);
1093 }
1094 }
1095
1096 /* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */
1097 regs[0] = 0x0 | (segment << 5) | (C15_C_D_Ind << 26);
1098 arm9tdmi_write_core_regs(target, 0x1, regs);
1099
1100 /* set interpret mode */
1101 cp15c15 |= 0x1;
1102 arm920t_write_cp15_physical(target,
1103 CP15PHYS_TESTSTATE, cp15c15);
1104
1105 /* Write ICache victim */
1106 arm920t_execute_cp15(target,
1107 ARMV4_5_MCR(15, 0, 0, 9, 1, 1), ARMV4_5_LDR(1, 0));
1108
1109 /* clear interpret mode */
1110 cp15c15 &= ~0x1;
1111 arm920t_write_cp15_physical(target,
1112 CP15PHYS_TESTSTATE, cp15c15);
1113 }
1114
1115 /* restore CP15 MMU and Cache settings */
1116 arm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_ctrl_saved);
1117
1118 command_print(CMD_CTX, "cache content successfully output to %s",
1119 CMD_ARGV[0]);
1120
1121 fclose(output);
1122
1123 if (!is_arm_mode(arm->core_mode)) {
1124 LOG_ERROR("not a valid arm core mode - communication failure?");
1125 return ERROR_FAIL;
1126 }
1127
1128 /* force writeback of the valid data */
1129 r = arm->core_cache->reg_list;
1130 r[0].dirty = r[0].valid;
1131 r[1].dirty = r[1].valid;
1132 r[2].dirty = r[2].valid;
1133 r[3].dirty = r[3].valid;
1134 r[4].dirty = r[4].valid;
1135 r[5].dirty = r[5].valid;
1136 r[6].dirty = r[6].valid;
1137 r[7].dirty = r[7].valid;
1138
1139 r = arm_reg_current(arm, 8);
1140 r->dirty = r->valid;
1141
1142 r = arm_reg_current(arm, 9);
1143 r->dirty = r->valid;
1144
1145 return ERROR_OK;
1146 }
1147
1148 COMMAND_HANDLER(arm920t_handle_read_mmu_command)
1149 {
1150 int retval = ERROR_OK;
1151 struct target *target = get_current_target(CMD_CTX);
1152 struct arm920t_common *arm920t = target_to_arm920(target);
1153 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
1154 struct arm *arm = &arm7_9->arm;
1155 uint32_t cp15c15;
1156 uint32_t cp15_ctrl, cp15_ctrl_saved;
1157 uint32_t regs[16];
1158 uint32_t *regs_p[16];
1159 int i;
1160 FILE *output;
1161 uint32_t Dlockdown, Ilockdown;
1162 struct arm920t_tlb_entry d_tlb[64], i_tlb[64];
1163 int victim;
1164 struct reg *r;
1165
1166 retval = arm920t_verify_pointer(CMD_CTX, arm920t);
1167 if (retval != ERROR_OK)
1168 return retval;
1169
1170 if (CMD_ARGC != 1)
1171 return ERROR_COMMAND_SYNTAX_ERROR;
1172
1173 output = fopen(CMD_ARGV[0], "w");
1174 if (output == NULL) {
1175 LOG_DEBUG("error opening mmu content file");
1176 return ERROR_OK;
1177 }
1178
1179 for (i = 0; i < 16; i++)
1180 regs_p[i] = &regs[i];
1181
1182 /* disable MMU and Caches */
1183 arm920t_read_cp15_physical(target, CP15PHYS_CTRL, &cp15_ctrl);
1184 retval = jtag_execute_queue();
1185 if (retval != ERROR_OK)
1186 return retval;
1187 cp15_ctrl_saved = cp15_ctrl;
1188 cp15_ctrl &= ~(ARMV4_5_MMU_ENABLED
1189 | ARMV4_5_D_U_CACHE_ENABLED | ARMV4_5_I_CACHE_ENABLED);
1190 arm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_ctrl);
1191
1192 /* read CP15 test state register */
1193 arm920t_read_cp15_physical(target, CP15PHYS_TESTSTATE, &cp15c15);
1194 retval = jtag_execute_queue();
1195 if (retval != ERROR_OK)
1196 return retval;
1197
1198 /* prepare reading D TLB content
1199 * */
1200
1201 /* set interpret mode */
1202 cp15c15 |= 0x1;
1203 arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);
1204
1205 /* Read D TLB lockdown */
1206 arm920t_execute_cp15(target,
1207 ARMV4_5_MRC(15, 0, 0, 10, 0, 0), ARMV4_5_LDR(1, 0));
1208
1209 /* clear interpret mode */
1210 cp15c15 &= ~0x1;
1211 arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);
1212
1213 /* read D TLB lockdown stored to r1 */
1214 arm9tdmi_read_core_regs(target, 0x2, regs_p);
1215 retval = jtag_execute_queue();
1216 if (retval != ERROR_OK)
1217 return retval;
1218 Dlockdown = regs[1];
1219
1220 for (victim = 0; victim < 64; victim += 8) {
1221 /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
1222 * base remains unchanged, victim goes through entries 0 to 63
1223 */
1224 regs[1] = (Dlockdown & 0xfc000000) | (victim << 20);
1225 arm9tdmi_write_core_regs(target, 0x2, regs);
1226
1227 /* set interpret mode */
1228 cp15c15 |= 0x1;
1229 arm920t_write_cp15_physical(target,
1230 CP15PHYS_TESTSTATE, cp15c15);
1231
1232 /* Write D TLB lockdown */
1233 arm920t_execute_cp15(target,
1234 ARMV4_5_MCR(15, 0, 0, 10, 0, 0),
1235 ARMV4_5_STR(1, 0));
1236
1237 /* Read D TLB CAM */
1238 arm920t_execute_cp15(target,
1239 ARMV4_5_MCR(15, 4, 0, 15, 6, 4),
1240 ARMV4_5_LDMIA(0, 0x3fc, 0, 0));
1241
1242 /* clear interpret mode */
1243 cp15c15 &= ~0x1;
1244 arm920t_write_cp15_physical(target,
1245 CP15PHYS_TESTSTATE, cp15c15);
1246
1247 /* read D TLB CAM content stored to r2-r9 */
1248 arm9tdmi_read_core_regs(target, 0x3fc, regs_p);
1249 retval = jtag_execute_queue();
1250 if (retval != ERROR_OK)
1251 return retval;
1252
1253 for (i = 0; i < 8; i++)
1254 d_tlb[victim + i].cam = regs[i + 2];
1255 }
1256
1257 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
1260 */
1261 regs[1] = (Dlockdown & 0xfc000000) | (victim << 20);
1262 arm9tdmi_write_core_regs(target, 0x2, regs);
1263
1264 /* set interpret mode */
1265 cp15c15 |= 0x1;
1266 arm920t_write_cp15_physical(target,
1267 CP15PHYS_TESTSTATE, cp15c15);
1268
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));
1272
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));
1276
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));
1280
1281 /* clear interpret mode */
1282 cp15c15 &= ~0x1;
1283 arm920t_write_cp15_physical(target,
1284 CP15PHYS_TESTSTATE, cp15c15);
1285
1286 /* read D TLB RAM content stored to r2 and r3 */
1287 arm9tdmi_read_core_regs(target, 0xc, regs_p);
1288 retval = jtag_execute_queue();
1289 if (retval != ERROR_OK)
1290 return retval;
1291
1292 d_tlb[victim].ram1 = regs[2];
1293 d_tlb[victim].ram2 = regs[3];
1294 }
1295
1296 /* restore D TLB lockdown */
1297 regs[1] = Dlockdown;
1298 arm9tdmi_write_core_regs(target, 0x2, regs);
1299
1300 /* Write D TLB lockdown */
1301 arm920t_execute_cp15(target,
1302 ARMV4_5_MCR(15, 0, 0, 10, 0, 0), ARMV4_5_STR(1, 0));
1303
1304 /* prepare reading I TLB content
1305 * */
1306
1307 /* set interpret mode */
1308 cp15c15 |= 0x1;
1309 arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);
1310
1311 /* Read I TLB lockdown */
1312 arm920t_execute_cp15(target,
1313 ARMV4_5_MRC(15, 0, 0, 10, 0, 1), ARMV4_5_LDR(1, 0));
1314
1315 /* clear interpret mode */
1316 cp15c15 &= ~0x1;
1317 arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);
1318
1319 /* read I TLB lockdown stored to r1 */
1320 arm9tdmi_read_core_regs(target, 0x2, regs_p);
1321 retval = jtag_execute_queue();
1322 if (retval != ERROR_OK)
1323 return retval;
1324 Ilockdown = regs[1];
1325
1326 for (victim = 0; victim < 64; victim += 8) {
1327 /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
1328 * base remains unchanged, victim goes through entries 0 to 63
1329 */
1330 regs[1] = (Ilockdown & 0xfc000000) | (victim << 20);
1331 arm9tdmi_write_core_regs(target, 0x2, regs);
1332
1333 /* set interpret mode */
1334 cp15c15 |= 0x1;
1335 arm920t_write_cp15_physical(target,
1336 CP15PHYS_TESTSTATE, cp15c15);
1337
1338 /* Write I TLB lockdown */
1339 arm920t_execute_cp15(target,
1340 ARMV4_5_MCR(15, 0, 0, 10, 0, 1),
1341 ARMV4_5_STR(1, 0));
1342
1343 /* Read I TLB CAM */
1344 arm920t_execute_cp15(target,
1345 ARMV4_5_MCR(15, 4, 0, 15, 5, 4),
1346 ARMV4_5_LDMIA(0, 0x3fc, 0, 0));
1347
1348 /* clear interpret mode */
1349 cp15c15 &= ~0x1;
1350 arm920t_write_cp15_physical(target,
1351 CP15PHYS_TESTSTATE, cp15c15);
1352
1353 /* read I TLB CAM content stored to r2-r9 */
1354 arm9tdmi_read_core_regs(target, 0x3fc, regs_p);
1355 retval = jtag_execute_queue();
1356 if (retval != ERROR_OK)
1357 return retval;
1358
1359 for (i = 0; i < 8; i++)
1360 i_tlb[i + victim].cam = regs[i + 2];
1361 }
1362
1363 for (victim = 0; victim < 64; victim++) {
1364 /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
1365 * base remains unchanged, victim goes through entries 0 to 63
1366 */
1367 regs[1] = (Dlockdown & 0xfc000000) | (victim << 20);
1368 arm9tdmi_write_core_regs(target, 0x2, regs);
1369
1370 /* set interpret mode */
1371 cp15c15 |= 0x1;
1372 arm920t_write_cp15_physical(target,
1373 CP15PHYS_TESTSTATE, cp15c15);
1374
1375 /* Write I TLB lockdown */
1376 arm920t_execute_cp15(target,
1377 ARMV4_5_MCR(15, 0, 0, 10, 0, 1), ARMV4_5_STR(1, 0));
1378
1379 /* Read I TLB RAM1 */
1380 arm920t_execute_cp15(target,
1381 ARMV4_5_MCR(15, 4, 0, 15, 9, 4), ARMV4_5_LDR(2, 0));
1382
1383 /* Read I TLB RAM2 */
1384 arm920t_execute_cp15(target,
1385 ARMV4_5_MCR(15, 4, 0, 15, 1, 5), ARMV4_5_LDR(3, 0));
1386
1387 /* clear interpret mode */
1388 cp15c15 &= ~0x1;
1389 arm920t_write_cp15_physical(target,
1390 CP15PHYS_TESTSTATE, cp15c15);
1391
1392 /* read I TLB RAM content stored to r2 and r3 */
1393 arm9tdmi_read_core_regs(target, 0xc, regs_p);
1394 retval = jtag_execute_queue();
1395 if (retval != ERROR_OK)
1396 return retval;
1397
1398 i_tlb[victim].ram1 = regs[2];
1399 i_tlb[victim].ram2 = regs[3];
1400 }
1401
1402 /* restore I TLB lockdown */
1403 regs[1] = Ilockdown;
1404 arm9tdmi_write_core_regs(target, 0x2, regs);
1405
1406 /* Write I TLB lockdown */
1407 arm920t_execute_cp15(target,
1408 ARMV4_5_MCR(15, 0, 0, 10, 0, 1), ARMV4_5_STR(1, 0));
1409
1410 /* restore CP15 MMU and Cache settings */
1411 arm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_ctrl_saved);
1412
1413 /* output data to file */
1414 fprintf(output, "D TLB content:\n");
1415 for (i = 0; i < 64; i++) {
1416 fprintf(output, "%i: 0x%8.8" PRIx32 " 0x%8.8" PRIx32
1417 " 0x%8.8" PRIx32 " %s\n",
1418 i, d_tlb[i].cam, d_tlb[i].ram1, d_tlb[i].ram2,
1419 (d_tlb[i].cam & 0x20) ? "(valid)" : "(invalid)");
1420 }
1421
1422 fprintf(output, "\n\nI TLB content:\n");
1423 for (i = 0; i < 64; i++) {
1424 fprintf(output, "%i: 0x%8.8" PRIx32 " 0x%8.8" PRIx32
1425 " 0x%8.8" PRIx32 " %s\n",
1426 i, i_tlb[i].cam, i_tlb[i].ram1, i_tlb[i].ram2,
1427 (i_tlb[i].cam & 0x20) ? "(valid)" : "(invalid)");
1428 }
1429
1430 command_print(CMD_CTX, "mmu content successfully output to %s",
1431 CMD_ARGV[0]);
1432
1433 fclose(output);
1434
1435 if (!is_arm_mode(arm->core_mode)) {
1436 LOG_ERROR("not a valid arm core mode - communication failure?");
1437 return ERROR_FAIL;
1438 }
1439
1440 /* force writeback of the valid data */
1441 r = arm->core_cache->reg_list;
1442 r[0].dirty = r[0].valid;
1443 r[1].dirty = r[1].valid;
1444 r[2].dirty = r[2].valid;
1445 r[3].dirty = r[3].valid;
1446 r[4].dirty = r[4].valid;
1447 r[5].dirty = r[5].valid;
1448 r[6].dirty = r[6].valid;
1449 r[7].dirty = r[7].valid;
1450
1451 r = arm_reg_current(arm, 8);
1452 r->dirty = r->valid;
1453
1454 r = arm_reg_current(arm, 9);
1455 r->dirty = r->valid;
1456
1457 return ERROR_OK;
1458 }
1459
1460 COMMAND_HANDLER(arm920t_handle_cp15_command)
1461 {
1462 int retval;
1463 struct target *target = get_current_target(CMD_CTX);
1464 struct arm920t_common *arm920t = target_to_arm920(target);
1465
1466 retval = arm920t_verify_pointer(CMD_CTX, arm920t);
1467 if (retval != ERROR_OK)
1468 return retval;
1469
1470 if (target->state != TARGET_HALTED) {
1471 command_print(CMD_CTX, "target must be stopped for "
1472 "\"%s\" command", CMD_NAME);
1473 return ERROR_OK;
1474 }
1475
1476 /* one argument, read a register.
1477 * two arguments, write it.
1478 */
1479 if (CMD_ARGC >= 1) {
1480 int address;
1481 COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], address);
1482
1483 if (CMD_ARGC == 1) {
1484 uint32_t value;
1485 retval = arm920t_read_cp15_physical(target, address, &value);
1486 if (retval != ERROR_OK) {
1487 command_print(CMD_CTX,
1488 "couldn't access reg %i", address);
1489 return ERROR_OK;
1490 }
1491 retval = jtag_execute_queue();
1492 if (retval != ERROR_OK)
1493 return retval;
1494
1495 command_print(CMD_CTX, "%i: %8.8" PRIx32,
1496 address, value);
1497 } else if (CMD_ARGC == 2) {
1498 uint32_t value;
1499 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
1500 retval = arm920t_write_cp15_physical(target,
1501 address, value);
1502 if (retval != ERROR_OK) {
1503 command_print(CMD_CTX,
1504 "couldn't access reg %i", address);
1505 /* REVISIT why lie? "return retval"? */
1506 return ERROR_OK;
1507 }
1508 command_print(CMD_CTX, "%i: %8.8" PRIx32,
1509 address, value);
1510 }
1511 }
1512
1513 return ERROR_OK;
1514 }
1515
1516 COMMAND_HANDLER(arm920t_handle_cp15i_command)
1517 {
1518 int retval;
1519 struct target *target = get_current_target(CMD_CTX);
1520 struct arm920t_common *arm920t = target_to_arm920(target);
1521
1522 retval = arm920t_verify_pointer(CMD_CTX, arm920t);
1523 if (retval != ERROR_OK)
1524 return retval;
1525
1526
1527 if (target->state != TARGET_HALTED) {
1528 command_print(CMD_CTX, "target must be stopped for "
1529 "\"%s\" command", CMD_NAME);
1530 return ERROR_OK;
1531 }
1532
1533 /* one argument, read a register.
1534 * two arguments, write it.
1535 */
1536 if (CMD_ARGC >= 1) {
1537 uint32_t opcode;
1538 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], opcode);
1539
1540 if (CMD_ARGC == 1) {
1541 uint32_t value;
1542 retval = arm920t_read_cp15_interpreted(target,
1543 opcode, 0x0, &value);
1544 if (retval != ERROR_OK) {
1545 command_print(CMD_CTX,
1546 "couldn't execute %8.8" PRIx32,
1547 opcode);
1548 /* REVISIT why lie? "return retval"? */
1549 return ERROR_OK;
1550 }
1551
1552 command_print(CMD_CTX, "%8.8" PRIx32 ": %8.8" PRIx32,
1553 opcode, value);
1554 } else if (CMD_ARGC == 2) {
1555 uint32_t value;
1556 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
1557 retval = arm920t_write_cp15_interpreted(target,
1558 opcode, value, 0);
1559 if (retval != ERROR_OK) {
1560 command_print(CMD_CTX,
1561 "couldn't execute %8.8" PRIx32,
1562 opcode);
1563 /* REVISIT why lie? "return retval"? */
1564 return ERROR_OK;
1565 }
1566 command_print(CMD_CTX, "%8.8" PRIx32 ": %8.8" PRIx32,
1567 opcode, value);
1568 } else if (CMD_ARGC == 3) {
1569 uint32_t value;
1570 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
1571 uint32_t address;
1572 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], address);
1573 retval = arm920t_write_cp15_interpreted(target,
1574 opcode, value, address);
1575 if (retval != ERROR_OK) {
1576 command_print(CMD_CTX,
1577 "couldn't execute %8.8" PRIx32, opcode);
1578 /* REVISIT why lie? "return retval"? */
1579 return ERROR_OK;
1580 }
1581 command_print(CMD_CTX, "%8.8" PRIx32 ": %8.8" PRIx32
1582 " %8.8" PRIx32, opcode, value, address);
1583 }
1584 } else
1585 return ERROR_COMMAND_SYNTAX_ERROR;
1586
1587 return ERROR_OK;
1588 }
1589
1590 COMMAND_HANDLER(arm920t_handle_cache_info_command)
1591 {
1592 int retval;
1593 struct target *target = get_current_target(CMD_CTX);
1594 struct arm920t_common *arm920t = target_to_arm920(target);
1595
1596 retval = arm920t_verify_pointer(CMD_CTX, arm920t);
1597 if (retval != ERROR_OK)
1598 return retval;
1599
1600 return armv4_5_handle_cache_info_command(CMD_CTX,
1601 &arm920t->armv4_5_mmu.armv4_5_cache);
1602 }
1603
1604
1605 static int arm920t_mrc(struct target *target, int cpnum,
1606 uint32_t op1, uint32_t op2,
1607 uint32_t CRn, uint32_t CRm,
1608 uint32_t *value)
1609 {
1610 if (cpnum != 15) {
1611 LOG_ERROR("Only cp15 is supported");
1612 return ERROR_FAIL;
1613 }
1614
1615 /* read "to" r0 */
1616 return arm920t_read_cp15_interpreted(target,
1617 ARMV4_5_MRC(cpnum, op1, 0, CRn, CRm, op2),
1618 0, value);
1619 }
1620
1621 static int arm920t_mcr(struct target *target, int cpnum,
1622 uint32_t op1, uint32_t op2,
1623 uint32_t CRn, uint32_t CRm,
1624 uint32_t value)
1625 {
1626 if (cpnum != 15) {
1627 LOG_ERROR("Only cp15 is supported");
1628 return ERROR_FAIL;
1629 }
1630
1631 /* write "from" r0 */
1632 return arm920t_write_cp15_interpreted(target,
1633 ARMV4_5_MCR(cpnum, op1, 0, CRn, CRm, op2),
1634 0, value);
1635 }
1636
1637 static const struct command_registration arm920t_exec_command_handlers[] = {
1638 {
1639 .name = "cp15",
1640 .handler = arm920t_handle_cp15_command,
1641 .mode = COMMAND_EXEC,
1642 .help = "display/modify cp15 register",
1643 .usage = "regnum [value]",
1644 },
1645 {
1646 .name = "cp15i",
1647 .handler = arm920t_handle_cp15i_command,
1648 .mode = COMMAND_EXEC,
1649 /* prefer using less error-prone "arm mcr" or "arm mrc" */
1650 .help = "display/modify cp15 register using ARM opcode"
1651 " (DEPRECATED)",
1652 .usage = "instruction [value [address]]",
1653 },
1654 {
1655 .name = "cache_info",
1656 .handler = arm920t_handle_cache_info_command,
1657 .mode = COMMAND_EXEC,
1658 .usage = "",
1659 .help = "display information about target caches",
1660 },
1661 {
1662 .name = "read_cache",
1663 .handler = arm920t_handle_read_cache_command,
1664 .mode = COMMAND_EXEC,
1665 .help = "dump I/D cache content to file",
1666 .usage = "filename",
1667 },
1668 {
1669 .name = "read_mmu",
1670 .handler = arm920t_handle_read_mmu_command,
1671 .mode = COMMAND_EXEC,
1672 .help = "dump I/D mmu content to file",
1673 .usage = "filename",
1674 },
1675 COMMAND_REGISTRATION_DONE
1676 };
1677 const struct command_registration arm920t_command_handlers[] = {
1678 {
1679 .chain = arm9tdmi_command_handlers,
1680 },
1681 {
1682 .name = "arm920t",
1683 .mode = COMMAND_ANY,
1684 .help = "arm920t command group",
1685 .usage = "",
1686 .chain = arm920t_exec_command_handlers,
1687 },
1688 COMMAND_REGISTRATION_DONE
1689 };
1690
1691 /** Holds methods for ARM920 targets. */
1692 struct target_type arm920t_target = {
1693 .name = "arm920t",
1694
1695 .poll = arm7_9_poll,
1696 .arch_state = arm920t_arch_state,
1697
1698 .target_request_data = arm7_9_target_request_data,
1699
1700 .halt = arm7_9_halt,
1701 .resume = arm7_9_resume,
1702 .step = arm7_9_step,
1703
1704 .assert_reset = arm7_9_assert_reset,
1705 .deassert_reset = arm7_9_deassert_reset,
1706 .soft_reset_halt = arm920t_soft_reset_halt,
1707
1708 .get_gdb_reg_list = arm_get_gdb_reg_list,
1709
1710 .read_memory = arm920t_read_memory,
1711 .write_memory = arm920t_write_memory_opt,
1712 .read_phys_memory = arm920t_read_phys_memory,
1713 .write_phys_memory = arm920t_write_phys_memory,
1714 .mmu = arm920_mmu,
1715 .virt2phys = arm920_virt2phys,
1716
1717 .checksum_memory = arm_checksum_memory,
1718 .blank_check_memory = arm_blank_check_memory,
1719
1720 .run_algorithm = armv4_5_run_algorithm,
1721
1722 .add_breakpoint = arm7_9_add_breakpoint,
1723 .remove_breakpoint = arm7_9_remove_breakpoint,
1724 .add_watchpoint = arm7_9_add_watchpoint,
1725 .remove_watchpoint = arm7_9_remove_watchpoint,
1726
1727 .commands = arm920t_command_handlers,
1728 .target_create = arm920t_target_create,
1729 .init_target = arm9tdmi_init_target,
1730 .examine = arm7_9_examine,
1731 .check_reset = arm7_9_check_reset,
1732 };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)