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

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)