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

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)