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

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)