ARM920: implement basic MMU ops
[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 static int arm920_mmu(struct target_s *target, int *enabled)
464 {
465 if (target->state != TARGET_HALTED) {
466 LOG_ERROR("%s: target not halted", __func__);
467 return ERROR_TARGET_INVALID;
468 }
469
470 *enabled = target_to_arm920(target)->armv4_5_mmu.mmu_enabled;
471 return ERROR_OK;
472 }
473
474 static int arm920_virt2phys(struct target_s *target,
475 uint32_t virt, uint32_t *phys)
476 {
477 /** @todo Implement this! */
478 LOG_ERROR("%s: not implemented", __func__);
479 return ERROR_FAIL;
480 }
481
482 /** Reads a buffer, in the specified word size, with current MMU settings. */
483 int arm920t_read_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
484 {
485 int retval;
486
487 retval = arm7_9_read_memory(target, address, size, count, buffer);
488
489 return retval;
490 }
491
492
493 static int arm920t_read_phys_memory(struct target_s *target,
494 uint32_t address, uint32_t size,
495 uint32_t count, uint8_t *buffer)
496 {
497 struct arm920t_common_s *arm920t = target_to_arm920(target);
498
499 return armv4_5_mmu_read_physical(target, &arm920t->armv4_5_mmu,
500 address, size, count, buffer);
501 }
502
503 static int arm920t_write_phys_memory(struct target_s *target,
504 uint32_t address, uint32_t size,
505 uint32_t count, uint8_t *buffer)
506 {
507 struct arm920t_common_s *arm920t = target_to_arm920(target);
508
509 return armv4_5_mmu_write_physical(target, &arm920t->armv4_5_mmu,
510 address, size, count, buffer);
511 }
512
513
514 /** Writes a buffer, in the specified word size, with current MMU settings. */
515 int arm920t_write_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
516 {
517 int retval;
518
519 if ((retval = arm7_9_write_memory(target, address, size, count, buffer)) != ERROR_OK)
520 return retval;
521
522 /* This fn is used to write breakpoints, so we need to make sure
523 * that the data cache is flushed and the instruction cache is
524 * invalidated
525 */
526 if (((size == 4) || (size == 2)) && (count == 1))
527 {
528 struct arm920t_common_s *arm920t = target_to_arm920(target);
529
530 if (arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled)
531 {
532 LOG_DEBUG("D-Cache enabled, flush and invalidate cache line");
533 /* MCR p15,0,Rd,c7,c10,2 */
534 retval = arm920t_write_cp15_interpreted(target, 0xee070f5e, 0x0, address);
535 if (retval != ERROR_OK)
536 return retval;
537 }
538
539 if (arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled)
540 {
541 LOG_DEBUG("I-Cache enabled, invalidating affected I-Cache line");
542 retval = arm920t_write_cp15_interpreted(target, 0xee070f35, 0x0, address);
543 if (retval != ERROR_OK)
544 return retval;
545 }
546 }
547
548 return retval;
549 }
550
551 // EXPORTED to FA256
552 int arm920t_soft_reset_halt(struct target_s *target)
553 {
554 int retval = ERROR_OK;
555 struct arm920t_common_s *arm920t = target_to_arm920(target);
556 struct arm7_9_common_s *arm7_9 = target_to_arm7_9(target);
557 struct armv4_5_common_s *armv4_5 = &arm7_9->armv4_5_common;
558 reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
559
560 if ((retval = target_halt(target)) != ERROR_OK)
561 {
562 return retval;
563 }
564
565 long long then = timeval_ms();
566 int timeout;
567 while (!(timeout = ((timeval_ms()-then) > 1000)))
568 {
569 if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0)
570 {
571 embeddedice_read_reg(dbg_stat);
572 if ((retval = jtag_execute_queue()) != ERROR_OK)
573 {
574 return retval;
575 }
576 } else
577 {
578 break;
579 }
580 if (debug_level >= 3)
581 {
582 /* do not eat all CPU, time out after 1 se*/
583 alive_sleep(100);
584 } else
585 {
586 keep_alive();
587 }
588 }
589 if (timeout)
590 {
591 LOG_ERROR("Failed to halt CPU after 1 sec");
592 return ERROR_TARGET_TIMEOUT;
593 }
594
595 target->state = TARGET_HALTED;
596
597 /* SVC, ARM state, IRQ and FIQ disabled */
598 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8, 0xd3);
599 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
600 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
601
602 /* start fetching from 0x0 */
603 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
604 armv4_5->core_cache->reg_list[15].dirty = 1;
605 armv4_5->core_cache->reg_list[15].valid = 1;
606
607 armv4_5->core_mode = ARMV4_5_MODE_SVC;
608 armv4_5->core_state = ARMV4_5_STATE_ARM;
609
610 arm920t_disable_mmu_caches(target, 1, 1, 1);
611 arm920t->armv4_5_mmu.mmu_enabled = 0;
612 arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;
613 arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;
614
615 if ((retval = target_call_event_callbacks(target, TARGET_EVENT_HALTED)) != ERROR_OK)
616 {
617 return retval;
618 }
619
620 return ERROR_OK;
621 }
622
623 int arm920t_init_arch_info(target_t *target, arm920t_common_t *arm920t, jtag_tap_t *tap)
624 {
625 arm9tdmi_common_t *arm9tdmi = &arm920t->arm9tdmi_common;
626 arm7_9_common_t *arm7_9 = &arm9tdmi->arm7_9_common;
627
628 /* initialize arm9tdmi specific info (including arm7_9 and armv4_5)
629 */
630 arm9tdmi_init_arch_info(target, arm9tdmi, tap);
631
632 arm920t->common_magic = ARM920T_COMMON_MAGIC;
633
634 arm7_9->post_debug_entry = arm920t_post_debug_entry;
635 arm7_9->pre_restore_context = arm920t_pre_restore_context;
636
637 arm920t->armv4_5_mmu.armv4_5_cache.ctype = -1;
638 arm920t->armv4_5_mmu.get_ttb = arm920t_get_ttb;
639 arm920t->armv4_5_mmu.read_memory = arm7_9_read_memory;
640 arm920t->armv4_5_mmu.write_memory = arm7_9_write_memory;
641 arm920t->armv4_5_mmu.disable_mmu_caches = arm920t_disable_mmu_caches;
642 arm920t->armv4_5_mmu.enable_mmu_caches = arm920t_enable_mmu_caches;
643 arm920t->armv4_5_mmu.has_tiny_pages = 1;
644 arm920t->armv4_5_mmu.mmu_enabled = 0;
645
646 /* disabling linefills leads to lockups, so keep them enabled for now
647 * this doesn't affect correctness, but might affect timing issues, if
648 * important data is evicted from the cache during the debug session
649 * */
650 arm920t->preserve_cache = 0;
651
652 /* override hw single-step capability from ARM9TDMI */
653 arm7_9->has_single_step = 1;
654
655 return ERROR_OK;
656 }
657
658 static int arm920t_target_create(struct target_s *target, Jim_Interp *interp)
659 {
660 arm920t_common_t *arm920t = calloc(1,sizeof(arm920t_common_t));
661
662 return arm920t_init_arch_info(target, arm920t, target->tap);
663 }
664
665 static int arm920t_handle_read_cache_command(struct command_context_s *cmd_ctx,
666 char *cmd, char **args, int argc)
667 {
668 int retval = ERROR_OK;
669 target_t *target = get_current_target(cmd_ctx);
670 struct arm920t_common_s *arm920t = target_to_arm920(target);
671 struct arm7_9_common_s *arm7_9 = target_to_arm7_9(target);
672 struct armv4_5_common_s *armv4_5 = &arm7_9->armv4_5_common;
673 uint32_t cp15c15;
674 uint32_t cp15_ctrl, cp15_ctrl_saved;
675 uint32_t regs[16];
676 uint32_t *regs_p[16];
677 uint32_t C15_C_D_Ind, C15_C_I_Ind;
678 int i;
679 FILE *output;
680 arm920t_cache_line_t d_cache[8][64], i_cache[8][64];
681 int segment, index;
682
683 retval = arm920t_verify_pointer(cmd_ctx, arm920t);
684 if (retval != ERROR_OK)
685 return retval;
686
687 if (argc != 1)
688 {
689 command_print(cmd_ctx, "usage: arm920t read_cache <filename>");
690 return ERROR_OK;
691 }
692
693 if ((output = fopen(args[0], "w")) == NULL)
694 {
695 LOG_DEBUG("error opening cache content file");
696 return ERROR_OK;
697 }
698
699 for (i = 0; i < 16; i++)
700 regs_p[i] = &regs[i];
701
702 /* disable MMU and Caches */
703 arm920t_read_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), &cp15_ctrl);
704 if ((retval = jtag_execute_queue()) != ERROR_OK)
705 {
706 return retval;
707 }
708 cp15_ctrl_saved = cp15_ctrl;
709 cp15_ctrl &= ~(ARMV4_5_MMU_ENABLED | ARMV4_5_D_U_CACHE_ENABLED | ARMV4_5_I_CACHE_ENABLED);
710 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), cp15_ctrl);
711
712 /* read CP15 test state register */
713 arm920t_read_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), &cp15c15);
714 jtag_execute_queue();
715
716 /* read DCache content */
717 fprintf(output, "DCache:\n");
718
719 /* go through segments 0 to nsets (8 on ARM920T, 4 on ARM922T) */
720 for (segment = 0; segment < arm920t->armv4_5_mmu.armv4_5_cache.d_u_size.nsets; segment++)
721 {
722 fprintf(output, "\nsegment: %i\n----------", segment);
723
724 /* Ra: r0 = SBZ(31:8):segment(7:5):SBZ(4:0) */
725 regs[0] = 0x0 | (segment << 5);
726 arm9tdmi_write_core_regs(target, 0x1, regs);
727
728 /* set interpret mode */
729 cp15c15 |= 0x1;
730 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
731
732 /* D CAM Read, loads current victim into C15.C.D.Ind */
733 arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,6,2), ARMV4_5_LDR(1, 0));
734
735 /* read current victim */
736 arm920t_read_cp15_physical(target, 0x3d, &C15_C_D_Ind);
737
738 /* clear interpret mode */
739 cp15c15 &= ~0x1;
740 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
741
742 for (index = 0; index < 64; index++)
743 {
744 /* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */
745 regs[0] = 0x0 | (segment << 5) | (index << 26);
746 arm9tdmi_write_core_regs(target, 0x1, regs);
747
748 /* set interpret mode */
749 cp15c15 |= 0x1;
750 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
751
752 /* Write DCache victim */
753 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,9,1,0), ARMV4_5_LDR(1, 0));
754
755 /* Read D RAM */
756 arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,10,2), ARMV4_5_LDMIA(0, 0x1fe, 0, 0));
757
758 /* Read D CAM */
759 arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,6,2), ARMV4_5_LDR(9, 0));
760
761 /* clear interpret mode */
762 cp15c15 &= ~0x1;
763 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
764
765 /* read D RAM and CAM content */
766 arm9tdmi_read_core_regs(target, 0x3fe, regs_p);
767 if ((retval = jtag_execute_queue()) != ERROR_OK)
768 {
769 return retval;
770 }
771
772 d_cache[segment][index].cam = regs[9];
773
774 /* mask LFSR[6] */
775 regs[9] &= 0xfffffffe;
776 fprintf(output, "\nsegment: %i, index: %i, CAM: 0x%8.8" PRIx32 ", content (%s):\n", segment, index, regs[9], (regs[9] & 0x10) ? "valid" : "invalid");
777
778 for (i = 1; i < 9; i++)
779 {
780 d_cache[segment][index].data[i] = regs[i];
781 fprintf(output, "%i: 0x%8.8" PRIx32 "\n", i-1, regs[i]);
782 }
783
784 }
785
786 /* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */
787 regs[0] = 0x0 | (segment << 5) | (C15_C_D_Ind << 26);
788 arm9tdmi_write_core_regs(target, 0x1, regs);
789
790 /* set interpret mode */
791 cp15c15 |= 0x1;
792 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
793
794 /* Write DCache victim */
795 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,9,1,0), ARMV4_5_LDR(1, 0));
796
797 /* clear interpret mode */
798 cp15c15 &= ~0x1;
799 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
800 }
801
802 /* read ICache content */
803 fprintf(output, "ICache:\n");
804
805 /* go through segments 0 to nsets (8 on ARM920T, 4 on ARM922T) */
806 for (segment = 0; segment < arm920t->armv4_5_mmu.armv4_5_cache.d_u_size.nsets; segment++)
807 {
808 fprintf(output, "segment: %i\n----------", segment);
809
810 /* Ra: r0 = SBZ(31:8):segment(7:5):SBZ(4:0) */
811 regs[0] = 0x0 | (segment << 5);
812 arm9tdmi_write_core_regs(target, 0x1, regs);
813
814 /* set interpret mode */
815 cp15c15 |= 0x1;
816 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
817
818 /* I CAM Read, loads current victim into C15.C.I.Ind */
819 arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,5,2), ARMV4_5_LDR(1, 0));
820
821 /* read current victim */
822 arm920t_read_cp15_physical(target, 0x3b, &C15_C_I_Ind);
823
824 /* clear interpret mode */
825 cp15c15 &= ~0x1;
826 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
827
828 for (index = 0; index < 64; index++)
829 {
830 /* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */
831 regs[0] = 0x0 | (segment << 5) | (index << 26);
832 arm9tdmi_write_core_regs(target, 0x1, regs);
833
834 /* set interpret mode */
835 cp15c15 |= 0x1;
836 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
837
838 /* Write ICache victim */
839 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,9,1,1), ARMV4_5_LDR(1, 0));
840
841 /* Read I RAM */
842 arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,9,2), ARMV4_5_LDMIA(0, 0x1fe, 0, 0));
843
844 /* Read I CAM */
845 arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,5,2), ARMV4_5_LDR(9, 0));
846
847 /* clear interpret mode */
848 cp15c15 &= ~0x1;
849 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
850
851 /* read I RAM and CAM content */
852 arm9tdmi_read_core_regs(target, 0x3fe, regs_p);
853 if ((retval = jtag_execute_queue()) != ERROR_OK)
854 {
855 return retval;
856 }
857
858 i_cache[segment][index].cam = regs[9];
859
860 /* mask LFSR[6] */
861 regs[9] &= 0xfffffffe;
862 fprintf(output, "\nsegment: %i, index: %i, CAM: 0x%8.8" PRIx32 ", content (%s):\n", segment, index, regs[9], (regs[9] & 0x10) ? "valid" : "invalid");
863
864 for (i = 1; i < 9; i++)
865 {
866 i_cache[segment][index].data[i] = regs[i];
867 fprintf(output, "%i: 0x%8.8" PRIx32 "\n", i-1, regs[i]);
868 }
869 }
870
871 /* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */
872 regs[0] = 0x0 | (segment << 5) | (C15_C_D_Ind << 26);
873 arm9tdmi_write_core_regs(target, 0x1, regs);
874
875 /* set interpret mode */
876 cp15c15 |= 0x1;
877 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
878
879 /* Write ICache victim */
880 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,9,1,1), ARMV4_5_LDR(1, 0));
881
882 /* clear interpret mode */
883 cp15c15 &= ~0x1;
884 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
885 }
886
887 /* restore CP15 MMU and Cache settings */
888 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), cp15_ctrl_saved);
889
890 command_print(cmd_ctx, "cache content successfully output to %s", args[0]);
891
892 fclose(output);
893
894 if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
895 return ERROR_FAIL;
896
897 /* mark registers dirty. */
898 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;
899 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;
900 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;
901 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;
902 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;
903 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;
904 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;
905 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;
906 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;
907 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;
908
909 return ERROR_OK;
910 }
911
912 static int arm920t_handle_read_mmu_command(struct command_context_s *cmd_ctx,
913 char *cmd, char **args, int argc)
914 {
915 int retval = ERROR_OK;
916 target_t *target = get_current_target(cmd_ctx);
917 struct arm920t_common_s *arm920t = target_to_arm920(target);
918 struct arm7_9_common_s *arm7_9 = target_to_arm7_9(target);
919 struct armv4_5_common_s *armv4_5 = &arm7_9->armv4_5_common;
920 uint32_t cp15c15;
921 uint32_t cp15_ctrl, cp15_ctrl_saved;
922 uint32_t regs[16];
923 uint32_t *regs_p[16];
924 int i;
925 FILE *output;
926 uint32_t Dlockdown, Ilockdown;
927 arm920t_tlb_entry_t d_tlb[64], i_tlb[64];
928 int victim;
929
930 retval = arm920t_verify_pointer(cmd_ctx, arm920t);
931 if (retval != ERROR_OK)
932 return retval;
933
934 if (argc != 1)
935 {
936 command_print(cmd_ctx, "usage: arm920t read_mmu <filename>");
937 return ERROR_OK;
938 }
939
940 if ((output = fopen(args[0], "w")) == NULL)
941 {
942 LOG_DEBUG("error opening mmu content file");
943 return ERROR_OK;
944 }
945
946 for (i = 0; i < 16; i++)
947 regs_p[i] = &regs[i];
948
949 /* disable MMU and Caches */
950 arm920t_read_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), &cp15_ctrl);
951 if ((retval = jtag_execute_queue()) != ERROR_OK)
952 {
953 return retval;
954 }
955 cp15_ctrl_saved = cp15_ctrl;
956 cp15_ctrl &= ~(ARMV4_5_MMU_ENABLED | ARMV4_5_D_U_CACHE_ENABLED | ARMV4_5_I_CACHE_ENABLED);
957 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), cp15_ctrl);
958
959 /* read CP15 test state register */
960 arm920t_read_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), &cp15c15);
961 if ((retval = jtag_execute_queue()) != ERROR_OK)
962 {
963 return retval;
964 }
965
966 /* prepare reading D TLB content
967 * */
968
969 /* set interpret mode */
970 cp15c15 |= 0x1;
971 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
972
973 /* Read D TLB lockdown */
974 arm920t_execute_cp15(target, ARMV4_5_MRC(15,0,0,10,0,0), ARMV4_5_LDR(1, 0));
975
976 /* clear interpret mode */
977 cp15c15 &= ~0x1;
978 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
979
980 /* read D TLB lockdown stored to r1 */
981 arm9tdmi_read_core_regs(target, 0x2, regs_p);
982 if ((retval = jtag_execute_queue()) != ERROR_OK)
983 {
984 return retval;
985 }
986 Dlockdown = regs[1];
987
988 for (victim = 0; victim < 64; victim += 8)
989 {
990 /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
991 * base remains unchanged, victim goes through entries 0 to 63 */
992 regs[1] = (Dlockdown & 0xfc000000) | (victim << 20);
993 arm9tdmi_write_core_regs(target, 0x2, regs);
994
995 /* set interpret mode */
996 cp15c15 |= 0x1;
997 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
998
999 /* Write D TLB lockdown */
1000 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,0), ARMV4_5_STR(1, 0));
1001
1002 /* Read D TLB CAM */
1003 arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,6,4), ARMV4_5_LDMIA(0, 0x3fc, 0, 0));
1004
1005 /* clear interpret mode */
1006 cp15c15 &= ~0x1;
1007 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
1008
1009 /* read D TLB CAM content stored to r2-r9 */
1010 arm9tdmi_read_core_regs(target, 0x3fc, regs_p);
1011 if ((retval = jtag_execute_queue()) != ERROR_OK)
1012 {
1013 return retval;
1014 }
1015
1016 for (i = 0; i < 8; i++)
1017 d_tlb[victim + i].cam = regs[i + 2];
1018 }
1019
1020 for (victim = 0; victim < 64; victim++)
1021 {
1022 /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
1023 * base remains unchanged, victim goes through entries 0 to 63 */
1024 regs[1] = (Dlockdown & 0xfc000000) | (victim << 20);
1025 arm9tdmi_write_core_regs(target, 0x2, regs);
1026
1027 /* set interpret mode */
1028 cp15c15 |= 0x1;
1029 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
1030
1031 /* Write D TLB lockdown */
1032 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,0), ARMV4_5_STR(1, 0));
1033
1034 /* Read D TLB RAM1 */
1035 arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,10,4), ARMV4_5_LDR(2,0));
1036
1037 /* Read D TLB RAM2 */
1038 arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,2,5), ARMV4_5_LDR(3,0));
1039
1040 /* clear interpret mode */
1041 cp15c15 &= ~0x1;
1042 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
1043
1044 /* read D TLB RAM content stored to r2 and r3 */
1045 arm9tdmi_read_core_regs(target, 0xc, regs_p);
1046 if ((retval = jtag_execute_queue()) != ERROR_OK)
1047 {
1048 return retval;
1049 }
1050
1051 d_tlb[victim].ram1 = regs[2];
1052 d_tlb[victim].ram2 = regs[3];
1053 }
1054
1055 /* restore D TLB lockdown */
1056 regs[1] = Dlockdown;
1057 arm9tdmi_write_core_regs(target, 0x2, regs);
1058
1059 /* Write D TLB lockdown */
1060 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,0), ARMV4_5_STR(1, 0));
1061
1062 /* prepare reading I TLB content
1063 * */
1064
1065 /* set interpret mode */
1066 cp15c15 |= 0x1;
1067 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
1068
1069 /* Read I TLB lockdown */
1070 arm920t_execute_cp15(target, ARMV4_5_MRC(15,0,0,10,0,1), ARMV4_5_LDR(1, 0));
1071
1072 /* clear interpret mode */
1073 cp15c15 &= ~0x1;
1074 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
1075
1076 /* read I TLB lockdown stored to r1 */
1077 arm9tdmi_read_core_regs(target, 0x2, regs_p);
1078 if ((retval = jtag_execute_queue()) != ERROR_OK)
1079 {
1080 return retval;
1081 }
1082 Ilockdown = regs[1];
1083
1084 for (victim = 0; victim < 64; victim += 8)
1085 {
1086 /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
1087 * base remains unchanged, victim goes through entries 0 to 63 */
1088 regs[1] = (Ilockdown & 0xfc000000) | (victim << 20);
1089 arm9tdmi_write_core_regs(target, 0x2, regs);
1090
1091 /* set interpret mode */
1092 cp15c15 |= 0x1;
1093 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
1094
1095 /* Write I TLB lockdown */
1096 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,1), ARMV4_5_STR(1, 0));
1097
1098 /* Read I TLB CAM */
1099 arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,5,4), ARMV4_5_LDMIA(0, 0x3fc, 0, 0));
1100
1101 /* clear interpret mode */
1102 cp15c15 &= ~0x1;
1103 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
1104
1105 /* read I TLB CAM content stored to r2-r9 */
1106 arm9tdmi_read_core_regs(target, 0x3fc, regs_p);
1107 if ((retval = jtag_execute_queue()) != ERROR_OK)
1108 {
1109 return retval;
1110 }
1111
1112 for (i = 0; i < 8; i++)
1113 i_tlb[i + victim].cam = regs[i + 2];
1114 }
1115
1116 for (victim = 0; victim < 64; victim++)
1117 {
1118 /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
1119 * base remains unchanged, victim goes through entries 0 to 63 */
1120 regs[1] = (Dlockdown & 0xfc000000) | (victim << 20);
1121 arm9tdmi_write_core_regs(target, 0x2, regs);
1122
1123 /* set interpret mode */
1124 cp15c15 |= 0x1;
1125 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
1126
1127 /* Write I TLB lockdown */
1128 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,1), ARMV4_5_STR(1, 0));
1129
1130 /* Read I TLB RAM1 */
1131 arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,9,4), ARMV4_5_LDR(2,0));
1132
1133 /* Read I TLB RAM2 */
1134 arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,1,5), ARMV4_5_LDR(3,0));
1135
1136 /* clear interpret mode */
1137 cp15c15 &= ~0x1;
1138 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
1139
1140 /* read I TLB RAM content stored to r2 and r3 */
1141 arm9tdmi_read_core_regs(target, 0xc, regs_p);
1142 if ((retval = jtag_execute_queue()) != ERROR_OK)
1143 {
1144 return retval;
1145 }
1146
1147 i_tlb[victim].ram1 = regs[2];
1148 i_tlb[victim].ram2 = regs[3];
1149 }
1150
1151 /* restore I TLB lockdown */
1152 regs[1] = Ilockdown;
1153 arm9tdmi_write_core_regs(target, 0x2, regs);
1154
1155 /* Write I TLB lockdown */
1156 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,1), ARMV4_5_STR(1, 0));
1157
1158 /* restore CP15 MMU and Cache settings */
1159 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), cp15_ctrl_saved);
1160
1161 /* output data to file */
1162 fprintf(output, "D TLB content:\n");
1163 for (i = 0; i < 64; i++)
1164 {
1165 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)");
1166 }
1167
1168 fprintf(output, "\n\nI TLB content:\n");
1169 for (i = 0; i < 64; i++)
1170 {
1171 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)");
1172 }
1173
1174 command_print(cmd_ctx, "mmu content successfully output to %s", args[0]);
1175
1176 fclose(output);
1177
1178 if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
1179 return ERROR_FAIL;
1180
1181 /* mark registers dirty */
1182 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;
1183 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;
1184 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;
1185 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;
1186 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;
1187 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;
1188 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;
1189 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;
1190 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;
1191 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;
1192
1193 return ERROR_OK;
1194 }
1195
1196 static int arm920t_handle_cp15_command(struct command_context_s *cmd_ctx,
1197 char *cmd, char **args, int argc)
1198 {
1199 int retval;
1200 target_t *target = get_current_target(cmd_ctx);
1201 struct arm920t_common_s *arm920t = target_to_arm920(target);
1202
1203 retval = arm920t_verify_pointer(cmd_ctx, arm920t);
1204 if (retval != ERROR_OK)
1205 return retval;
1206
1207 if (target->state != TARGET_HALTED)
1208 {
1209 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
1210 return ERROR_OK;
1211 }
1212
1213 /* one or more argument, access a single register (write if second argument is given */
1214 if (argc >= 1)
1215 {
1216 int address;
1217 COMMAND_PARSE_NUMBER(int, args[0], address);
1218
1219 if (argc == 1)
1220 {
1221 uint32_t value;
1222 if ((retval = arm920t_read_cp15_physical(target, address, &value)) != ERROR_OK)
1223 {
1224 command_print(cmd_ctx, "couldn't access reg %i", address);
1225 return ERROR_OK;
1226 }
1227 if ((retval = jtag_execute_queue()) != ERROR_OK)
1228 {
1229 return retval;
1230 }
1231
1232 command_print(cmd_ctx, "%i: %8.8" PRIx32 "", address, value);
1233 }
1234 else if (argc == 2)
1235 {
1236 uint32_t value;
1237 COMMAND_PARSE_NUMBER(u32, args[1], value);
1238 if ((retval = arm920t_write_cp15_physical(target, address, value)) != ERROR_OK)
1239 {
1240 command_print(cmd_ctx, "couldn't access reg %i", address);
1241 return ERROR_OK;
1242 }
1243 command_print(cmd_ctx, "%i: %8.8" PRIx32 "", address, value);
1244 }
1245 }
1246
1247 return ERROR_OK;
1248 }
1249
1250 static int arm920t_handle_cp15i_command(struct command_context_s *cmd_ctx,
1251 char *cmd, char **args, int argc)
1252 {
1253 int retval;
1254 target_t *target = get_current_target(cmd_ctx);
1255 struct arm920t_common_s *arm920t = target_to_arm920(target);
1256
1257 retval = arm920t_verify_pointer(cmd_ctx, arm920t);
1258 if (retval != ERROR_OK)
1259 return retval;
1260
1261
1262 if (target->state != TARGET_HALTED)
1263 {
1264 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
1265 return ERROR_OK;
1266 }
1267
1268 /* one or more argument, access a single register (write if second argument is given */
1269 if (argc >= 1)
1270 {
1271 uint32_t opcode;
1272 COMMAND_PARSE_NUMBER(u32, args[0], opcode);
1273
1274 if (argc == 1)
1275 {
1276 uint32_t value;
1277 if ((retval = arm920t_read_cp15_interpreted(target, opcode, 0x0, &value)) != ERROR_OK)
1278 {
1279 command_print(cmd_ctx, "couldn't execute %8.8" PRIx32 "", opcode);
1280 return ERROR_OK;
1281 }
1282
1283 command_print(cmd_ctx, "%8.8" PRIx32 ": %8.8" PRIx32 "", opcode, value);
1284 }
1285 else if (argc == 2)
1286 {
1287 uint32_t value;
1288 COMMAND_PARSE_NUMBER(u32, args[1], value);
1289 if ((retval = arm920t_write_cp15_interpreted(target, opcode, value, 0)) != ERROR_OK)
1290 {
1291 command_print(cmd_ctx, "couldn't execute %8.8" PRIx32 "", opcode);
1292 return ERROR_OK;
1293 }
1294 command_print(cmd_ctx, "%8.8" PRIx32 ": %8.8" PRIx32 "", opcode, value);
1295 }
1296 else if (argc == 3)
1297 {
1298 uint32_t value;
1299 COMMAND_PARSE_NUMBER(u32, args[1], value);
1300 uint32_t address;
1301 COMMAND_PARSE_NUMBER(u32, args[2], address);
1302 if ((retval = arm920t_write_cp15_interpreted(target, opcode, value, address)) != ERROR_OK)
1303 {
1304 command_print(cmd_ctx, "couldn't execute %8.8" PRIx32 "", opcode);
1305 return ERROR_OK;
1306 }
1307 command_print(cmd_ctx, "%8.8" PRIx32 ": %8.8" PRIx32 " %8.8" PRIx32 "", opcode, value, address);
1308 }
1309 }
1310 else
1311 {
1312 command_print(cmd_ctx, "usage: arm920t cp15i <opcode> [value] [address]");
1313 }
1314
1315 return ERROR_OK;
1316 }
1317
1318 static int arm920t_handle_cache_info_command(struct command_context_s *cmd_ctx,
1319 char *cmd, char **args, int argc)
1320 {
1321 int retval;
1322 target_t *target = get_current_target(cmd_ctx);
1323 struct arm920t_common_s *arm920t = target_to_arm920(target);
1324
1325 retval = arm920t_verify_pointer(cmd_ctx, arm920t);
1326 if (retval != ERROR_OK)
1327 return retval;
1328
1329 return armv4_5_handle_cache_info_command(cmd_ctx, &arm920t->armv4_5_mmu.armv4_5_cache);
1330 }
1331
1332
1333 static int arm920t_mrc(target_t *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t *value)
1334 {
1335 if (cpnum!=15)
1336 {
1337 LOG_ERROR("Only cp15 is supported");
1338 return ERROR_FAIL;
1339 }
1340
1341 return arm920t_read_cp15_interpreted(target, mrc_opcode(cpnum, op1, op2, CRn, CRm), 0, value);
1342 }
1343
1344 static int arm920t_mcr(target_t *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t value)
1345 {
1346 if (cpnum!=15)
1347 {
1348 LOG_ERROR("Only cp15 is supported");
1349 return ERROR_FAIL;
1350 }
1351
1352 return arm920t_write_cp15_interpreted(target, mrc_opcode(cpnum, op1, op2, CRn, CRm), 0, value);
1353 }
1354
1355 /** Registers commands to access coprocessor, cache, and MMU resources. */
1356 int arm920t_register_commands(struct command_context_s *cmd_ctx)
1357 {
1358 int retval;
1359 command_t *arm920t_cmd;
1360
1361 retval = arm9tdmi_register_commands(cmd_ctx);
1362
1363 arm920t_cmd = register_command(cmd_ctx, NULL, "arm920t",
1364 NULL, COMMAND_ANY,
1365 "arm920t specific commands");
1366
1367 register_command(cmd_ctx, arm920t_cmd, "cp15",
1368 arm920t_handle_cp15_command, COMMAND_EXEC,
1369 "display/modify cp15 register <num> [value]");
1370 register_command(cmd_ctx, arm920t_cmd, "cp15i",
1371 arm920t_handle_cp15i_command, COMMAND_EXEC,
1372 "display/modify cp15 (interpreted access) "
1373 "<opcode> [value] [address]");
1374 register_command(cmd_ctx, arm920t_cmd, "cache_info",
1375 arm920t_handle_cache_info_command, COMMAND_EXEC,
1376 "display information about target caches");
1377 register_command(cmd_ctx, arm920t_cmd, "read_cache",
1378 arm920t_handle_read_cache_command, COMMAND_EXEC,
1379 "display I/D cache content");
1380 register_command(cmd_ctx, arm920t_cmd, "read_mmu",
1381 arm920t_handle_read_mmu_command, COMMAND_EXEC,
1382 "display I/D mmu content");
1383
1384 return retval;
1385 }
1386
1387 /** Holds methods for ARM920 targets. */
1388 target_type_t arm920t_target =
1389 {
1390 .name = "arm920t",
1391
1392 .poll = arm7_9_poll,
1393 .arch_state = arm920t_arch_state,
1394
1395 .target_request_data = arm7_9_target_request_data,
1396
1397 .halt = arm7_9_halt,
1398 .resume = arm7_9_resume,
1399 .step = arm7_9_step,
1400
1401 .assert_reset = arm7_9_assert_reset,
1402 .deassert_reset = arm7_9_deassert_reset,
1403 .soft_reset_halt = arm920t_soft_reset_halt,
1404
1405 .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
1406
1407 .read_memory = arm920t_read_memory,
1408 .write_memory = arm920t_write_memory,
1409 .read_phys_memory = arm920t_read_phys_memory,
1410 .write_phys_memory = arm920t_write_phys_memory,
1411 .mmu = arm920_mmu,
1412 .virt2phys = arm920_virt2phys,
1413
1414 .bulk_write_memory = arm7_9_bulk_write_memory,
1415 .checksum_memory = arm7_9_checksum_memory,
1416 .blank_check_memory = arm7_9_blank_check_memory,
1417
1418 .run_algorithm = armv4_5_run_algorithm,
1419
1420 .add_breakpoint = arm7_9_add_breakpoint,
1421 .remove_breakpoint = arm7_9_remove_breakpoint,
1422 .add_watchpoint = arm7_9_add_watchpoint,
1423 .remove_watchpoint = arm7_9_remove_watchpoint,
1424
1425 .register_commands = arm920t_register_commands,
1426 .target_create = arm920t_target_create,
1427 .init_target = arm9tdmi_init_target,
1428 .examine = arm9tdmi_examine,
1429 .mrc = arm920t_mrc,
1430 .mcr = arm920t_mcr,
1431 };

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)