Laurentiu Cocanu - memory read/write and exit() error path fixes
[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 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_RTI);
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].device = jtag_info->chain_pos;
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].device = jtag_info->chain_pos;
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].device = jtag_info->chain_pos;
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].device = jtag_info->chain_pos;
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 arm7_9_execute_sys_speed(target);
297
298 if ((retval = jtag_execute_queue()) != ERROR_OK)
299 {
300 LOG_ERROR("failed executing JTAG queue, exiting");
301 return retval;
302 }
303
304 return ERROR_OK;
305 }
306
307 int arm920t_read_cp15_interpreted(target_t *target, u32 cp15_opcode, u32 address, u32 *value)
308 {
309 armv4_5_common_t *armv4_5 = target->arch_info;
310 u32* regs_p[1];
311 u32 regs[2];
312 u32 cp15c15 = 0x0;
313
314 /* load address into R1 */
315 regs[1] = address;
316 arm9tdmi_write_core_regs(target, 0x2, regs);
317
318 /* read-modify-write CP15 test state register
319 * to enable interpreted access mode */
320 arm920t_read_cp15_physical(target, 0x1e, &cp15c15);
321 jtag_execute_queue();
322 cp15c15 |= 1; /* set interpret mode */
323 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
324
325 /* execute CP15 instruction and ARM load (reading from coprocessor) */
326 arm920t_execute_cp15(target, cp15_opcode, ARMV4_5_LDR(0, 1));
327
328 /* disable interpreted access mode */
329 cp15c15 &= ~1U; /* clear interpret mode */
330 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
331
332 /* retrieve value from R0 */
333 regs_p[0] = value;
334 arm9tdmi_read_core_regs(target, 0x1, regs_p);
335 jtag_execute_queue();
336
337 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
338 LOG_DEBUG("cp15_opcode: %8.8x, address: %8.8x, value: %8.8x", cp15_opcode, address, *value);
339 #endif
340
341 if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
342 return ERROR_FAIL;
343
344 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).dirty = 1;
345 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 1).dirty = 1;
346
347 return ERROR_OK;
348 }
349
350 int arm920t_write_cp15_interpreted(target_t *target, u32 cp15_opcode, u32 value, u32 address)
351 {
352 u32 cp15c15 = 0x0;
353 armv4_5_common_t *armv4_5 = target->arch_info;
354 u32 regs[2];
355
356 /* load value, address into R0, R1 */
357 regs[0] = value;
358 regs[1] = address;
359 arm9tdmi_write_core_regs(target, 0x3, regs);
360
361 /* read-modify-write CP15 test state register
362 * to enable interpreted access mode */
363 arm920t_read_cp15_physical(target, 0x1e, &cp15c15);
364 jtag_execute_queue();
365 cp15c15 |= 1; /* set interpret mode */
366 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
367
368 /* execute CP15 instruction and ARM store (writing to coprocessor) */
369 arm920t_execute_cp15(target, cp15_opcode, ARMV4_5_STR(0, 1));
370
371 /* disable interpreted access mode */
372 cp15c15 &= ~1U; /* set interpret mode */
373 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
374
375 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
376 LOG_DEBUG("cp15_opcode: %8.8x, value: %8.8x, address: %8.8x", cp15_opcode, value, address);
377 #endif
378
379 if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
380 return ERROR_FAIL;
381
382 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).dirty = 1;
383 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 1).dirty = 1;
384
385 return ERROR_OK;
386 }
387
388 u32 arm920t_get_ttb(target_t *target)
389 {
390 int retval;
391 u32 ttb = 0x0;
392
393 if ((retval = arm920t_read_cp15_interpreted(target, 0xeebf0f51, 0x0, &ttb)) != ERROR_OK)
394 return retval;
395
396 return ttb;
397 }
398
399 void arm920t_disable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
400 {
401 u32 cp15_control;
402
403 /* read cp15 control register */
404 arm920t_read_cp15_physical(target, 0x2, &cp15_control);
405 jtag_execute_queue();
406
407 if (mmu)
408 cp15_control &= ~0x1U;
409
410 if (d_u_cache)
411 cp15_control &= ~0x4U;
412
413 if (i_cache)
414 cp15_control &= ~0x1000U;
415
416 arm920t_write_cp15_physical(target, 0x2, cp15_control);
417 }
418
419 void arm920t_enable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
420 {
421 u32 cp15_control;
422
423 /* read cp15 control register */
424 arm920t_read_cp15_physical(target, 0x2, &cp15_control);
425 jtag_execute_queue();
426
427 if (mmu)
428 cp15_control |= 0x1U;
429
430 if (d_u_cache)
431 cp15_control |= 0x4U;
432
433 if (i_cache)
434 cp15_control |= 0x1000U;
435
436 arm920t_write_cp15_physical(target, 0x2, cp15_control);
437 }
438
439 void arm920t_post_debug_entry(target_t *target)
440 {
441 u32 cp15c15;
442 armv4_5_common_t *armv4_5 = target->arch_info;
443 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
444 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
445 arm920t_common_t *arm920t = arm9tdmi->arch_info;
446
447 /* examine cp15 control reg */
448 arm920t_read_cp15_physical(target, 0x2, &arm920t->cp15_control_reg);
449 jtag_execute_queue();
450 LOG_DEBUG("cp15_control_reg: %8.8x", arm920t->cp15_control_reg);
451
452 if (arm920t->armv4_5_mmu.armv4_5_cache.ctype == -1)
453 {
454 u32 cache_type_reg;
455 /* identify caches */
456 arm920t_read_cp15_physical(target, 0x1, &cache_type_reg);
457 jtag_execute_queue();
458 armv4_5_identify_cache(cache_type_reg, &arm920t->armv4_5_mmu.armv4_5_cache);
459 }
460
461 arm920t->armv4_5_mmu.mmu_enabled = (arm920t->cp15_control_reg & 0x1U) ? 1 : 0;
462 arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = (arm920t->cp15_control_reg & 0x4U) ? 1 : 0;
463 arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = (arm920t->cp15_control_reg & 0x1000U) ? 1 : 0;
464
465 /* save i/d fault status and address register */
466 arm920t_read_cp15_interpreted(target, 0xee150f10, 0x0, &arm920t->d_fsr);
467 arm920t_read_cp15_interpreted(target, 0xee150f30, 0x0, &arm920t->i_fsr);
468 arm920t_read_cp15_interpreted(target, 0xee160f10, 0x0, &arm920t->d_far);
469 arm920t_read_cp15_interpreted(target, 0xee160f30, 0x0, &arm920t->i_far);
470
471 LOG_DEBUG("D FSR: 0x%8.8x, D FAR: 0x%8.8x, I FSR: 0x%8.8x, I FAR: 0x%8.8x",
472 arm920t->d_fsr, arm920t->d_far, arm920t->i_fsr, arm920t->i_far);
473
474 if (arm920t->preserve_cache)
475 {
476 /* read-modify-write CP15 test state register
477 * to disable I/D-cache linefills */
478 arm920t_read_cp15_physical(target, 0x1e, &cp15c15);
479 jtag_execute_queue();
480 cp15c15 |= 0x600;
481 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
482 }
483 }
484
485 void arm920t_pre_restore_context(target_t *target)
486 {
487 u32 cp15c15;
488 armv4_5_common_t *armv4_5 = target->arch_info;
489 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
490 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
491 arm920t_common_t *arm920t = arm9tdmi->arch_info;
492
493 /* restore i/d fault status and address register */
494 arm920t_write_cp15_interpreted(target, 0xee050f10, arm920t->d_fsr, 0x0);
495 arm920t_write_cp15_interpreted(target, 0xee050f30, arm920t->i_fsr, 0x0);
496 arm920t_write_cp15_interpreted(target, 0xee060f10, arm920t->d_far, 0x0);
497 arm920t_write_cp15_interpreted(target, 0xee060f30, arm920t->i_far, 0x0);
498
499 /* read-modify-write CP15 test state register
500 * to reenable I/D-cache linefills */
501 if (arm920t->preserve_cache)
502 {
503 arm920t_read_cp15_physical(target, 0x1e, &cp15c15);
504 jtag_execute_queue();
505 cp15c15 &= ~0x600U;
506 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
507 }
508 }
509
510 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)
511 {
512 armv4_5_common_t *armv4_5 = target->arch_info;
513 arm7_9_common_t *arm7_9;
514 arm9tdmi_common_t *arm9tdmi;
515 arm920t_common_t *arm920t;
516
517 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
518 {
519 return -1;
520 }
521
522 arm7_9 = armv4_5->arch_info;
523 if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
524 {
525 return -1;
526 }
527
528 arm9tdmi = arm7_9->arch_info;
529 if (arm9tdmi->common_magic != ARM9TDMI_COMMON_MAGIC)
530 {
531 return -1;
532 }
533
534 arm920t = arm9tdmi->arch_info;
535 if (arm920t->common_magic != ARM920T_COMMON_MAGIC)
536 {
537 return -1;
538 }
539
540 *armv4_5_p = armv4_5;
541 *arm7_9_p = arm7_9;
542 *arm9tdmi_p = arm9tdmi;
543 *arm920t_p = arm920t;
544
545 return ERROR_OK;
546 }
547
548 int arm920t_arch_state(struct target_s *target)
549 {
550 armv4_5_common_t *armv4_5 = target->arch_info;
551 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
552 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
553 arm920t_common_t *arm920t = arm9tdmi->arch_info;
554
555 char *state[] =
556 {
557 "disabled", "enabled"
558 };
559
560 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
561 {
562 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
563 exit(-1);
564 }
565
566 LOG_USER( "target halted in %s state due to %s, current mode: %s\n"
567 "cpsr: 0x%8.8x pc: 0x%8.8x\n"
568 "MMU: %s, D-Cache: %s, I-Cache: %s",
569 armv4_5_state_strings[armv4_5->core_state],
570 Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name,
571 armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)],
572 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
573 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
574 state[arm920t->armv4_5_mmu.mmu_enabled],
575 state[arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],
576 state[arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled]);
577
578 return ERROR_OK;
579 }
580
581 int arm920t_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
582 {
583 int retval;
584
585 retval = arm7_9_read_memory(target, address, size, count, buffer);
586
587 return retval;
588 }
589
590 int arm920t_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
591 {
592 int retval;
593 armv4_5_common_t *armv4_5 = target->arch_info;
594 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
595 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
596 arm920t_common_t *arm920t = arm9tdmi->arch_info;
597
598 if ((retval = arm7_9_write_memory(target, address, size, count, buffer)) != ERROR_OK)
599 return retval;
600
601 if (((size == 4) || (size == 2)) && (count == 1))
602 {
603 if (arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled)
604 {
605 LOG_DEBUG("D-Cache enabled, writing through to main memory");
606 u32 pa, cb, ap;
607 int type, domain;
608
609 pa = armv4_5_mmu_translate_va(target, &arm920t->armv4_5_mmu, address, &type, &cb, &domain, &ap);
610 if (type == -1)
611 return ERROR_OK;
612 /* cacheable & bufferable means write-back region */
613 if (cb == 3)
614 armv4_5_mmu_write_physical(target, &arm920t->armv4_5_mmu, pa, size, count, buffer);
615 }
616
617 if (arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled)
618 {
619 LOG_DEBUG("I-Cache enabled, invalidating affected I-Cache line");
620 arm920t_write_cp15_interpreted(target, 0xee070f35, 0x0, address);
621 }
622 }
623
624 return retval;
625 }
626
627 int arm920t_soft_reset_halt(struct target_s *target)
628 {
629 int retval = ERROR_OK;
630 armv4_5_common_t *armv4_5 = target->arch_info;
631 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
632 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
633 arm920t_common_t *arm920t = arm9tdmi->arch_info;
634 reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
635
636 if((retval = target_halt(target)) != ERROR_OK)
637 {
638 return retval;
639 }
640
641 long long then=timeval_ms();
642 int timeout;
643 while (!(timeout=((timeval_ms()-then)>1000)))
644 {
645 if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0)
646 {
647 embeddedice_read_reg(dbg_stat);
648 if((retval = jtag_execute_queue()) != ERROR_OK)
649 {
650 return retval;
651 }
652 } else
653 {
654 break;
655 }
656 if (debug_level>=3)
657 {
658 /* do not eat all CPU, time out after 1 se*/
659 alive_sleep(100);
660 } else
661 {
662 keep_alive();
663 }
664 }
665 if (timeout)
666 {
667 LOG_ERROR("Failed to halt CPU after 1 sec");
668 return ERROR_TARGET_TIMEOUT;
669 }
670
671 target->state = TARGET_HALTED;
672
673 /* SVC, ARM state, IRQ and FIQ disabled */
674 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8, 0xd3);
675 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
676 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
677
678 /* start fetching from 0x0 */
679 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
680 armv4_5->core_cache->reg_list[15].dirty = 1;
681 armv4_5->core_cache->reg_list[15].valid = 1;
682
683 armv4_5->core_mode = ARMV4_5_MODE_SVC;
684 armv4_5->core_state = ARMV4_5_STATE_ARM;
685
686 arm920t_disable_mmu_caches(target, 1, 1, 1);
687 arm920t->armv4_5_mmu.mmu_enabled = 0;
688 arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;
689 arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;
690
691 if((retval = target_call_event_callbacks(target, TARGET_EVENT_HALTED)) != ERROR_OK)
692 {
693 return retval;
694 }
695
696 return ERROR_OK;
697 }
698
699 int arm920t_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
700 {
701 arm9tdmi_init_target(cmd_ctx, target);
702
703 return ERROR_OK;
704
705 }
706
707 int arm920t_quit(void)
708 {
709
710 return ERROR_OK;
711 }
712
713 int arm920t_init_arch_info(target_t *target, arm920t_common_t *arm920t, int chain_pos, const char *variant)
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, chain_pos, variant);
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->chain_position, target->variant);
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
999
1000 /* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */
1001 regs[0] = 0x0 | (segment << 5) | (C15_C_D_Ind << 26);
1002 arm9tdmi_write_core_regs(target, 0x1, regs);
1003
1004 /* set interpret mode */
1005 cp15c15 |= 0x1;
1006 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
1007
1008 /* Write ICache victim */
1009 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,9,1,1), ARMV4_5_LDR(1, 0));
1010
1011 /* clear interpret mode */
1012 cp15c15 &= ~0x1;
1013 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
1014 }
1015
1016 /* restore CP15 MMU and Cache settings */
1017 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), cp15_ctrl_saved);
1018
1019 command_print(cmd_ctx, "cache content successfully output to %s", args[0]);
1020
1021 fclose(output);
1022
1023 if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
1024 return ERROR_FAIL;
1025
1026 /* mark registers dirty. */
1027 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;
1028 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;
1029 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;
1030 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;
1031 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;
1032 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;
1033 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;
1034 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;
1035 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;
1036 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;
1037
1038 return ERROR_OK;
1039 }
1040
1041 int arm920t_handle_read_mmu_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1042 {
1043 int retval = ERROR_OK;
1044 target_t *target = get_current_target(cmd_ctx);
1045 armv4_5_common_t *armv4_5;
1046 arm7_9_common_t *arm7_9;
1047 arm9tdmi_common_t *arm9tdmi;
1048 arm920t_common_t *arm920t;
1049 arm_jtag_t *jtag_info;
1050 u32 cp15c15;
1051 u32 cp15_ctrl, cp15_ctrl_saved;
1052 u32 regs[16];
1053 u32 *regs_p[16];
1054 int i;
1055 FILE *output;
1056 u32 Dlockdown, Ilockdown;
1057 arm920t_tlb_entry_t d_tlb[64], i_tlb[64];
1058 int victim;
1059
1060 if (argc != 1)
1061 {
1062 command_print(cmd_ctx, "usage: arm920t read_mmu <filename>");
1063 return ERROR_OK;
1064 }
1065
1066 if ((output = fopen(args[0], "w")) == NULL)
1067 {
1068 LOG_DEBUG("error opening mmu content file");
1069 return ERROR_OK;
1070 }
1071
1072 for (i = 0; i < 16; i++)
1073 regs_p[i] = &regs[i];
1074
1075 if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
1076 {
1077 command_print(cmd_ctx, "current target isn't an ARM920t target");
1078 return ERROR_OK;
1079 }
1080
1081 jtag_info = &arm7_9->jtag_info;
1082
1083 /* disable MMU and Caches */
1084 arm920t_read_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), &cp15_ctrl);
1085 if((retval = jtag_execute_queue()) != ERROR_OK)
1086 {
1087 return retval;
1088 }
1089 cp15_ctrl_saved = cp15_ctrl;
1090 cp15_ctrl &= ~(ARMV4_5_MMU_ENABLED | ARMV4_5_D_U_CACHE_ENABLED | ARMV4_5_I_CACHE_ENABLED);
1091 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), cp15_ctrl);
1092
1093 /* read CP15 test state register */
1094 arm920t_read_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), &cp15c15);
1095 if((retval = jtag_execute_queue()) != ERROR_OK)
1096 {
1097 return retval;
1098 }
1099
1100 /* prepare reading D TLB content
1101 * */
1102
1103 /* set interpret mode */
1104 cp15c15 |= 0x1;
1105 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
1106
1107 /* Read D TLB lockdown */
1108 arm920t_execute_cp15(target, ARMV4_5_MRC(15,0,0,10,0,0), ARMV4_5_LDR(1, 0));
1109
1110 /* clear interpret mode */
1111 cp15c15 &= ~0x1;
1112 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
1113
1114 /* read D TLB lockdown stored to r1 */
1115 arm9tdmi_read_core_regs(target, 0x2, regs_p);
1116 if((retval = jtag_execute_queue()) != ERROR_OK)
1117 {
1118 return retval;
1119 }
1120 Dlockdown = regs[1];
1121
1122 for (victim = 0; victim < 64; victim += 8)
1123 {
1124 /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
1125 * base remains unchanged, victim goes through entries 0 to 63 */
1126 regs[1] = (Dlockdown & 0xfc000000) | (victim << 20);
1127 arm9tdmi_write_core_regs(target, 0x2, regs);
1128
1129 /* set interpret mode */
1130 cp15c15 |= 0x1;
1131 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
1132
1133 /* Write D TLB lockdown */
1134 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,0), ARMV4_5_STR(1, 0));
1135
1136 /* Read D TLB CAM */
1137 arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,6,4), ARMV4_5_LDMIA(0, 0x3fc, 0, 0));
1138
1139 /* clear interpret mode */
1140 cp15c15 &= ~0x1;
1141 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
1142
1143 /* read D TLB CAM content stored to r2-r9 */
1144 arm9tdmi_read_core_regs(target, 0x3fc, regs_p);
1145 if((retval = jtag_execute_queue()) != ERROR_OK)
1146 {
1147 return retval;
1148 }
1149
1150 for (i = 0; i < 8; i++)
1151 d_tlb[victim + i].cam = regs[i + 2];
1152 }
1153
1154 for (victim = 0; victim < 64; victim++)
1155 {
1156 /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
1157 * base remains unchanged, victim goes through entries 0 to 63 */
1158 regs[1] = (Dlockdown & 0xfc000000) | (victim << 20);
1159 arm9tdmi_write_core_regs(target, 0x2, regs);
1160
1161 /* set interpret mode */
1162 cp15c15 |= 0x1;
1163 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
1164
1165 /* Write D TLB lockdown */
1166 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,0), ARMV4_5_STR(1, 0));
1167
1168 /* Read D TLB RAM1 */
1169 arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,10,4), ARMV4_5_LDR(2,0));
1170
1171 /* Read D TLB RAM2 */
1172 arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,2,5), ARMV4_5_LDR(3,0));
1173
1174 /* clear interpret mode */
1175 cp15c15 &= ~0x1;
1176 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
1177
1178 /* read D TLB RAM content stored to r2 and r3 */
1179 arm9tdmi_read_core_regs(target, 0xc, regs_p);
1180 if((retval = jtag_execute_queue()) != ERROR_OK)
1181 {
1182 return retval;
1183 }
1184
1185 d_tlb[victim].ram1 = regs[2];
1186 d_tlb[victim].ram2 = regs[3];
1187 }
1188
1189 /* restore D TLB lockdown */
1190 regs[1] = Dlockdown;
1191 arm9tdmi_write_core_regs(target, 0x2, regs);
1192
1193 /* Write D TLB lockdown */
1194 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,0), ARMV4_5_STR(1, 0));
1195
1196 /* prepare reading I TLB content
1197 * */
1198
1199 /* set interpret mode */
1200 cp15c15 |= 0x1;
1201 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
1202
1203 /* Read I TLB lockdown */
1204 arm920t_execute_cp15(target, ARMV4_5_MRC(15,0,0,10,0,1), ARMV4_5_LDR(1, 0));
1205
1206 /* clear interpret mode */
1207 cp15c15 &= ~0x1;
1208 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
1209
1210 /* read I TLB lockdown stored to r1 */
1211 arm9tdmi_read_core_regs(target, 0x2, regs_p);
1212 if((retval = jtag_execute_queue()) != ERROR_OK)
1213 {
1214 return retval;
1215 }
1216 Ilockdown = regs[1];
1217
1218 for (victim = 0; victim < 64; victim += 8)
1219 {
1220 /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
1221 * base remains unchanged, victim goes through entries 0 to 63 */
1222 regs[1] = (Ilockdown & 0xfc000000) | (victim << 20);
1223 arm9tdmi_write_core_regs(target, 0x2, regs);
1224
1225 /* set interpret mode */
1226 cp15c15 |= 0x1;
1227 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
1228
1229 /* Write I TLB lockdown */
1230 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,1), ARMV4_5_STR(1, 0));
1231
1232 /* Read I TLB CAM */
1233 arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,5,4), ARMV4_5_LDMIA(0, 0x3fc, 0, 0));
1234
1235 /* clear interpret mode */
1236 cp15c15 &= ~0x1;
1237 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
1238
1239 /* read I TLB CAM content stored to r2-r9 */
1240 arm9tdmi_read_core_regs(target, 0x3fc, regs_p);
1241 if((retval = jtag_execute_queue()) != ERROR_OK)
1242 {
1243 return retval;
1244 }
1245
1246 for (i = 0; i < 8; i++)
1247 i_tlb[i + victim].cam = regs[i + 2];
1248 }
1249
1250 for (victim = 0; victim < 64; victim++)
1251 {
1252 /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
1253 * base remains unchanged, victim goes through entries 0 to 63 */
1254 regs[1] = (Dlockdown & 0xfc000000) | (victim << 20);
1255 arm9tdmi_write_core_regs(target, 0x2, regs);
1256
1257 /* set interpret mode */
1258 cp15c15 |= 0x1;
1259 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
1260
1261 /* Write I TLB lockdown */
1262 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,1), ARMV4_5_STR(1, 0));
1263
1264 /* Read I TLB RAM1 */
1265 arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,9,4), ARMV4_5_LDR(2,0));
1266
1267 /* Read I TLB RAM2 */
1268 arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,1,5), ARMV4_5_LDR(3,0));
1269
1270 /* clear interpret mode */
1271 cp15c15 &= ~0x1;
1272 arm920t_write_cp15_physical(target, 0x1e, cp15c15);
1273
1274 /* read I TLB RAM content stored to r2 and r3 */
1275 arm9tdmi_read_core_regs(target, 0xc, regs_p);
1276 if((retval = jtag_execute_queue()) != ERROR_OK)
1277 {
1278 return retval;
1279 }
1280
1281 i_tlb[victim].ram1 = regs[2];
1282 i_tlb[victim].ram2 = regs[3];
1283 }
1284
1285 /* restore I TLB lockdown */
1286 regs[1] = Ilockdown;
1287 arm9tdmi_write_core_regs(target, 0x2, regs);
1288
1289 /* Write I TLB lockdown */
1290 arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,1), ARMV4_5_STR(1, 0));
1291
1292 /* restore CP15 MMU and Cache settings */
1293 arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), cp15_ctrl_saved);
1294
1295 /* output data to file */
1296 fprintf(output, "D TLB content:\n");
1297 for (i = 0; i < 64; i++)
1298 {
1299 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)");
1300 }
1301
1302 fprintf(output, "\n\nI TLB content:\n");
1303 for (i = 0; i < 64; i++)
1304 {
1305 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)");
1306 }
1307
1308 command_print(cmd_ctx, "mmu content successfully output to %s", args[0]);
1309
1310 fclose(output);
1311
1312 if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
1313 return ERROR_FAIL;
1314
1315 /* mark registers dirty */
1316 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;
1317 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;
1318 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;
1319 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;
1320 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;
1321 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;
1322 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;
1323 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;
1324 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;
1325 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;
1326
1327 return ERROR_OK;
1328 }
1329 int arm920t_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1330 {
1331 int retval;
1332 target_t *target = get_current_target(cmd_ctx);
1333 armv4_5_common_t *armv4_5;
1334 arm7_9_common_t *arm7_9;
1335 arm9tdmi_common_t *arm9tdmi;
1336 arm920t_common_t *arm920t;
1337 arm_jtag_t *jtag_info;
1338
1339 if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
1340 {
1341 command_print(cmd_ctx, "current target isn't an ARM920t target");
1342 return ERROR_OK;
1343 }
1344
1345 jtag_info = &arm7_9->jtag_info;
1346
1347 if (target->state != TARGET_HALTED)
1348 {
1349 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
1350 return ERROR_OK;
1351 }
1352
1353 /* one or more argument, access a single register (write if second argument is given */
1354 if (argc >= 1)
1355 {
1356 int address = strtoul(args[0], NULL, 0);
1357
1358 if (argc == 1)
1359 {
1360 u32 value;
1361 if ((retval = arm920t_read_cp15_physical(target, address, &value)) != ERROR_OK)
1362 {
1363 command_print(cmd_ctx, "couldn't access reg %i", address);
1364 return ERROR_OK;
1365 }
1366 if((retval = jtag_execute_queue()) != ERROR_OK)
1367 {
1368 return retval;
1369 }
1370
1371 command_print(cmd_ctx, "%i: %8.8x", address, value);
1372 }
1373 else if (argc == 2)
1374 {
1375 u32 value = strtoul(args[1], NULL, 0);
1376 if ((retval = arm920t_write_cp15_physical(target, address, value)) != ERROR_OK)
1377 {
1378 command_print(cmd_ctx, "couldn't access reg %i", address);
1379 return ERROR_OK;
1380 }
1381 command_print(cmd_ctx, "%i: %8.8x", address, value);
1382 }
1383 }
1384
1385 return ERROR_OK;
1386 }
1387
1388 int arm920t_handle_cp15i_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1389 {
1390 int retval;
1391 target_t *target = get_current_target(cmd_ctx);
1392 armv4_5_common_t *armv4_5;
1393 arm7_9_common_t *arm7_9;
1394 arm9tdmi_common_t *arm9tdmi;
1395 arm920t_common_t *arm920t;
1396 arm_jtag_t *jtag_info;
1397
1398 if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
1399 {
1400 command_print(cmd_ctx, "current target isn't an ARM920t target");
1401 return ERROR_OK;
1402 }
1403
1404 jtag_info = &arm7_9->jtag_info;
1405
1406 if (target->state != TARGET_HALTED)
1407 {
1408 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
1409 return ERROR_OK;
1410 }
1411
1412 /* one or more argument, access a single register (write if second argument is given */
1413 if (argc >= 1)
1414 {
1415 u32 opcode = strtoul(args[0], NULL, 0);
1416
1417 if (argc == 1)
1418 {
1419 u32 value;
1420 if ((retval = arm920t_read_cp15_interpreted(target, opcode, 0x0, &value)) != ERROR_OK)
1421 {
1422 command_print(cmd_ctx, "couldn't execute %8.8x", opcode);
1423 return ERROR_OK;
1424 }
1425
1426 command_print(cmd_ctx, "%8.8x: %8.8x", opcode, value);
1427 }
1428 else if (argc == 2)
1429 {
1430 u32 value = strtoul(args[1], NULL, 0);
1431 if ((retval = arm920t_write_cp15_interpreted(target, opcode, value, 0)) != ERROR_OK)
1432 {
1433 command_print(cmd_ctx, "couldn't execute %8.8x", opcode);
1434 return ERROR_OK;
1435 }
1436 command_print(cmd_ctx, "%8.8x: %8.8x", opcode, value);
1437 }
1438 else if (argc == 3)
1439 {
1440 u32 value = strtoul(args[1], NULL, 0);
1441 u32 address = strtoul(args[2], NULL, 0);
1442 if ((retval = arm920t_write_cp15_interpreted(target, opcode, value, address)) != ERROR_OK)
1443 {
1444 command_print(cmd_ctx, "couldn't execute %8.8x", opcode);
1445 return ERROR_OK;
1446 }
1447 command_print(cmd_ctx, "%8.8x: %8.8x %8.8x", opcode, value, address);
1448 }
1449 }
1450 else
1451 {
1452 command_print(cmd_ctx, "usage: arm920t cp15i <opcode> [value] [address]");
1453 }
1454
1455 return ERROR_OK;
1456 }
1457
1458 int arm920t_handle_cache_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1459 {
1460 target_t *target = get_current_target(cmd_ctx);
1461 armv4_5_common_t *armv4_5;
1462 arm7_9_common_t *arm7_9;
1463 arm9tdmi_common_t *arm9tdmi;
1464 arm920t_common_t *arm920t;
1465
1466 if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
1467 {
1468 command_print(cmd_ctx, "current target isn't an ARM920t target");
1469 return ERROR_OK;
1470 }
1471
1472 return armv4_5_handle_cache_info_command(cmd_ctx, &arm920t->armv4_5_mmu.armv4_5_cache);
1473 }
1474
1475 int arm920t_handle_virt2phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
1476 {
1477 target_t *target = get_current_target(cmd_ctx);
1478 armv4_5_common_t *armv4_5;
1479 arm7_9_common_t *arm7_9;
1480 arm9tdmi_common_t *arm9tdmi;
1481 arm920t_common_t *arm920t;
1482 arm_jtag_t *jtag_info;
1483
1484 if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
1485 {
1486 command_print(cmd_ctx, "current target isn't an ARM920t target");
1487 return ERROR_OK;
1488 }
1489
1490 jtag_info = &arm7_9->jtag_info;
1491
1492 if (target->state != TARGET_HALTED)
1493 {
1494 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
1495 return ERROR_OK;
1496 }
1497
1498 return armv4_5_mmu_handle_virt2phys_command(cmd_ctx, cmd, args, argc, target, &arm920t->armv4_5_mmu);
1499 }
1500
1501 int arm920t_handle_md_phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
1502 {
1503 target_t *target = get_current_target(cmd_ctx);
1504 armv4_5_common_t *armv4_5;
1505 arm7_9_common_t *arm7_9;
1506 arm9tdmi_common_t *arm9tdmi;
1507 arm920t_common_t *arm920t;
1508 arm_jtag_t *jtag_info;
1509
1510 if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
1511 {
1512 command_print(cmd_ctx, "current target isn't an ARM920t target");
1513 return ERROR_OK;
1514 }
1515
1516 jtag_info = &arm7_9->jtag_info;
1517
1518 if (target->state != TARGET_HALTED)
1519 {
1520 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
1521 return ERROR_OK;
1522 }
1523
1524 return armv4_5_mmu_handle_md_phys_command(cmd_ctx, cmd, args, argc, target, &arm920t->armv4_5_mmu);
1525 }
1526
1527 int arm920t_handle_mw_phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
1528 {
1529 target_t *target = get_current_target(cmd_ctx);
1530 armv4_5_common_t *armv4_5;
1531 arm7_9_common_t *arm7_9;
1532 arm9tdmi_common_t *arm9tdmi;
1533 arm920t_common_t *arm920t;
1534 arm_jtag_t *jtag_info;
1535
1536 if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
1537 {
1538 command_print(cmd_ctx, "current target isn't an ARM920t target");
1539 return ERROR_OK;
1540 }
1541
1542 jtag_info = &arm7_9->jtag_info;
1543
1544 if (target->state != TARGET_HALTED)
1545 {
1546 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
1547 return ERROR_OK;
1548 }
1549
1550 return armv4_5_mmu_handle_mw_phys_command(cmd_ctx, cmd, args, argc, target, &arm920t->armv4_5_mmu);
1551 }

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)