target: don't swap MMU/no-MMU work areas
[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 "time_support.h"
26 #include "target_type.h"
27
28
29 /*
30 * For information about the ARM920T, see ARM DDI 0151C especially
31 * Chapter 9 about debug support, which shows how to manipulate each
32 * of the different scan chains:
33 *
34 * 0 ... ARM920 signals, e.g. to rest of SOC (unused here)
35 * 1 ... debugging; watchpoint and breakpoint status, etc; also
36 * MMU and cache access in conjunction with scan chain 15
37 * 2 ... EmbeddedICE
38 * 3 ... external boundary scan (SoC-specific, unused here)
39 * 4 ... access to cache tag RAM
40 * 6 ... ETM9
41 * 15 ... access coprocessor 15, "physical" or "interpreted" modes
42 * "interpreted" works with a few actual MRC/MCR instructions
43 * "physical" provides register-like behaviors.
44 *
45 * The ARM922T is similar, but with smaller caches (8K each, vs 16K).
46 */
47
48 #if 0
49 #define _DEBUG_INSTRUCTION_EXECUTION_
50 #endif
51
52 #define ARM920T_CP15_PHYS_ADDR(x, y, z) ((x << 5) | (y << 1) << (z))
53
54 static int arm920t_read_cp15_physical(target_t *target,
55 int reg_addr, uint32_t *value)
56 {
57 struct arm920t_common_s *arm920t = target_to_arm920(target);
58 arm_jtag_t *jtag_info;
59 scan_field_t fields[4];
60 uint8_t access_type_buf = 1;
61 uint8_t reg_addr_buf = reg_addr & 0x3f;
62 uint8_t nr_w_buf = 0;
63
64 jtag_info = &arm920t->arm9tdmi_common.arm7_9_common.jtag_info;
65
66 jtag_set_end_state(TAP_IDLE);
67 arm_jtag_scann(jtag_info, 0xf);
68 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
69
70 fields[0].tap = jtag_info->tap;
71 fields[0].num_bits = 1;
72 fields[0].out_value = &access_type_buf;
73 fields[0].in_value = NULL;
74
75 fields[1].tap = jtag_info->tap;
76 fields[1].num_bits = 32;
77 fields[1].out_value = NULL;
78 fields[1].in_value = NULL;
79
80 fields[2].tap = jtag_info->tap;
81 fields[2].num_bits = 6;
82 fields[2].out_value = &reg_addr_buf;
83 fields[2].in_value = NULL;
84
85 fields[3].tap = jtag_info->tap;
86 fields[3].num_bits = 1;
87 fields[3].out_value = &nr_w_buf;
88 fields[3].in_value = NULL;
89
90 jtag_add_dr_scan(4, fields, jtag_get_end_state());
91
92 fields[1].in_value = (uint8_t *)value;
93
94 jtag_add_dr_scan(4, fields, jtag_get_end_state());
95
96 jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)value);
97
98 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
99 jtag_execute_queue();
100 LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value);
101 #endif
102
103 return ERROR_OK;
104 }
105
106 static int arm920t_write_cp15_physical(target_t *target,
107 int reg_addr, uint32_t value)
108 {
109 struct arm920t_common_s *arm920t = target_to_arm920(target);
110 arm_jtag_t *jtag_info;
111 scan_field_t fields[4];
112 uint8_t access_type_buf = 1;
113 uint8_t reg_addr_buf = reg_addr & 0x3f;
114 uint8_t nr_w_buf = 1;
115 uint8_t value_buf[4];
116
117 jtag_info = &arm920t->arm9tdmi_common.arm7_9_common.jtag_info;
118
119 buf_set_u32(value_buf, 0, 32, value);
120
121 jtag_set_end_state(TAP_IDLE);
122 arm_jtag_scann(jtag_info, 0xf);
123 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
124
125 fields[0].tap = jtag_info->tap;
126 fields[0].num_bits = 1;
127 fields[0].out_value = &access_type_buf;
128 fields[0].in_value = NULL;
129
130 fields[1].tap = jtag_info->tap;
131 fields[1].num_bits = 32;
132 fields[1].out_value = value_buf;
133 fields[1].in_value = NULL;
134
135 fields[2].tap = jtag_info->tap;
136 fields[2].num_bits = 6;
137 fields[2].out_value = &reg_addr_buf;
138 fields[2].in_value = NULL;
139
140 fields[3].tap = jtag_info->tap;
141 fields[3].num_bits = 1;
142 fields[3].out_value = &nr_w_buf;
143 fields[3].in_value = NULL;
144
145 jtag_add_dr_scan(4, fields, jtag_get_end_state());
146
147 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
148 LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, value);
149 #endif
150
151 return ERROR_OK;
152 }
153
154 static int arm920t_execute_cp15(target_t *target, uint32_t cp15_opcode,
155 uint32_t arm_opcode)
156 {
157 int retval;
158 struct arm920t_common_s *arm920t = target_to_arm920(target);
159 arm_jtag_t *jtag_info;
160 scan_field_t fields[4];
161 uint8_t access_type_buf = 0; /* interpreted access */
162 uint8_t reg_addr_buf = 0x0;
163 uint8_t nr_w_buf = 0;
164 uint8_t cp15_opcode_buf[4];
165
166 jtag_info = &arm920t->arm9tdmi_common.arm7_9_common.jtag_info;
167
168 jtag_set_end_state(TAP_IDLE);
169 arm_jtag_scann(jtag_info, 0xf);
170 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
171
172 buf_set_u32(cp15_opcode_buf, 0, 32, cp15_opcode);
173
174 fields[0].tap = jtag_info->tap;
175 fields[0].num_bits = 1;
176 fields[0].out_value = &access_type_buf;
177 fields[0].in_value = NULL;
178
179 fields[1].tap = jtag_info->tap;
180 fields[1].num_bits = 32;
181 fields[1].out_value = cp15_opcode_buf;
182 fields[1].in_value = NULL;
183
184 fields[2].tap = jtag_info->tap;
185 fields[2].num_bits = 6;
186 fields[2].out_value = &reg_addr_buf;
187 fields[2].in_value = NULL;
188
189 fields[3].tap = jtag_info->tap;
190 fields[3].num_bits = 1;
191 fields[3].out_value = &nr_w_buf;
192 fields[3].in_value = NULL;
193
194 jtag_add_dr_scan(4, fields, jtag_get_end_state());
195
196 arm9tdmi_clock_out(jtag_info, arm_opcode, 0, NULL, 0);
197 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
198 retval = arm7_9_execute_sys_speed(target);
199 if (retval != ERROR_OK)
200 return retval;
201
202 if ((retval = jtag_execute_queue()) != ERROR_OK)
203 {
204 LOG_ERROR("failed executing JTAG queue");
205 return retval;
206 }
207
208 return ERROR_OK;
209 }
210
211 static int arm920t_read_cp15_interpreted(target_t *target,
212 uint32_t cp15_opcode, uint32_t address, uint32_t *value)
213 {
214 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
215 uint32_t* regs_p[1];
216 uint32_t regs[2];
217 uint32_t cp15c15 = 0x0;
218
219 /* load address into R1 */
220 regs[1] = address;
221 arm9tdmi_write_core_regs(target, 0x2, regs);
222
223 /* read-modify-write CP15 test state register
224 * to enable interpreted access mode */
225 arm920t_read_cp15_physical(target, 0x1e, &cp15c15);
226 jtag_execute_queue();
227 cp15c15 |= 1; /* set interpret mode */
228 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
229
230 /* execute CP15 instruction and ARM load (reading from coprocessor) */
231 arm920t_execute_cp15(target, cp15_opcode, ARMV4_5_LDR(0, 1));
232
233 /* disable interpreted access mode */
234 cp15c15 &= ~1U; /* clear interpret mode */
235 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
236
237 /* retrieve value from R0 */
238 regs_p[0] = value;
239 arm9tdmi_read_core_regs(target, 0x1, regs_p);
240 jtag_execute_queue();
241
242 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
243 LOG_DEBUG("cp15_opcode: %8.8x, address: %8.8x, value: %8.8x", cp15_opcode, address, *value);
244 #endif
245
246 if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
247 return ERROR_FAIL;
248
249 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).dirty = 1;
250 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 1).dirty = 1;
251
252 return ERROR_OK;
253 }
254
255 static
256 int arm920t_write_cp15_interpreted(target_t *target,
257 uint32_t cp15_opcode, uint32_t value, uint32_t address)
258 {
259 uint32_t cp15c15 = 0x0;
260 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
261 uint32_t regs[2];
262
263 /* load value, address into R0, R1 */
264 regs[0] = value;
265 regs[1] = address;
266 arm9tdmi_write_core_regs(target, 0x3, regs);
267
268 /* read-modify-write CP15 test state register
269 * to enable interpreted access mode */
270 arm920t_read_cp15_physical(target, 0x1e, &cp15c15);
271 jtag_execute_queue();
272 cp15c15 |= 1; /* set interpret mode */
273 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
274
275 /* execute CP15 instruction and ARM store (writing to coprocessor) */
276 arm920t_execute_cp15(target, cp15_opcode, ARMV4_5_STR(0, 1));
277
278 /* disable interpreted access mode */
279 cp15c15 &= ~1U; /* set interpret mode */
280 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
281
282 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
283 LOG_DEBUG("cp15_opcode: %8.8x, value: %8.8x, address: %8.8x", cp15_opcode, value, address);
284 #endif
285
286 if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
287 return ERROR_FAIL;
288
289 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).dirty = 1;
290 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 1).dirty = 1;
291
292 return ERROR_OK;
293 }
294
295 // EXPORTED to FA256
296 uint32_t arm920t_get_ttb(target_t *target)
297 {
298 int retval;
299 uint32_t ttb = 0x0;
300
301 if ((retval = arm920t_read_cp15_interpreted(target, 0xeebf0f51, 0x0, &ttb)) != ERROR_OK)
302 return retval;
303
304 return ttb;
305 }
306
307 // EXPORTED to FA256
308 void arm920t_disable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
309 {
310 uint32_t cp15_control;
311
312 /* read cp15 control register */
313 arm920t_read_cp15_physical(target, 0x2, &cp15_control);
314 jtag_execute_queue();
315
316 if (mmu)
317 cp15_control &= ~0x1U;
318
319 if (d_u_cache)
320 cp15_control &= ~0x4U;
321
322 if (i_cache)
323 cp15_control &= ~0x1000U;
324
325 arm920t_write_cp15_physical(target, 0x2, cp15_control);
326 }
327
328 // EXPORTED to FA256
329 void arm920t_enable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
330 {
331 uint32_t cp15_control;
332
333 /* read cp15 control register */
334 arm920t_read_cp15_physical(target, 0x2, &cp15_control);
335 jtag_execute_queue();
336
337 if (mmu)
338 cp15_control |= 0x1U;
339
340 if (d_u_cache)
341 cp15_control |= 0x4U;
342
343 if (i_cache)
344 cp15_control |= 0x1000U;
345
346 arm920t_write_cp15_physical(target, 0x2, cp15_control);
347 }
348
349 // EXPORTED to FA256
350 void arm920t_post_debug_entry(target_t *target)
351 {
352 uint32_t cp15c15;
353 struct arm920t_common_s *arm920t = target_to_arm920(target);
354
355 /* examine cp15 control reg */
356 arm920t_read_cp15_physical(target, 0x2, &arm920t->cp15_control_reg);
357 jtag_execute_queue();
358 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32 "", arm920t->cp15_control_reg);
359
360 if (arm920t->armv4_5_mmu.armv4_5_cache.ctype == -1)
361 {
362 uint32_t cache_type_reg;
363 /* identify caches */
364 arm920t_read_cp15_physical(target, 0x1, &cache_type_reg);
365 jtag_execute_queue();
366 armv4_5_identify_cache(cache_type_reg, &arm920t->armv4_5_mmu.armv4_5_cache);
367 }
368
369 arm920t->armv4_5_mmu.mmu_enabled = (arm920t->cp15_control_reg & 0x1U) ? 1 : 0;
370 arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = (arm920t->cp15_control_reg & 0x4U) ? 1 : 0;
371 arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = (arm920t->cp15_control_reg & 0x1000U) ? 1 : 0;
372
373 /* save i/d fault status and address register */
374 arm920t_read_cp15_interpreted(target, 0xee150f10, 0x0, &arm920t->d_fsr);
375 arm920t_read_cp15_interpreted(target, 0xee150f30, 0x0, &arm920t->i_fsr);
376 arm920t_read_cp15_interpreted(target, 0xee160f10, 0x0, &arm920t->d_far);
377 arm920t_read_cp15_interpreted(target, 0xee160f30, 0x0, &arm920t->i_far);
378
379 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 "",
380 arm920t->d_fsr, arm920t->d_far, arm920t->i_fsr, arm920t->i_far);
381
382 if (arm920t->preserve_cache)
383 {
384 /* read-modify-write CP15 test state register
385 * to disable I/D-cache linefills */
386 arm920t_read_cp15_physical(target, 0x1e, &cp15c15);
387 jtag_execute_queue();
388 cp15c15 |= 0x600;
389 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
390 }
391 }
392
393 // EXPORTED to FA256
394 void arm920t_pre_restore_context(target_t *target)
395 {
396 uint32_t cp15c15;
397 struct arm920t_common_s *arm920t = target_to_arm920(target);
398
399 /* restore i/d fault status and address register */
400 arm920t_write_cp15_interpreted(target, 0xee050f10, arm920t->d_fsr, 0x0);
401 arm920t_write_cp15_interpreted(target, 0xee050f30, arm920t->i_fsr, 0x0);
402 arm920t_write_cp15_interpreted(target, 0xee060f10, arm920t->d_far, 0x0);
403 arm920t_write_cp15_interpreted(target, 0xee060f30, arm920t->i_far, 0x0);
404
405 /* read-modify-write CP15 test state register
406 * to reenable I/D-cache linefills */
407 if (arm920t->preserve_cache)
408 {
409 arm920t_read_cp15_physical(target, 0x1e, &cp15c15);
410 jtag_execute_queue();
411 cp15c15 &= ~0x600U;
412 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
413 }
414 }
415
416 static const char arm920_not[] = "target is not an ARM920";
417
418 static int arm920t_verify_pointer(struct command_context_s *cmd_ctx,
419 struct arm920t_common_s *arm920t)
420 {
421 if (arm920t->common_magic != ARM920T_COMMON_MAGIC) {
422 command_print(cmd_ctx, arm920_not);
423 return ERROR_TARGET_INVALID;
424 }
425
426 return ERROR_OK;
427 }
428
429 /** Logs summary of ARM920 state for a halted target. */
430 int arm920t_arch_state(struct target_s *target)
431 {
432 static const char *state[] =
433 {
434 "disabled", "enabled"
435 };
436
437 struct arm920t_common_s *arm920t = target_to_arm920(target);
438 struct armv4_5_common_s *armv4_5;
439
440 if (arm920t->common_magic != ARM920T_COMMON_MAGIC)
441 {
442 LOG_ERROR("BUG: %s", arm920_not);
443 return ERROR_TARGET_INVALID;
444 }
445
446 armv4_5 = &arm920t->arm9tdmi_common.arm7_9_common.armv4_5_common;
447
448 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
449 "cpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "\n"
450 "MMU: %s, D-Cache: %s, I-Cache: %s",
451 armv4_5_state_strings[armv4_5->core_state],
452 Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name,
453 armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)],
454 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
455 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
456 state[arm920t->armv4_5_mmu.mmu_enabled],
457 state[arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],
458 state[arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled]);
459
460 return ERROR_OK;
461 }
462
463 /** Reads a buffer, in the specified word size, with current MMU settings. */
464 int arm920t_read_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
465 {
466 int retval;
467
468 retval = arm7_9_read_memory(target, address, size, count, buffer);
469
470 return retval;
471 }
472
473
474 static int arm920t_read_phys_memory(struct target_s *target,
475 uint32_t address, uint32_t size,
476 uint32_t count, uint8_t *buffer)
477 {
478 struct arm920t_common_s *arm920t = target_to_arm920(target);
479
480 return armv4_5_mmu_read_physical(target, &arm920t->armv4_5_mmu,
481 address, size, count, buffer);
482 }
483
484 static int arm920t_write_phys_memory(struct target_s *target,
485 uint32_t address, uint32_t size,
486 uint32_t count, uint8_t *buffer)
487 {
488 struct arm920t_common_s *arm920t = target_to_arm920(target);
489
490 return armv4_5_mmu_write_physical(target, &arm920t->armv4_5_mmu,
491 address, size, count, buffer);
492 }
493
494
495 /** Writes a buffer, in the specified word size, with current MMU settings. */
496 int arm920t_write_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
497 {
498 int retval;
499
500 if ((retval = arm7_9_write_memory(target, address, size, count, buffer)) != ERROR_OK)
501 return retval;
502
503 /* This fn is used to write breakpoints, so we need to make sure
504 * that the data cache is flushed and the instruction cache is
505 * invalidated
506 */
507 if (((size == 4) || (size == 2)) && (count == 1))
508 {
509 struct arm920t_common_s *arm920t = target_to_arm920(target);
510
511 if (arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled)
512 {
513 LOG_DEBUG("D-Cache enabled, flush and invalidate cache line");
514 /* MCR p15,0,Rd,c7,c10,2 */
515 retval = arm920t_write_cp15_interpreted(target, 0xee070f5e, 0x0, address);
516 if (retval != ERROR_OK)
517 return retval;
518 }
519
520 if (arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled)
521 {
522 LOG_DEBUG("I-Cache enabled, invalidating affected I-Cache line");
523 retval = arm920t_write_cp15_interpreted(target, 0xee070f35, 0x0, address);
524 if (retval != ERROR_OK)
525 return retval;
526 }
527 }
528
529 return retval;
530 }
531
532 // EXPORTED to FA256
533 int arm920t_soft_reset_halt(struct target_s *target)
534 {
535 int retval = ERROR_OK;
536 struct arm920t_common_s *arm920t = target_to_arm920(target);
537 struct arm7_9_common_s *arm7_9 = target_to_arm7_9(target);
538 struct armv4_5_common_s *armv4_5 = &arm7_9->armv4_5_common;
539 reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
540
541 if ((retval = target_halt(target)) != ERROR_OK)
542 {
543 return retval;
544 }
545
546 long long then = timeval_ms();
547 int timeout;
548 while (!(timeout = ((timeval_ms()-then) > 1000)))
549 {
550 if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0)
551 {
552 embeddedice_read_reg(dbg_stat);
553 if ((retval = jtag_execute_queue()) != ERROR_OK)
554 {
555 return retval;
556 }
557 } else
558 {
559 break;
560 }
561 if (debug_level >= 3)
562 {
563 /* do not eat all CPU, time out after 1 se*/
564 alive_sleep(100);
565 } else
566 {
567 keep_alive();
568 }
569 }
570 if (timeout)
571 {
572 LOG_ERROR("Failed to halt CPU after 1 sec");
573 return ERROR_TARGET_TIMEOUT;
574 }
575
576 target->state = TARGET_HALTED;
577
578 /* SVC, ARM state, IRQ and FIQ disabled */
579 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8, 0xd3);
580 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
581 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
582
583 /* start fetching from 0x0 */
584 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
585 armv4_5->core_cache->reg_list[15].dirty = 1;
586 armv4_5->core_cache->reg_list[15].valid = 1;
587
588 armv4_5->core_mode = ARMV4_5_MODE_SVC;
589 armv4_5->core_state = ARMV4_5_STATE_ARM;
590
591 arm920t_disable_mmu_caches(target, 1, 1, 1);
592 arm920t->armv4_5_mmu.mmu_enabled = 0;
593 arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;
594 arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;
595
596 if ((retval = target_call_event_callbacks(target, TARGET_EVENT_HALTED)) != ERROR_OK)
597 {
598 return retval;
599 }
600
601 return ERROR_OK;
602 }
603
604 int arm920t_init_arch_info(target_t *target, arm920t_common_t *arm920t, jtag_tap_t *tap)
605 {
606 arm9tdmi_common_t *arm9tdmi = &arm920t->arm9tdmi_common;
607 arm7_9_common_t *arm7_9 = &arm9tdmi->arm7_9_common;
608
609 /* initialize arm9tdmi specific info (including arm7_9 and armv4_5)
610 */
611 arm9tdmi_init_arch_info(target, arm9tdmi, tap);
612
613 arm920t->common_magic = ARM920T_COMMON_MAGIC;
614
615 arm7_9->post_debug_entry = arm920t_post_debug_entry;
616 arm7_9->pre_restore_context = arm920t_pre_restore_context;
617
618 arm920t->armv4_5_mmu.armv4_5_cache.ctype = -1;
619 arm920t->armv4_5_mmu.get_ttb = arm920t_get_ttb;
620 arm920t->armv4_5_mmu.read_memory = arm7_9_read_memory;
621 arm920t->armv4_5_mmu.write_memory = arm7_9_write_memory;
622 arm920t->armv4_5_mmu.disable_mmu_caches = arm920t_disable_mmu_caches;
623 arm920t->armv4_5_mmu.enable_mmu_caches = arm920t_enable_mmu_caches;
624 arm920t->armv4_5_mmu.has_tiny_pages = 1;
625 arm920t->armv4_5_mmu.mmu_enabled = 0;
626
627 /* disabling linefills leads to lockups, so keep them enabled for now
628 * this doesn't affect correctness, but might affect timing issues, if
629 * important data is evicted from the cache during the debug session
630 * */
631 arm920t->preserve_cache = 0;
632
633 /* override hw single-step capability from ARM9TDMI */
634 arm7_9->has_single_step = 1;
635
636 return ERROR_OK;
637 }
638
639 static int arm920t_target_create(struct target_s *target, Jim_Interp *interp)
640 {
641 arm920t_common_t *arm920t = calloc(1,sizeof(arm920t_common_t));
642
643 return arm920t_init_arch_info(target, arm920t, target->tap);
644 }
645
646 static int arm920t_handle_read_cache_command(struct command_context_s *cmd_ctx,
647 char *cmd, char **args, int argc)
648 {
649 int retval = ERROR_OK;
650 target_t *target = get_current_target(cmd_ctx);
651 struct arm920t_common_s *arm920t = target_to_arm920(target);
652 struct arm7_9_common_s *arm7_9 = target_to_arm7_9(target);
653 struct armv4_5_common_s *armv4_5 = &arm7_9->armv4_5_common;
654 uint32_t cp15c15;
655 uint32_t cp15_ctrl, cp15_ctrl_saved;
656 uint32_t regs[16];
657 uint32_t *regs_p[16];
658 uint32_t C15_C_D_Ind, C15_C_I_Ind;
659 int i;
660 FILE *output;
661 arm920t_cache_line_t d_cache[8][64], i_cache[8][64];
662 int segment, index;
663
664 retval = arm920t_verify_pointer(cmd_ctx, arm920t);
665 if (retval != ERROR_OK)
666 return retval;
667
668 if (argc != 1)
669 {
670 command_print(cmd_ctx, "usage: arm920t read_cache <filename>");
671 return ERROR_OK;
672 }
673
674 if ((output = fopen(args[0], "w")) == NULL)
675 {
676 LOG_DEBUG("error opening cache content file");
677 return ERROR_OK;
678 }
679
680 for (i = 0; i < 16; i++)
681 regs_p[i] = &regs[i];
682
683 /* disable MMU and Caches */
684 arm920t_read_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), &cp15_ctrl);
685 if ((retval = jtag_execute_queue()) != ERROR_OK)
686 {
687 return retval;
688 }
689 cp15_ctrl_saved = cp15_ctrl;
690 cp15_ctrl &= ~(ARMV4_5_MMU_ENABLED | ARMV4_5_D_U_CACHE_ENABLED | ARMV4_5_I_CACHE_ENABLED);
691 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), cp15_ctrl);
692
693 /* read CP15 test state register */
694 arm920t_read_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), &cp15c15);
695 jtag_execute_queue();
696
697 /* read DCache content */
698 fprintf(output, "DCache:\n");
699
700 /* go through segments 0 to nsets (8 on ARM920T, 4 on ARM922T) */
701 for (segment = 0; segment < arm920t->armv4_5_mmu.armv4_5_cache.d_u_size.nsets; segment++)
702 {
703 fprintf(output, "\nsegment: %i\n----------", segment);
704
705 /* Ra: r0 = SBZ(31:8):segment(7:5):SBZ(4:0) */
706 regs[0] = 0x0 | (segment << 5);
707 arm9tdmi_write_core_regs(target, 0x1, regs);
708
709 /* set interpret mode */
710 cp15c15 |= 0x1;
711 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
712
713 /* D CAM Read, loads current victim into C15.C.D.Ind */
714 arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,6,2), ARMV4_5_LDR(1, 0));
715
716 /* read current victim */
717 arm920t_read_cp15_physical(target, 0x3d, &C15_C_D_Ind);
718
719 /* clear interpret mode */
720 cp15c15 &= ~0x1;
721 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
722
723 for (index = 0; index < 64; index++)
724 {
725 /* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */
726 regs[0] = 0x0 | (segment << 5) | (index << 26);
727 arm9tdmi_write_core_regs(target, 0x1, regs);
728
729 /* set interpret mode */
730 cp15c15 |= 0x1;
731 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
732
733 /* Write DCache victim */
734 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,9,1,0), ARMV4_5_LDR(1, 0));
735
736 /* Read D RAM */
737 arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,10,2), ARMV4_5_LDMIA(0, 0x1fe, 0, 0));
738
739 /* Read D CAM */
740 arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,6,2), ARMV4_5_LDR(9, 0));
741
742 /* clear interpret mode */
743 cp15c15 &= ~0x1;
744 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
745
746 /* read D RAM and CAM content */
747 arm9tdmi_read_core_regs(target, 0x3fe, regs_p);
748 if ((retval = jtag_execute_queue()) != ERROR_OK)
749 {
750 return retval;
751 }
752
753 d_cache[segment][index].cam = regs[9];
754
755 /* mask LFSR[6] */
756 regs[9] &= 0xfffffffe;
757 fprintf(output, "\nsegment: %i, index: %i, CAM: 0x%8.8" PRIx32 ", content (%s):\n", segment, index, regs[9], (regs[9] & 0x10) ? "valid" : "invalid");
758
759 for (i = 1; i < 9; i++)
760 {
761 d_cache[segment][index].data[i] = regs[i];
762 fprintf(output, "%i: 0x%8.8" PRIx32 "\n", i-1, regs[i]);
763 }
764
765 }
766
767 /* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */
768 regs[0] = 0x0 | (segment << 5) | (C15_C_D_Ind << 26);
769 arm9tdmi_write_core_regs(target, 0x1, regs);
770
771 /* set interpret mode */
772 cp15c15 |= 0x1;
773 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
774
775 /* Write DCache victim */
776 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,9,1,0), ARMV4_5_LDR(1, 0));
777
778 /* clear interpret mode */
779 cp15c15 &= ~0x1;
780 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
781 }
782
783 /* read ICache content */
784 fprintf(output, "ICache:\n");
785
786 /* go through segments 0 to nsets (8 on ARM920T, 4 on ARM922T) */
787 for (segment = 0; segment < arm920t->armv4_5_mmu.armv4_5_cache.d_u_size.nsets; segment++)
788 {
789 fprintf(output, "segment: %i\n----------", segment);
790
791 /* Ra: r0 = SBZ(31:8):segment(7:5):SBZ(4:0) */
792 regs[0] = 0x0 | (segment << 5);
793 arm9tdmi_write_core_regs(target, 0x1, regs);
794
795 /* set interpret mode */
796 cp15c15 |= 0x1;
797 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
798
799 /* I CAM Read, loads current victim into C15.C.I.Ind */
800 arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,5,2), ARMV4_5_LDR(1, 0));
801
802 /* read current victim */
803 arm920t_read_cp15_physical(target, 0x3b, &C15_C_I_Ind);
804
805 /* clear interpret mode */
806 cp15c15 &= ~0x1;
807 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
808
809 for (index = 0; index < 64; index++)
810 {
811 /* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */
812 regs[0] = 0x0 | (segment << 5) | (index << 26);
813 arm9tdmi_write_core_regs(target, 0x1, regs);
814
815 /* set interpret mode */
816 cp15c15 |= 0x1;
817 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
818
819 /* Write ICache victim */
820 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,9,1,1), ARMV4_5_LDR(1, 0));
821
822 /* Read I RAM */
823 arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,9,2), ARMV4_5_LDMIA(0, 0x1fe, 0, 0));
824
825 /* Read I CAM */
826 arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,5,2), ARMV4_5_LDR(9, 0));
827
828 /* clear interpret mode */
829 cp15c15 &= ~0x1;
830 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
831
832 /* read I RAM and CAM content */
833 arm9tdmi_read_core_regs(target, 0x3fe, regs_p);
834 if ((retval = jtag_execute_queue()) != ERROR_OK)
835 {
836 return retval;
837 }
838
839 i_cache[segment][index].cam = regs[9];
840
841 /* mask LFSR[6] */
842 regs[9] &= 0xfffffffe;
843 fprintf(output, "\nsegment: %i, index: %i, CAM: 0x%8.8" PRIx32 ", content (%s):\n", segment, index, regs[9], (regs[9] & 0x10) ? "valid" : "invalid");
844
845 for (i = 1; i < 9; i++)
846 {
847 i_cache[segment][index].data[i] = regs[i];
848 fprintf(output, "%i: 0x%8.8" PRIx32 "\n", i-1, regs[i]);
849 }
850 }
851
852 /* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */
853 regs[0] = 0x0 | (segment << 5) | (C15_C_D_Ind << 26);
854 arm9tdmi_write_core_regs(target, 0x1, regs);
855
856 /* set interpret mode */
857 cp15c15 |= 0x1;
858 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
859
860 /* Write ICache victim */
861 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,9,1,1), ARMV4_5_LDR(1, 0));
862
863 /* clear interpret mode */
864 cp15c15 &= ~0x1;
865 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
866 }
867
868 /* restore CP15 MMU and Cache settings */
869 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), cp15_ctrl_saved);
870
871 command_print(cmd_ctx, "cache content successfully output to %s", args[0]);
872
873 fclose(output);
874
875 if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
876 return ERROR_FAIL;
877
878 /* mark registers dirty. */
879 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).valid;
880 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 1).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 1).valid;
881 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 2).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 2).valid;
882 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 3).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 3).valid;
883 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 4).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 4).valid;
884 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 5).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 5).valid;
885 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 6).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 6).valid;
886 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 7).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 7).valid;
887 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 8).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 8).valid;
888 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 9).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 9).valid;
889
890 return ERROR_OK;
891 }
892
893 static int arm920t_handle_read_mmu_command(struct command_context_s *cmd_ctx,
894 char *cmd, char **args, int argc)
895 {
896 int retval = ERROR_OK;
897 target_t *target = get_current_target(cmd_ctx);
898 struct arm920t_common_s *arm920t = target_to_arm920(target);
899 struct arm7_9_common_s *arm7_9 = target_to_arm7_9(target);
900 struct armv4_5_common_s *armv4_5 = &arm7_9->armv4_5_common;
901 uint32_t cp15c15;
902 uint32_t cp15_ctrl, cp15_ctrl_saved;
903 uint32_t regs[16];
904 uint32_t *regs_p[16];
905 int i;
906 FILE *output;
907 uint32_t Dlockdown, Ilockdown;
908 arm920t_tlb_entry_t d_tlb[64], i_tlb[64];
909 int victim;
910
911 retval = arm920t_verify_pointer(cmd_ctx, arm920t);
912 if (retval != ERROR_OK)
913 return retval;
914
915 if (argc != 1)
916 {
917 command_print(cmd_ctx, "usage: arm920t read_mmu <filename>");
918 return ERROR_OK;
919 }
920
921 if ((output = fopen(args[0], "w")) == NULL)
922 {
923 LOG_DEBUG("error opening mmu content file");
924 return ERROR_OK;
925 }
926
927 for (i = 0; i < 16; i++)
928 regs_p[i] = &regs[i];
929
930 /* disable MMU and Caches */
931 arm920t_read_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), &cp15_ctrl);
932 if ((retval = jtag_execute_queue()) != ERROR_OK)
933 {
934 return retval;
935 }
936 cp15_ctrl_saved = cp15_ctrl;
937 cp15_ctrl &= ~(ARMV4_5_MMU_ENABLED | ARMV4_5_D_U_CACHE_ENABLED | ARMV4_5_I_CACHE_ENABLED);
938 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), cp15_ctrl);
939
940 /* read CP15 test state register */
941 arm920t_read_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), &cp15c15);
942 if ((retval = jtag_execute_queue()) != ERROR_OK)
943 {
944 return retval;
945 }
946
947 /* prepare reading D TLB content
948 * */
949
950 /* set interpret mode */
951 cp15c15 |= 0x1;
952 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
953
954 /* Read D TLB lockdown */
955 arm920t_execute_cp15(target, ARMV4_5_MRC(15,0,0,10,0,0), ARMV4_5_LDR(1, 0));
956
957 /* clear interpret mode */
958 cp15c15 &= ~0x1;
959 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
960
961 /* read D TLB lockdown stored to r1 */
962 arm9tdmi_read_core_regs(target, 0x2, regs_p);
963 if ((retval = jtag_execute_queue()) != ERROR_OK)
964 {
965 return retval;
966 }
967 Dlockdown = regs[1];
968
969 for (victim = 0; victim < 64; victim += 8)
970 {
971 /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
972 * base remains unchanged, victim goes through entries 0 to 63 */
973 regs[1] = (Dlockdown & 0xfc000000) | (victim << 20);
974 arm9tdmi_write_core_regs(target, 0x2, regs);
975
976 /* set interpret mode */
977 cp15c15 |= 0x1;
978 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
979
980 /* Write D TLB lockdown */
981 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,0), ARMV4_5_STR(1, 0));
982
983 /* Read D TLB CAM */
984 arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,6,4), ARMV4_5_LDMIA(0, 0x3fc, 0, 0));
985
986 /* clear interpret mode */
987 cp15c15 &= ~0x1;
988 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
989
990 /* read D TLB CAM content stored to r2-r9 */
991 arm9tdmi_read_core_regs(target, 0x3fc, regs_p);
992 if ((retval = jtag_execute_queue()) != ERROR_OK)
993 {
994 return retval;
995 }
996
997 for (i = 0; i < 8; i++)
998 d_tlb[victim + i].cam = regs[i + 2];
999 }
1000
1001 for (victim = 0; victim < 64; victim++)
1002 {
1003 /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
1004 * base remains unchanged, victim goes through entries 0 to 63 */
1005 regs[1] = (Dlockdown & 0xfc000000) | (victim << 20);
1006 arm9tdmi_write_core_regs(target, 0x2, regs);
1007
1008 /* set interpret mode */
1009 cp15c15 |= 0x1;
1010 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
1011
1012 /* Write D TLB lockdown */
1013 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,0), ARMV4_5_STR(1, 0));
1014
1015 /* Read D TLB RAM1 */
1016 arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,10,4), ARMV4_5_LDR(2,0));
1017
1018 /* Read D TLB RAM2 */
1019 arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,2,5), ARMV4_5_LDR(3,0));
1020
1021 /* clear interpret mode */
1022 cp15c15 &= ~0x1;
1023 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
1024
1025 /* read D TLB RAM content stored to r2 and r3 */
1026 arm9tdmi_read_core_regs(target, 0xc, regs_p);
1027 if ((retval = jtag_execute_queue()) != ERROR_OK)
1028 {
1029 return retval;
1030 }
1031
1032 d_tlb[victim].ram1 = regs[2];
1033 d_tlb[victim].ram2 = regs[3];
1034 }
1035
1036 /* restore D TLB lockdown */
1037 regs[1] = Dlockdown;
1038 arm9tdmi_write_core_regs(target, 0x2, regs);
1039
1040 /* Write D TLB lockdown */
1041 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,0), ARMV4_5_STR(1, 0));
1042
1043 /* prepare reading I TLB content
1044 * */
1045
1046 /* set interpret mode */
1047 cp15c15 |= 0x1;
1048 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
1049
1050 /* Read I TLB lockdown */
1051 arm920t_execute_cp15(target, ARMV4_5_MRC(15,0,0,10,0,1), ARMV4_5_LDR(1, 0));
1052
1053 /* clear interpret mode */
1054 cp15c15 &= ~0x1;
1055 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
1056
1057 /* read I TLB lockdown stored to r1 */
1058 arm9tdmi_read_core_regs(target, 0x2, regs_p);
1059 if ((retval = jtag_execute_queue()) != ERROR_OK)
1060 {
1061 return retval;
1062 }
1063 Ilockdown = regs[1];
1064
1065 for (victim = 0; victim < 64; victim += 8)
1066 {
1067 /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
1068 * base remains unchanged, victim goes through entries 0 to 63 */
1069 regs[1] = (Ilockdown & 0xfc000000) | (victim << 20);
1070 arm9tdmi_write_core_regs(target, 0x2, regs);
1071
1072 /* set interpret mode */
1073 cp15c15 |= 0x1;
1074 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
1075
1076 /* Write I TLB lockdown */
1077 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,1), ARMV4_5_STR(1, 0));
1078
1079 /* Read I TLB CAM */
1080 arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,5,4), ARMV4_5_LDMIA(0, 0x3fc, 0, 0));
1081
1082 /* clear interpret mode */
1083 cp15c15 &= ~0x1;
1084 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
1085
1086 /* read I TLB CAM content stored to r2-r9 */
1087 arm9tdmi_read_core_regs(target, 0x3fc, regs_p);
1088 if ((retval = jtag_execute_queue()) != ERROR_OK)
1089 {
1090 return retval;
1091 }
1092
1093 for (i = 0; i < 8; i++)
1094 i_tlb[i + victim].cam = regs[i + 2];
1095 }
1096
1097 for (victim = 0; victim < 64; victim++)
1098 {
1099 /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
1100 * base remains unchanged, victim goes through entries 0 to 63 */
1101 regs[1] = (Dlockdown & 0xfc000000) | (victim << 20);
1102 arm9tdmi_write_core_regs(target, 0x2, regs);
1103
1104 /* set interpret mode */
1105 cp15c15 |= 0x1;
1106 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
1107
1108 /* Write I TLB lockdown */
1109 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,1), ARMV4_5_STR(1, 0));
1110
1111 /* Read I TLB RAM1 */
1112 arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,9,4), ARMV4_5_LDR(2,0));
1113
1114 /* Read I TLB RAM2 */
1115 arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,1,5), ARMV4_5_LDR(3,0));
1116
1117 /* clear interpret mode */
1118 cp15c15 &= ~0x1;
1119 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
1120
1121 /* read I TLB RAM content stored to r2 and r3 */
1122 arm9tdmi_read_core_regs(target, 0xc, regs_p);
1123 if ((retval = jtag_execute_queue()) != ERROR_OK)
1124 {
1125 return retval;
1126 }
1127
1128 i_tlb[victim].ram1 = regs[2];
1129 i_tlb[victim].ram2 = regs[3];
1130 }
1131
1132 /* restore I TLB lockdown */
1133 regs[1] = Ilockdown;
1134 arm9tdmi_write_core_regs(target, 0x2, regs);
1135
1136 /* Write I TLB lockdown */
1137 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,1), ARMV4_5_STR(1, 0));
1138
1139 /* restore CP15 MMU and Cache settings */
1140 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), cp15_ctrl_saved);
1141
1142 /* output data to file */
1143 fprintf(output, "D TLB content:\n");
1144 for (i = 0; i < 64; i++)
1145 {
1146 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)");
1147 }
1148
1149 fprintf(output, "\n\nI TLB content:\n");
1150 for (i = 0; i < 64; i++)
1151 {
1152 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)");
1153 }
1154
1155 command_print(cmd_ctx, "mmu content successfully output to %s", args[0]);
1156
1157 fclose(output);
1158
1159 if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
1160 return ERROR_FAIL;
1161
1162 /* mark registers dirty */
1163 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).valid;
1164 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 1).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 1).valid;
1165 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 2).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 2).valid;
1166 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 3).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 3).valid;
1167 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 4).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 4).valid;
1168 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 5).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 5).valid;
1169 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 6).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 6).valid;
1170 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 7).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 7).valid;
1171 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 8).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 8).valid;
1172 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 9).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 9).valid;
1173
1174 return ERROR_OK;
1175 }
1176
1177 static int arm920t_handle_cp15_command(struct command_context_s *cmd_ctx,
1178 char *cmd, char **args, int argc)
1179 {
1180 int retval;
1181 target_t *target = get_current_target(cmd_ctx);
1182 struct arm920t_common_s *arm920t = target_to_arm920(target);
1183
1184 retval = arm920t_verify_pointer(cmd_ctx, arm920t);
1185 if (retval != ERROR_OK)
1186 return retval;
1187
1188 if (target->state != TARGET_HALTED)
1189 {
1190 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
1191 return ERROR_OK;
1192 }
1193
1194 /* one or more argument, access a single register (write if second argument is given */
1195 if (argc >= 1)
1196 {
1197 int address;
1198 COMMAND_PARSE_NUMBER(int, args[0], address);
1199
1200 if (argc == 1)
1201 {
1202 uint32_t value;
1203 if ((retval = arm920t_read_cp15_physical(target, address, &value)) != ERROR_OK)
1204 {
1205 command_print(cmd_ctx, "couldn't access reg %i", address);
1206 return ERROR_OK;
1207 }
1208 if ((retval = jtag_execute_queue()) != ERROR_OK)
1209 {
1210 return retval;
1211 }
1212
1213 command_print(cmd_ctx, "%i: %8.8" PRIx32 "", address, value);
1214 }
1215 else if (argc == 2)
1216 {
1217 uint32_t value;
1218 COMMAND_PARSE_NUMBER(u32, args[1], value);
1219 if ((retval = arm920t_write_cp15_physical(target, address, value)) != ERROR_OK)
1220 {
1221 command_print(cmd_ctx, "couldn't access reg %i", address);
1222 return ERROR_OK;
1223 }
1224 command_print(cmd_ctx, "%i: %8.8" PRIx32 "", address, value);
1225 }
1226 }
1227
1228 return ERROR_OK;
1229 }
1230
1231 static int arm920t_handle_cp15i_command(struct command_context_s *cmd_ctx,
1232 char *cmd, char **args, int argc)
1233 {
1234 int retval;
1235 target_t *target = get_current_target(cmd_ctx);
1236 struct arm920t_common_s *arm920t = target_to_arm920(target);
1237
1238 retval = arm920t_verify_pointer(cmd_ctx, arm920t);
1239 if (retval != ERROR_OK)
1240 return retval;
1241
1242
1243 if (target->state != TARGET_HALTED)
1244 {
1245 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
1246 return ERROR_OK;
1247 }
1248
1249 /* one or more argument, access a single register (write if second argument is given */
1250 if (argc >= 1)
1251 {
1252 uint32_t opcode;
1253 COMMAND_PARSE_NUMBER(u32, args[0], opcode);
1254
1255 if (argc == 1)
1256 {
1257 uint32_t value;
1258 if ((retval = arm920t_read_cp15_interpreted(target, opcode, 0x0, &value)) != ERROR_OK)
1259 {
1260 command_print(cmd_ctx, "couldn't execute %8.8" PRIx32 "", opcode);
1261 return ERROR_OK;
1262 }
1263
1264 command_print(cmd_ctx, "%8.8" PRIx32 ": %8.8" PRIx32 "", opcode, value);
1265 }
1266 else if (argc == 2)
1267 {
1268 uint32_t value;
1269 COMMAND_PARSE_NUMBER(u32, args[1], value);
1270 if ((retval = arm920t_write_cp15_interpreted(target, opcode, value, 0)) != ERROR_OK)
1271 {
1272 command_print(cmd_ctx, "couldn't execute %8.8" PRIx32 "", opcode);
1273 return ERROR_OK;
1274 }
1275 command_print(cmd_ctx, "%8.8" PRIx32 ": %8.8" PRIx32 "", opcode, value);
1276 }
1277 else if (argc == 3)
1278 {
1279 uint32_t value;
1280 COMMAND_PARSE_NUMBER(u32, args[1], value);
1281 uint32_t address;
1282 COMMAND_PARSE_NUMBER(u32, args[2], address);
1283 if ((retval = arm920t_write_cp15_interpreted(target, opcode, value, address)) != ERROR_OK)
1284 {
1285 command_print(cmd_ctx, "couldn't execute %8.8" PRIx32 "", opcode);
1286 return ERROR_OK;
1287 }
1288 command_print(cmd_ctx, "%8.8" PRIx32 ": %8.8" PRIx32 " %8.8" PRIx32 "", opcode, value, address);
1289 }
1290 }
1291 else
1292 {
1293 command_print(cmd_ctx, "usage: arm920t cp15i <opcode> [value] [address]");
1294 }
1295
1296 return ERROR_OK;
1297 }
1298
1299 static int arm920t_handle_cache_info_command(struct command_context_s *cmd_ctx,
1300 char *cmd, char **args, int argc)
1301 {
1302 int retval;
1303 target_t *target = get_current_target(cmd_ctx);
1304 struct arm920t_common_s *arm920t = target_to_arm920(target);
1305
1306 retval = arm920t_verify_pointer(cmd_ctx, arm920t);
1307 if (retval != ERROR_OK)
1308 return retval;
1309
1310 return armv4_5_handle_cache_info_command(cmd_ctx, &arm920t->armv4_5_mmu.armv4_5_cache);
1311 }
1312
1313
1314 static int arm920t_mrc(target_t *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t *value)
1315 {
1316 if (cpnum!=15)
1317 {
1318 LOG_ERROR("Only cp15 is supported");
1319 return ERROR_FAIL;
1320 }
1321
1322 return arm920t_read_cp15_interpreted(target, mrc_opcode(cpnum, op1, op2, CRn, CRm), 0, value);
1323 }
1324
1325 static int arm920t_mcr(target_t *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t value)
1326 {
1327 if (cpnum!=15)
1328 {
1329 LOG_ERROR("Only cp15 is supported");
1330 return ERROR_FAIL;
1331 }
1332
1333 return arm920t_write_cp15_interpreted(target, mrc_opcode(cpnum, op1, op2, CRn, CRm), 0, value);
1334 }
1335
1336 /** Registers commands to access coprocessor, cache, and MMU resources. */
1337 int arm920t_register_commands(struct command_context_s *cmd_ctx)
1338 {
1339 int retval;
1340 command_t *arm920t_cmd;
1341
1342 retval = arm9tdmi_register_commands(cmd_ctx);
1343
1344 arm920t_cmd = register_command(cmd_ctx, NULL, "arm920t",
1345 NULL, COMMAND_ANY,
1346 "arm920t specific commands");
1347
1348 register_command(cmd_ctx, arm920t_cmd, "cp15",
1349 arm920t_handle_cp15_command, COMMAND_EXEC,
1350 "display/modify cp15 register <num> [value]");
1351 register_command(cmd_ctx, arm920t_cmd, "cp15i",
1352 arm920t_handle_cp15i_command, COMMAND_EXEC,
1353 "display/modify cp15 (interpreted access) "
1354 "<opcode> [value] [address]");
1355 register_command(cmd_ctx, arm920t_cmd, "cache_info",
1356 arm920t_handle_cache_info_command, COMMAND_EXEC,
1357 "display information about target caches");
1358 register_command(cmd_ctx, arm920t_cmd, "read_cache",
1359 arm920t_handle_read_cache_command, COMMAND_EXEC,
1360 "display I/D cache content");
1361 register_command(cmd_ctx, arm920t_cmd, "read_mmu",
1362 arm920t_handle_read_mmu_command, COMMAND_EXEC,
1363 "display I/D mmu content");
1364
1365 return retval;
1366 }
1367
1368 /** Holds methods for ARM920 targets. */
1369 target_type_t arm920t_target =
1370 {
1371 .name = "arm920t",
1372
1373 .poll = arm7_9_poll,
1374 .arch_state = arm920t_arch_state,
1375
1376 .target_request_data = arm7_9_target_request_data,
1377
1378 .halt = arm7_9_halt,
1379 .resume = arm7_9_resume,
1380 .step = arm7_9_step,
1381
1382 .assert_reset = arm7_9_assert_reset,
1383 .deassert_reset = arm7_9_deassert_reset,
1384 .soft_reset_halt = arm920t_soft_reset_halt,
1385
1386 .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
1387
1388 .read_memory = arm920t_read_memory,
1389 .write_memory = arm920t_write_memory,
1390 .read_phys_memory = arm920t_read_phys_memory,
1391 .write_phys_memory = arm920t_write_phys_memory,
1392 .bulk_write_memory = arm7_9_bulk_write_memory,
1393 .checksum_memory = arm7_9_checksum_memory,
1394 .blank_check_memory = arm7_9_blank_check_memory,
1395
1396 .run_algorithm = armv4_5_run_algorithm,
1397
1398 .add_breakpoint = arm7_9_add_breakpoint,
1399 .remove_breakpoint = arm7_9_remove_breakpoint,
1400 .add_watchpoint = arm7_9_add_watchpoint,
1401 .remove_watchpoint = arm7_9_remove_watchpoint,
1402
1403 .register_commands = arm920t_register_commands,
1404 .target_create = arm920t_target_create,
1405 .init_target = arm9tdmi_init_target,
1406 .examine = arm9tdmi_examine,
1407 .mrc = arm920t_mrc,
1408 .mcr = arm920t_mcr,
1409 };

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)