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

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)