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

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)