a89a5a5a4738933085d7d5f14ab5abbeb8852227
[openocd.git] / src / flash / str9xpec.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 "replacements.h"
25
26 #include "str9xpec.h"
27 #include "flash.h"
28 #include "target.h"
29 #include "log.h"
30 #include "armv4_5.h"
31 #include "arm7_9_common.h"
32 #include "jtag.h"
33 #include "binarybuffer.h"
34
35 #include <stdlib.h>
36 #include <string.h>
37 #include <unistd.h>
38 #include <getopt.h>
39
40 str9xpec_mem_layout_t mem_layout_str9pec[] = {
41 {0x00000000, 0x10000, 0},
42 {0x00010000, 0x10000, 1},
43 {0x00020000, 0x10000, 2},
44 {0x00030000, 0x10000, 3},
45 {0x00040000, 0x10000, 4},
46 {0x00050000, 0x10000, 5},
47 {0x00060000, 0x10000, 6},
48 {0x00070000, 0x10000, 7},
49 {0x00080000, 0x02000, 32},
50 {0x00082000, 0x02000, 33},
51 {0x00084000, 0x02000, 34},
52 {0x00086000, 0x02000, 35}
53 };
54
55 int str9xpec_register_commands(struct command_context_s *cmd_ctx);
56 int str9xpec_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
57 int str9xpec_erase(struct flash_bank_s *bank, int first, int last);
58 int str9xpec_protect(struct flash_bank_s *bank, int set, int first, int last);
59 int str9xpec_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
60 int str9xpec_probe(struct flash_bank_s *bank);
61 int str9xpec_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
62 int str9xpec_protect_check(struct flash_bank_s *bank);
63 int str9xpec_erase_check(struct flash_bank_s *bank);
64 int str9xpec_info(struct flash_bank_s *bank, char *buf, int buf_size);
65
66 int str9xpec_erase_area(struct flash_bank_s *bank, int first, int last);
67 int str9xpec_set_address(struct flash_bank_s *bank, u8 sector);
68 int str9xpec_write_options(struct flash_bank_s *bank);
69
70 int str9xpec_handle_flash_options_cmap_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
71 int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
72 int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
73 int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
74 int str9xpec_handle_flash_options_read_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
75 int str9xpec_handle_flash_options_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
76 int str9xpec_handle_flash_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
77 int str9xpec_handle_flash_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
78 int str9xpec_handle_flash_enable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
79 int str9xpec_handle_flash_disable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
80
81 flash_driver_t str9xpec_flash =
82 {
83 .name = "str9xpec",
84 .register_commands = str9xpec_register_commands,
85 .flash_bank_command = str9xpec_flash_bank_command,
86 .erase = str9xpec_erase,
87 .protect = str9xpec_protect,
88 .write = str9xpec_write,
89 .probe = str9xpec_probe,
90 .erase_check = str9xpec_erase_check,
91 .protect_check = str9xpec_protect_check,
92 .info = str9xpec_info
93 };
94
95 int str9xpec_register_commands(struct command_context_s *cmd_ctx)
96 {
97 command_t *str9xpec_cmd = register_command(cmd_ctx, NULL, "str9xpec", NULL, COMMAND_ANY, "str9xpec flash specific commands");
98
99 register_command(cmd_ctx, str9xpec_cmd, "enable_turbo", str9xpec_handle_flash_enable_turbo_command, COMMAND_EXEC,
100 "enable str9xpec turbo mode");
101 register_command(cmd_ctx, str9xpec_cmd, "disable_turbo", str9xpec_handle_flash_disable_turbo_command, COMMAND_EXEC,
102 "disable str9xpec turbo mode");
103 register_command(cmd_ctx, str9xpec_cmd, "options_cmap", str9xpec_handle_flash_options_cmap_command, COMMAND_EXEC,
104 "configure str9xpec boot sector");
105 register_command(cmd_ctx, str9xpec_cmd, "options_lvdthd", str9xpec_handle_flash_options_lvdthd_command, COMMAND_EXEC,
106 "configure str9xpec lvd threshold");
107 register_command(cmd_ctx, str9xpec_cmd, "options_lvdsel", str9xpec_handle_flash_options_lvdsel_command, COMMAND_EXEC,
108 "configure str9xpec lvd selection");
109 register_command(cmd_ctx, str9xpec_cmd, "options_lvdwarn", str9xpec_handle_flash_options_lvdwarn_command, COMMAND_EXEC,
110 "configure str9xpec lvd warning");
111 register_command(cmd_ctx, str9xpec_cmd, "options_read", str9xpec_handle_flash_options_read_command, COMMAND_EXEC,
112 "read str9xpec options");
113 register_command(cmd_ctx, str9xpec_cmd, "options_write", str9xpec_handle_flash_options_write_command, COMMAND_EXEC,
114 "write str9xpec options");
115 register_command(cmd_ctx, str9xpec_cmd, "lock", str9xpec_handle_flash_lock_command, COMMAND_EXEC,
116 "lock str9xpec device");
117 register_command(cmd_ctx, str9xpec_cmd, "unlock", str9xpec_handle_flash_unlock_command, COMMAND_EXEC,
118 "unlock str9xpec device");
119 register_command(cmd_ctx, str9xpec_cmd, "part_id", str9xpec_handle_part_id_command, COMMAND_EXEC,
120 "print part id of str9xpec flash bank <num>");
121
122 return ERROR_OK;
123 }
124
125 int str9xpec_set_instr(int chain_pos, u32 new_instr, enum tap_state end_state)
126 {
127 jtag_device_t *device = jtag_get_device(chain_pos);
128
129 if (device == NULL)
130 {
131 DEBUG("Invalid Target");
132 return ERROR_TARGET_INVALID;
133 }
134
135 if (buf_get_u32(device->cur_instr, 0, device->ir_length) != new_instr)
136 {
137 scan_field_t field;
138
139 field.device = chain_pos;
140 field.num_bits = device->ir_length;
141 field.out_value = calloc(CEIL(field.num_bits, 8), 1);
142 buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
143 field.out_mask = NULL;
144 field.in_value = NULL;
145 field.in_check_value = NULL;
146 field.in_check_mask = NULL;
147 field.in_handler = NULL;
148 field.in_handler_priv = NULL;
149
150 jtag_add_ir_scan(1, &field, end_state, NULL);
151
152 free(field.out_value);
153 }
154
155 return ERROR_OK;
156 }
157
158 u8 str9xpec_isc_status(int chain_pos)
159 {
160 scan_field_t field;
161 u8 status;
162
163 if (str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI) != ERROR_OK)
164 return ISC_STATUS_ERROR;
165
166 field.device = chain_pos;
167 field.num_bits = 8;
168 field.out_value = NULL;
169 field.out_mask = NULL;
170 field.in_value = &status;
171 field.in_check_value = NULL;
172 field.in_check_mask = NULL;
173 field.in_handler = NULL;
174 field.in_handler_priv = NULL;
175
176 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
177 jtag_execute_queue();
178
179 DEBUG("status: 0x%2.2x", status);
180
181 if (status & ISC_STATUS_SECURITY)
182 INFO("Device Security Bit Set");
183
184 return status;
185 }
186
187 int str9xpec_isc_enable(struct flash_bank_s *bank)
188 {
189 u8 status;
190 u32 chain_pos;
191 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
192
193 chain_pos = str9xpec_info->chain_pos;
194
195 if (str9xpec_info->isc_enable)
196 return ERROR_OK;
197
198 /* enter isc mode */
199 if (str9xpec_set_instr(chain_pos, ISC_ENABLE, TAP_RTI) != ERROR_OK)
200 return ERROR_TARGET_INVALID;
201
202 /* check ISC status */
203 status = str9xpec_isc_status(chain_pos);
204 if (status & ISC_STATUS_MODE)
205 {
206 /* we have entered isc mode */
207 str9xpec_info->isc_enable = 1;
208 DEBUG("ISC_MODE Enabled");
209 }
210
211 return ERROR_OK;
212 }
213
214 int str9xpec_isc_disable(struct flash_bank_s *bank)
215 {
216 u8 status;
217 u32 chain_pos;
218 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
219
220 chain_pos = str9xpec_info->chain_pos;
221
222 if (!str9xpec_info->isc_enable)
223 return ERROR_OK;
224
225 if (str9xpec_set_instr(chain_pos, ISC_DISABLE, TAP_RTI) != ERROR_OK)
226 return ERROR_TARGET_INVALID;
227
228 /* delay to handle aborts */
229 jtag_add_sleep(50);
230
231 /* check ISC status */
232 status = str9xpec_isc_status(chain_pos);
233 if (!(status & ISC_STATUS_MODE))
234 {
235 /* we have left isc mode */
236 str9xpec_info->isc_enable = 0;
237 DEBUG("ISC_MODE Disabled");
238 }
239
240 return ERROR_OK;
241 }
242
243 int str9xpec_read_config(struct flash_bank_s *bank)
244 {
245 scan_field_t field;
246 u8 status;
247 u32 chain_pos;
248
249 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
250
251 chain_pos = str9xpec_info->chain_pos;
252
253 DEBUG("ISC_CONFIGURATION");
254
255 /* execute ISC_CONFIGURATION command */
256 str9xpec_set_instr(chain_pos, ISC_CONFIGURATION, TAP_PI);
257
258 field.device = chain_pos;
259 field.num_bits = 64;
260 field.out_value = NULL;
261 field.out_mask = NULL;
262 field.in_value = str9xpec_info->options;
263 field.in_check_value = NULL;
264 field.in_check_mask = NULL;
265 field.in_handler = NULL;
266 field.in_handler_priv = NULL;
267
268 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
269 jtag_execute_queue();
270
271 status = str9xpec_isc_status(chain_pos);
272
273 return status;
274 }
275
276 int str9xpec_build_block_list(struct flash_bank_s *bank)
277 {
278 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
279
280 int i;
281 int num_sectors = 0, b0_sectors = 0;
282
283 switch (bank->size)
284 {
285 case (256 * 1024):
286 b0_sectors = 4;
287 break;
288 case (512 * 1024):
289 b0_sectors = 8;
290 break;
291 default:
292 ERROR("BUG: unknown bank->size encountered");
293 exit(-1);
294 }
295
296 /* include bank 1 sectors */
297 num_sectors = b0_sectors + 4;
298 bank->size += (32 * 1024);
299
300 bank->num_sectors = num_sectors;
301 bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors);
302 str9xpec_info->sector_bits = malloc(sizeof(u32) * num_sectors);
303
304 num_sectors = 0;
305
306 for (i = 0; i < b0_sectors; i++)
307 {
308 bank->sectors[num_sectors].offset = mem_layout_str9pec[i].sector_start;
309 bank->sectors[num_sectors].size = mem_layout_str9pec[i].sector_size;
310 bank->sectors[num_sectors].is_erased = -1;
311 bank->sectors[num_sectors].is_protected = 1;
312 str9xpec_info->sector_bits[num_sectors++] = mem_layout_str9pec[i].sector_bit;
313 }
314
315 for (i = 8; i < 12; i++)
316 {
317 bank->sectors[num_sectors].offset = mem_layout_str9pec[i].sector_start;
318 bank->sectors[num_sectors].size = mem_layout_str9pec[i].sector_size;
319 bank->sectors[num_sectors].is_erased = -1;
320 bank->sectors[num_sectors].is_protected = 1;
321 str9xpec_info->sector_bits[num_sectors++] = mem_layout_str9pec[i].sector_bit;
322 }
323
324 return ERROR_OK;
325 }
326
327 /* flash bank str9x <base> <size> 0 0 <target#>
328 */
329 int str9xpec_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
330 {
331 str9xpec_flash_controller_t *str9xpec_info;
332 armv4_5_common_t *armv4_5 = NULL;
333 arm7_9_common_t *arm7_9 = NULL;
334 arm_jtag_t *jtag_info = NULL;
335
336 if (argc < 6)
337 {
338 WARNING("incomplete flash_bank str9x configuration");
339 return ERROR_FLASH_BANK_INVALID;
340 }
341
342 str9xpec_info = malloc(sizeof(str9xpec_flash_controller_t));
343 bank->driver_priv = str9xpec_info;
344
345 if (bank->base != 0x00000000)
346 {
347 WARNING("overriding flash base address for STR91x device with 0x00000000");
348 bank->base = 0x00000000;
349 }
350
351 /* find out jtag position of flash controller
352 * it is always after the arm966 core */
353
354 armv4_5 = bank->target->arch_info;
355 arm7_9 = armv4_5->arch_info;
356 jtag_info = &arm7_9->jtag_info;
357
358 str9xpec_info->chain_pos = (jtag_info->chain_pos - 1);
359 str9xpec_info->isc_enable = 0;
360 str9xpec_info->devarm = NULL;
361
362 str9xpec_build_block_list(bank);
363
364 /* clear option byte register */
365 buf_set_u32(str9xpec_info->options, 0, 64, 0);
366
367 return ERROR_OK;
368 }
369
370 int str9xpec_blank_check(struct flash_bank_s *bank, int first, int last)
371 {
372 scan_field_t field;
373 u8 status;
374 u32 chain_pos;
375 int i;
376 u8 *buffer = NULL;
377
378 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
379
380 chain_pos = str9xpec_info->chain_pos;
381
382 if (!str9xpec_info->isc_enable) {
383 str9xpec_isc_enable( bank );
384 }
385
386 if (!str9xpec_info->isc_enable) {
387 return ERROR_FLASH_OPERATION_FAILED;
388 }
389
390 buffer = calloc(CEIL(64, 8), 1);
391
392 DEBUG("blank check: first_bank: %i, last_bank: %i", first, last);
393
394 for (i = first; i <= last; i++) {
395 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
396 }
397
398 /* execute ISC_BLANK_CHECK command */
399 str9xpec_set_instr(chain_pos, ISC_BLANK_CHECK, TAP_PI);
400
401 field.device = chain_pos;
402 field.num_bits = 64;
403 field.out_value = buffer;
404 field.out_mask = NULL;
405 field.in_value = NULL;
406 field.in_check_value = NULL;
407 field.in_check_mask = NULL;
408 field.in_handler = NULL;
409 field.in_handler_priv = NULL;
410
411 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
412 jtag_add_sleep(40000);
413
414 /* read blank check result */
415 field.device = chain_pos;
416 field.num_bits = 64;
417 field.out_value = NULL;
418 field.out_mask = NULL;
419 field.in_value = buffer;
420 field.in_check_value = NULL;
421 field.in_check_mask = NULL;
422 field.in_handler = NULL;
423 field.in_handler_priv = NULL;
424
425 jtag_add_dr_scan(1, &field, TAP_PI, NULL);
426 jtag_execute_queue();
427
428 status = str9xpec_isc_status(chain_pos);
429
430 for (i = first; i <= last; i++)
431 {
432 if (buf_get_u32(buffer, str9xpec_info->sector_bits[i], 1))
433 bank->sectors[i].is_erased = 0;
434 else
435 bank->sectors[i].is_erased = 1;
436 }
437
438 free(buffer);
439
440 str9xpec_isc_disable(bank);
441
442 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
443 return ERROR_FLASH_OPERATION_FAILED;
444 return ERROR_OK;
445 }
446
447 int str9xpec_protect_check(struct flash_bank_s *bank)
448 {
449 u8 status;
450 int i;
451
452 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
453
454 status = str9xpec_read_config(bank);
455
456 for (i = 0; i < bank->num_sectors; i++)
457 {
458 if (buf_get_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1))
459 bank->sectors[i].is_protected = 1;
460 else
461 bank->sectors[i].is_protected = 0;
462 }
463
464 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
465 return ERROR_FLASH_OPERATION_FAILED;
466 return ERROR_OK;
467 }
468
469 int str9xpec_erase_area(struct flash_bank_s *bank, int first, int last)
470 {
471 scan_field_t field;
472 u8 status;
473 u32 chain_pos;
474 int i;
475 u8 *buffer = NULL;
476
477 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
478
479 chain_pos = str9xpec_info->chain_pos;
480
481 if (!str9xpec_info->isc_enable) {
482 str9xpec_isc_enable( bank );
483 }
484
485 if (!str9xpec_info->isc_enable) {
486 return ISC_STATUS_ERROR;
487 }
488
489 buffer = calloc(CEIL(64, 8), 1);
490
491 DEBUG("erase: first_bank: %i, last_bank: %i", first, last);
492
493 /* last bank: 0xFF signals a full erase (unlock complete device) */
494 /* last bank: 0xFE signals a option byte erase */
495 if (last == 0xFF)
496 {
497 for (i = 0; i < 64; i++) {
498 buf_set_u32(buffer, i, 1, 1);
499 }
500 }
501 else if (last == 0xFE)
502 {
503 buf_set_u32(buffer, 49, 1, 1);
504 }
505 else
506 {
507 for (i = first; i <= last; i++) {
508 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
509 }
510 }
511
512 DEBUG("ISC_ERASE");
513
514 /* execute ISC_ERASE command */
515 str9xpec_set_instr(chain_pos, ISC_ERASE, TAP_PI);
516
517 field.device = chain_pos;
518 field.num_bits = 64;
519 field.out_value = buffer;
520 field.out_mask = NULL;
521 field.in_value = NULL;
522 field.in_check_value = NULL;
523 field.in_check_mask = NULL;
524 field.in_handler = NULL;
525 field.in_handler_priv = NULL;
526
527 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
528 jtag_execute_queue();
529
530 jtag_add_sleep(10);
531
532 /* wait for erase completion */
533 while (!((status = str9xpec_isc_status(chain_pos)) & ISC_STATUS_BUSY)) {
534 usleep(1000);
535 }
536
537 free(buffer);
538
539 str9xpec_isc_disable(bank);
540
541 return status;
542 }
543
544 int str9xpec_erase(struct flash_bank_s *bank, int first, int last)
545 {
546 int status;
547
548 status = str9xpec_erase_area(bank, first, last);
549
550 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
551 return ERROR_FLASH_OPERATION_FAILED;
552
553 return ERROR_OK;
554 }
555
556 int str9xpec_lock_device(struct flash_bank_s *bank)
557 {
558 scan_field_t field;
559 u8 status;
560 u32 chain_pos;
561 str9xpec_flash_controller_t *str9xpec_info = NULL;
562
563 str9xpec_info = bank->driver_priv;
564 chain_pos = str9xpec_info->chain_pos;
565
566 if (!str9xpec_info->isc_enable) {
567 str9xpec_isc_enable( bank );
568 }
569
570 if (!str9xpec_info->isc_enable) {
571 return ISC_STATUS_ERROR;
572 }
573
574 /* set security address */
575 str9xpec_set_address(bank, 0x80);
576
577 /* execute ISC_PROGRAM command */
578 str9xpec_set_instr(chain_pos, ISC_PROGRAM_SECURITY, TAP_RTI);
579
580 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
581
582 do {
583 field.device = chain_pos;
584 field.num_bits = 8;
585 field.out_value = NULL;
586 field.out_mask = NULL;
587 field.in_value = &status;
588 field.in_check_value = NULL;
589 field.in_check_mask = NULL;
590 field.in_handler = NULL;
591 field.in_handler_priv = NULL;
592
593 jtag_add_dr_scan(1, &field, -1, NULL);
594 jtag_execute_queue();
595
596 } while(!(status & ISC_STATUS_BUSY));
597
598 str9xpec_isc_disable(bank);
599
600 return status;
601 }
602
603 int str9xpec_unlock_device(struct flash_bank_s *bank)
604 {
605 u8 status;
606
607 status = str9xpec_erase_area(bank, 0, 255);
608
609 return status;
610 }
611
612 int str9xpec_protect(struct flash_bank_s *bank, int set, int first, int last)
613 {
614 u8 status;
615 int i;
616
617 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
618
619 status = str9xpec_read_config(bank);
620
621 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
622 return ERROR_FLASH_OPERATION_FAILED;
623
624 DEBUG("protect: first_bank: %i, last_bank: %i", first, last);
625
626 /* last bank: 0xFF signals a full device protect */
627 if (last == 0xFF)
628 {
629 if( set )
630 {
631 status = str9xpec_lock_device(bank);
632 }
633 else
634 {
635 /* perform full erase to unlock device */
636 status = str9xpec_unlock_device(bank);
637 }
638 }
639 else
640 {
641 for (i = first; i <= last; i++)
642 {
643 if( set )
644 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 1);
645 else
646 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 0);
647 }
648
649 status = str9xpec_write_options(bank);
650 }
651
652 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
653 return ERROR_FLASH_OPERATION_FAILED;
654
655 return ERROR_OK;
656 }
657
658 int str9xpec_set_address(struct flash_bank_s *bank, u8 sector)
659 {
660 u32 chain_pos;
661 scan_field_t field;
662 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
663
664 chain_pos = str9xpec_info->chain_pos;
665
666 /* set flash controller address */
667 str9xpec_set_instr(chain_pos, ISC_ADDRESS_SHIFT, TAP_PI);
668
669 field.device = chain_pos;
670 field.num_bits = 8;
671 field.out_value = &sector;
672 field.out_mask = NULL;
673 field.in_value = NULL;
674 field.in_check_value = NULL;
675 field.in_check_mask = NULL;
676 field.in_handler = NULL;
677 field.in_handler_priv = NULL;
678
679 jtag_add_dr_scan(1, &field, -1, NULL);
680
681 return ERROR_OK;
682 }
683
684 int str9xpec_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
685 {
686 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
687 u32 dwords_remaining = (count / 8);
688 u32 bytes_remaining = (count & 0x00000007);
689 u32 bytes_written = 0;
690 u8 status;
691 u32 check_address = offset;
692 u32 chain_pos;
693 scan_field_t field;
694 u8 *scanbuf;
695 int i;
696 u32 first_sector = 0;
697 u32 last_sector = 0;
698
699 chain_pos = str9xpec_info->chain_pos;
700
701 if (!str9xpec_info->isc_enable) {
702 str9xpec_isc_enable(bank);
703 }
704
705 if (!str9xpec_info->isc_enable) {
706 return ERROR_FLASH_OPERATION_FAILED;
707 }
708
709 if (offset & 0x7)
710 {
711 WARNING("offset 0x%x breaks required 8-byte alignment", offset);
712 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
713 }
714
715 for (i = 0; i < bank->num_sectors; i++)
716 {
717 u32 sec_start = bank->sectors[i].offset;
718 u32 sec_end = sec_start + bank->sectors[i].size;
719
720 /* check if destination falls within the current sector */
721 if ((check_address >= sec_start) && (check_address < sec_end))
722 {
723 /* check if destination ends in the current sector */
724 if (offset + count < sec_end)
725 check_address = offset + count;
726 else
727 check_address = sec_end;
728 }
729
730 if ((offset >= sec_start) && (offset < sec_end)){
731 first_sector = i;
732 }
733
734 if ((offset + count >= sec_start) && (offset + count < sec_end)){
735 last_sector = i;
736 }
737 }
738
739 if (check_address != offset + count)
740 return ERROR_FLASH_DST_OUT_OF_BANK;
741
742 DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
743
744 scanbuf = calloc(CEIL(64, 8), 1);
745
746 DEBUG("ISC_PROGRAM");
747
748 for (i = first_sector; i <= last_sector; i++)
749 {
750 str9xpec_set_address(bank, str9xpec_info->sector_bits[i]);
751
752 dwords_remaining = dwords_remaining < (bank->sectors[i].size/8) ? dwords_remaining : (bank->sectors[i].size/8);
753
754 while (dwords_remaining > 0)
755 {
756 str9xpec_set_instr(chain_pos, ISC_PROGRAM, TAP_PI);
757
758 field.device = chain_pos;
759 field.num_bits = 64;
760 field.out_value = (buffer + bytes_written);
761 field.out_mask = NULL;
762 field.in_value = NULL;
763 field.in_check_value = NULL;
764 field.in_check_mask = NULL;
765 field.in_handler = NULL;
766 field.in_handler_priv = NULL;
767
768 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
769
770 /* small delay before polling */
771 jtag_add_sleep(50);
772
773 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
774
775 do {
776 field.device = chain_pos;
777 field.num_bits = 8;
778 field.out_value = NULL;
779 field.out_mask = NULL;
780 field.in_value = scanbuf;
781 field.in_check_value = NULL;
782 field.in_check_mask = NULL;
783 field.in_handler = NULL;
784 field.in_handler_priv = NULL;
785
786 jtag_add_dr_scan(1, &field, -1, NULL);
787 jtag_execute_queue();
788
789 status = buf_get_u32(scanbuf, 0, 8);
790
791 } while(!(status & ISC_STATUS_BUSY));
792
793 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
794 return ERROR_FLASH_OPERATION_FAILED;
795
796 //if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
797 // return ERROR_FLASH_OPERATION_FAILED;
798
799 dwords_remaining--;
800 bytes_written += 8;
801 }
802 }
803
804 if (bytes_remaining)
805 {
806 u8 last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
807 int i = 0;
808
809 while(bytes_remaining > 0)
810 {
811 last_dword[i++] = *(buffer + bytes_written);
812 bytes_remaining--;
813 bytes_written++;
814 }
815
816 str9xpec_set_instr(chain_pos, ISC_PROGRAM, TAP_PI);
817
818 field.device = chain_pos;
819 field.num_bits = 64;
820 field.out_value = last_dword;
821 field.out_mask = NULL;
822 field.in_value = NULL;
823 field.in_check_value = NULL;
824 field.in_check_mask = NULL;
825 field.in_handler = NULL;
826 field.in_handler_priv = NULL;
827
828 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
829
830 /* small delay before polling */
831 jtag_add_sleep(50);
832
833 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
834
835 do {
836 field.device = chain_pos;
837 field.num_bits = 8;
838 field.out_value = NULL;
839 field.out_mask = NULL;
840 field.in_value = scanbuf;
841 field.in_check_value = NULL;
842 field.in_check_mask = NULL;
843 field.in_handler = NULL;
844 field.in_handler_priv = NULL;
845
846 jtag_add_dr_scan(1, &field, -1, NULL);
847 jtag_execute_queue();
848
849 status = buf_get_u32(scanbuf, 0, 8);
850
851 } while(!(status & ISC_STATUS_BUSY));
852
853 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
854 return ERROR_FLASH_OPERATION_FAILED;
855
856 //if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
857 // return ERROR_FLASH_OPERATION_FAILED;
858 }
859
860 free(scanbuf);
861
862 str9xpec_isc_disable(bank);
863
864 return ERROR_OK;
865 }
866
867 int str9xpec_probe(struct flash_bank_s *bank)
868 {
869 return ERROR_OK;
870 }
871
872 int str9xpec_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
873 {
874 flash_bank_t *bank;
875 scan_field_t field;
876 u8 *buffer = NULL;
877 u32 chain_pos;
878 u32 idcode;
879 str9xpec_flash_controller_t *str9xpec_info = NULL;
880
881 if (argc < 1)
882 {
883 command_print(cmd_ctx, "usage: str9xpec part_id <num>");
884 return ERROR_OK;
885 }
886
887 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
888 if (!bank)
889 {
890 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
891 return ERROR_OK;
892 }
893
894 str9xpec_info = bank->driver_priv;
895 chain_pos = str9xpec_info->chain_pos;
896
897 buffer = calloc(CEIL(32, 8), 1);
898
899 str9xpec_set_instr(chain_pos, ISC_IDCODE, TAP_PI);
900
901 field.device = chain_pos;
902 field.num_bits = 32;
903 field.out_value = NULL;
904 field.out_mask = NULL;
905 field.in_value = buffer;
906 field.in_check_value = NULL;
907 field.in_check_mask = NULL;
908 field.in_handler = NULL;
909 field.in_handler_priv = NULL;
910
911 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
912 jtag_execute_queue();
913
914 idcode = buf_get_u32(buffer, 0, 32);
915
916 command_print(cmd_ctx, "str9xpec part id: 0x%8.8x", idcode);
917
918 free(buffer);
919
920 return ERROR_OK;
921 }
922
923 int str9xpec_erase_check(struct flash_bank_s *bank)
924 {
925 return str9xpec_blank_check(bank, 0, bank->num_sectors - 1);
926 }
927
928 int str9xpec_info(struct flash_bank_s *bank, char *buf, int buf_size)
929 {
930 snprintf(buf, buf_size, "str9xpec flash driver info" );
931 return ERROR_OK;
932 }
933
934 int str9xpec_handle_flash_options_read_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
935 {
936 flash_bank_t *bank;
937 u8 status;
938 str9xpec_flash_controller_t *str9xpec_info = NULL;
939
940 if (argc < 1)
941 {
942 command_print(cmd_ctx, "str9xpec options_read <bank>");
943 return ERROR_OK;
944 }
945
946 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
947 if (!bank)
948 {
949 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
950 return ERROR_OK;
951 }
952
953 str9xpec_info = bank->driver_priv;
954
955 status = str9xpec_read_config(bank);
956
957 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
958 return ERROR_FLASH_OPERATION_FAILED;
959
960 /* boot bank */
961 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1))
962 command_print(cmd_ctx, "CS Map: bank1");
963 else
964 command_print(cmd_ctx, "CS Map: bank0");
965
966 /* OTP lock */
967 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1))
968 command_print(cmd_ctx, "OTP Lock: OTP Locked");
969 else
970 command_print(cmd_ctx, "OTP Lock: OTP Unlocked");
971
972 /* LVD Threshold */
973 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1))
974 command_print(cmd_ctx, "LVD Threshold: 2.7v");
975 else
976 command_print(cmd_ctx, "LVD Threshold: 2.4v");
977
978 /* LVD reset warning */
979 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1))
980 command_print(cmd_ctx, "LVD Reset Warning: VDD or VDDQ Inputs");
981 else
982 command_print(cmd_ctx, "LVD Reset Warning: VDD Input Only");
983
984 /* LVD reset select */
985 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1))
986 command_print(cmd_ctx, "LVD Reset Selection: VDD or VDDQ Inputs");
987 else
988 command_print(cmd_ctx, "LVD Reset Selection: VDD Input Only");
989
990 return ERROR_OK;
991 }
992
993 int str9xpec_write_options(struct flash_bank_s *bank)
994 {
995 scan_field_t field;
996 u8 status;
997 u32 chain_pos;
998 str9xpec_flash_controller_t *str9xpec_info = NULL;
999
1000 str9xpec_info = bank->driver_priv;
1001 chain_pos = str9xpec_info->chain_pos;
1002
1003 /* erase config options first */
1004 str9xpec_erase_area( bank, 0xFE, 0xFE );
1005
1006 if (!str9xpec_info->isc_enable) {
1007 str9xpec_isc_enable( bank );
1008 }
1009
1010 if (!str9xpec_info->isc_enable) {
1011 return ISC_STATUS_ERROR;
1012 }
1013
1014 /* according to data 64th bit has to be set */
1015 buf_set_u32(str9xpec_info->options, 63, 1, 1);
1016
1017 /* set option byte address */
1018 str9xpec_set_address(bank, 0x50);
1019
1020 /* execute ISC_PROGRAM command */
1021 str9xpec_set_instr(chain_pos, ISC_PROGRAM, TAP_PI);
1022
1023 field.device = chain_pos;
1024 field.num_bits = 64;
1025 field.out_value = str9xpec_info->options;
1026 field.out_mask = NULL;
1027 field.in_value = NULL;
1028 field.in_check_value = NULL;
1029 field.in_check_mask = NULL;
1030 field.in_handler = NULL;
1031 field.in_handler_priv = NULL;
1032
1033 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
1034
1035 /* small delay before polling */
1036 jtag_add_sleep(50);
1037
1038 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
1039
1040 do {
1041 field.device = chain_pos;
1042 field.num_bits = 8;
1043 field.out_value = NULL;
1044 field.out_mask = NULL;
1045 field.in_value = &status;
1046 field.in_check_value = NULL;
1047 field.in_check_mask = NULL;
1048 field.in_handler = NULL;
1049 field.in_handler_priv = NULL;
1050
1051 jtag_add_dr_scan(1, &field, -1, NULL);
1052 jtag_execute_queue();
1053
1054 } while(!(status & ISC_STATUS_BUSY));
1055
1056 str9xpec_isc_disable(bank);
1057
1058 return status;
1059 }
1060
1061 int str9xpec_handle_flash_options_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1062 {
1063 flash_bank_t *bank;
1064 u8 status;
1065
1066 if (argc < 1)
1067 {
1068 command_print(cmd_ctx, "str9xpec options_write <bank>");
1069 return ERROR_OK;
1070 }
1071
1072 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1073 if (!bank)
1074 {
1075 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1076 return ERROR_OK;
1077 }
1078
1079 status = str9xpec_write_options(bank);
1080
1081 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1082 return ERROR_FLASH_OPERATION_FAILED;
1083
1084 return ERROR_OK;
1085 }
1086
1087 int str9xpec_handle_flash_options_cmap_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1088 {
1089 flash_bank_t *bank;
1090 str9xpec_flash_controller_t *str9xpec_info = NULL;
1091
1092 if (argc < 2)
1093 {
1094 command_print(cmd_ctx, "str9xpec options_cmap <bank> <bank0|bank1>");
1095 return ERROR_OK;
1096 }
1097
1098 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1099 if (!bank)
1100 {
1101 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1102 return ERROR_OK;
1103 }
1104
1105 str9xpec_info = bank->driver_priv;
1106
1107 if (strcmp(args[1], "bank1") == 0)
1108 {
1109 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 1);
1110 }
1111 else
1112 {
1113 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0);
1114 }
1115
1116 return ERROR_OK;
1117 }
1118
1119 int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1120 {
1121 flash_bank_t *bank;
1122 str9xpec_flash_controller_t *str9xpec_info = NULL;
1123
1124 if (argc < 2)
1125 {
1126 command_print(cmd_ctx, "str9xpec options_lvdthd <bank> <2.4v|2.7v>");
1127 return ERROR_OK;
1128 }
1129
1130 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1131 if (!bank)
1132 {
1133 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1134 return ERROR_OK;
1135 }
1136
1137 str9xpec_info = bank->driver_priv;
1138
1139 if (strcmp(args[1], "2.7v") == 0)
1140 {
1141 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 1);
1142 }
1143 else
1144 {
1145 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0);
1146 }
1147
1148 return ERROR_OK;
1149 }
1150
1151 int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1152 {
1153 flash_bank_t *bank;
1154 str9xpec_flash_controller_t *str9xpec_info = NULL;
1155
1156 if (argc < 2)
1157 {
1158 command_print(cmd_ctx, "str9xpec options_lvdsel <bank> <vdd|vdd_vddq>");
1159 return ERROR_OK;
1160 }
1161
1162 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1163 if (!bank)
1164 {
1165 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1166 return ERROR_OK;
1167 }
1168
1169 str9xpec_info = bank->driver_priv;
1170
1171 if (strcmp(args[1], "vdd_vddq") == 0)
1172 {
1173 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 1);
1174 }
1175 else
1176 {
1177 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0);
1178 }
1179
1180 return ERROR_OK;
1181 }
1182
1183 int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1184 {
1185 flash_bank_t *bank;
1186 str9xpec_flash_controller_t *str9xpec_info = NULL;
1187
1188 if (argc < 2)
1189 {
1190 command_print(cmd_ctx, "str9xpec options_lvdwarn <bank> <vdd|vdd_vddq>");
1191 return ERROR_OK;
1192 }
1193
1194 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1195 if (!bank)
1196 {
1197 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1198 return ERROR_OK;
1199 }
1200
1201 str9xpec_info = bank->driver_priv;
1202
1203 if (strcmp(args[1], "vdd_vddq") == 0)
1204 {
1205 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 1);
1206 }
1207 else
1208 {
1209 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0);
1210 }
1211
1212 return ERROR_OK;
1213 }
1214
1215 int str9xpec_handle_flash_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1216 {
1217 u8 status;
1218 flash_bank_t *bank;
1219
1220 if (argc < 1)
1221 {
1222 command_print(cmd_ctx, "str9xpec lock <bank>");
1223 return ERROR_OK;
1224 }
1225
1226 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1227 if (!bank)
1228 {
1229 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1230 return ERROR_OK;
1231 }
1232
1233 status = str9xpec_lock_device(bank);
1234
1235 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1236 return ERROR_FLASH_OPERATION_FAILED;
1237
1238 return ERROR_OK;
1239 }
1240
1241 int str9xpec_handle_flash_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1242 {
1243 u8 status;
1244 flash_bank_t *bank;
1245
1246 if (argc < 1)
1247 {
1248 command_print(cmd_ctx, "str9xpec unlock <bank>");
1249 return ERROR_OK;
1250 }
1251
1252 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1253 if (!bank)
1254 {
1255 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1256 return ERROR_OK;
1257 }
1258
1259 status = str9xpec_unlock_device(bank);
1260
1261 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1262 return ERROR_FLASH_OPERATION_FAILED;
1263
1264 return ERROR_OK;
1265 }
1266
1267 int str9xpec_handle_flash_enable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1268 {
1269 flash_bank_t *bank;
1270 u32 chain_pos;
1271 jtag_device_t* dev0;
1272 jtag_device_t* dev2;
1273 str9xpec_flash_controller_t *str9xpec_info = NULL;
1274
1275 if (argc < 1)
1276 {
1277 command_print(cmd_ctx, "str9xpec enable_turbo <bank>");
1278 return ERROR_OK;
1279 }
1280
1281 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1282 if (!bank)
1283 {
1284 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1285 return ERROR_OK;
1286 }
1287
1288 str9xpec_info = bank->driver_priv;
1289
1290 chain_pos = str9xpec_info->chain_pos;
1291
1292 /* remove arm core from chain - enter turbo mode */
1293
1294 str9xpec_set_instr(chain_pos+2, 0xD, TAP_RTI);
1295 jtag_execute_queue();
1296
1297 /* modify scan chain - str9 core has been removed */
1298 dev0 = jtag_get_device(chain_pos);
1299 str9xpec_info->devarm = jtag_get_device(chain_pos+1);
1300 dev2 = jtag_get_device(chain_pos+2);
1301 dev0->next = dev2;
1302 jtag_num_devices--;
1303
1304 return ERROR_OK;
1305 }
1306
1307 int str9xpec_handle_flash_disable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1308 {
1309 flash_bank_t *bank;
1310 u32 chain_pos;
1311 jtag_device_t* dev0;
1312 str9xpec_flash_controller_t *str9xpec_info = NULL;
1313
1314 if (argc < 1)
1315 {
1316 command_print(cmd_ctx, "str9xpec disable_turbo <bank>");
1317 return ERROR_OK;
1318 }
1319
1320 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1321 if (!bank)
1322 {
1323 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1324 return ERROR_OK;
1325 }
1326
1327 str9xpec_info = bank->driver_priv;
1328
1329 chain_pos = str9xpec_info->chain_pos;
1330
1331 dev0 = jtag_get_device(chain_pos);
1332
1333 /* exit turbo mode via TLR */
1334 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_TLR);
1335 jtag_execute_queue();
1336
1337 /* restore previous scan chain */
1338 if( str9xpec_info->devarm ) {
1339 dev0->next = str9xpec_info->devarm;
1340 jtag_num_devices++;
1341 str9xpec_info->devarm = NULL;
1342 }
1343
1344 return ERROR_OK;
1345 }

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)