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

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)