jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / src / flash / nor / tms470.c
1 /***************************************************************************
2 * Copyright (C) 2007,2008 by Christopher Kilgour *
3 * techie |_at_| whiterocker |_dot_| com *
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, see <http://www.gnu.org/licenses/>. *
17 ***************************************************************************/
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include "imp.h"
24
25 /* ----------------------------------------------------------------------
26 * Internal Support, Helpers
27 * ---------------------------------------------------------------------- */
28
29 struct tms470_flash_bank {
30 unsigned ordinal;
31
32 /* device identification register */
33 uint32_t device_ident_reg;
34 uint32_t silicon_version;
35 uint32_t technology_family;
36 uint32_t rom_flash;
37 uint32_t part_number;
38 const char *part_name;
39
40 };
41
42 static const struct flash_sector tms470r1a256_sectors[] = {
43 {0x00000000, 0x00002000, -1, -1},
44 {0x00002000, 0x00002000, -1, -1},
45 {0x00004000, 0x00002000, -1, -1},
46 {0x00006000, 0x00002000, -1, -1},
47 {0x00008000, 0x00008000, -1, -1},
48 {0x00010000, 0x00008000, -1, -1},
49 {0x00018000, 0x00008000, -1, -1},
50 {0x00020000, 0x00008000, -1, -1},
51 {0x00028000, 0x00008000, -1, -1},
52 {0x00030000, 0x00008000, -1, -1},
53 {0x00038000, 0x00002000, -1, -1},
54 {0x0003A000, 0x00002000, -1, -1},
55 {0x0003C000, 0x00002000, -1, -1},
56 {0x0003E000, 0x00002000, -1, -1},
57 };
58
59 #define TMS470R1A256_NUM_SECTORS \
60 ARRAY_SIZE(tms470r1a256_sectors)
61
62 static const struct flash_sector tms470r1a288_bank0_sectors[] = {
63 {0x00000000, 0x00002000, -1, -1},
64 {0x00002000, 0x00002000, -1, -1},
65 {0x00004000, 0x00002000, -1, -1},
66 {0x00006000, 0x00002000, -1, -1},
67 };
68
69 #define TMS470R1A288_BANK0_NUM_SECTORS \
70 ARRAY_SIZE(tms470r1a288_bank0_sectors)
71
72 static const struct flash_sector tms470r1a288_bank1_sectors[] = {
73 {0x00040000, 0x00010000, -1, -1},
74 {0x00050000, 0x00010000, -1, -1},
75 {0x00060000, 0x00010000, -1, -1},
76 {0x00070000, 0x00010000, -1, -1},
77 };
78
79 #define TMS470R1A288_BANK1_NUM_SECTORS \
80 ARRAY_SIZE(tms470r1a288_bank1_sectors)
81
82 static const struct flash_sector tms470r1a384_bank0_sectors[] = {
83 {0x00000000, 0x00002000, -1, -1},
84 {0x00002000, 0x00002000, -1, -1},
85 {0x00004000, 0x00004000, -1, -1},
86 {0x00008000, 0x00004000, -1, -1},
87 {0x0000C000, 0x00004000, -1, -1},
88 {0x00010000, 0x00004000, -1, -1},
89 {0x00014000, 0x00004000, -1, -1},
90 {0x00018000, 0x00002000, -1, -1},
91 {0x0001C000, 0x00002000, -1, -1},
92 {0x0001E000, 0x00002000, -1, -1},
93 };
94
95 #define TMS470R1A384_BANK0_NUM_SECTORS \
96 ARRAY_SIZE(tms470r1a384_bank0_sectors)
97
98 static const struct flash_sector tms470r1a384_bank1_sectors[] = {
99 {0x00020000, 0x00008000, -1, -1},
100 {0x00028000, 0x00008000, -1, -1},
101 {0x00030000, 0x00008000, -1, -1},
102 {0x00038000, 0x00008000, -1, -1},
103 };
104
105 #define TMS470R1A384_BANK1_NUM_SECTORS \
106 ARRAY_SIZE(tms470r1a384_bank1_sectors)
107
108 static const struct flash_sector tms470r1a384_bank2_sectors[] = {
109 {0x00040000, 0x00008000, -1, -1},
110 {0x00048000, 0x00008000, -1, -1},
111 {0x00050000, 0x00008000, -1, -1},
112 {0x00058000, 0x00008000, -1, -1},
113 };
114
115 #define TMS470R1A384_BANK2_NUM_SECTORS \
116 ARRAY_SIZE(tms470r1a384_bank2_sectors)
117
118 /* ---------------------------------------------------------------------- */
119
120 static int tms470_read_part_info(struct flash_bank *bank)
121 {
122 struct tms470_flash_bank *tms470_info = bank->driver_priv;
123 struct target *target = bank->target;
124 uint32_t device_ident_reg;
125 uint32_t silicon_version;
126 uint32_t technology_family;
127 uint32_t rom_flash;
128 uint32_t part_number;
129 const char *part_name;
130
131 /* we shall not rely on the caller in this test, this function allocates memory,
132 thus and executing the code more than once may cause memory leak */
133 if (tms470_info->device_ident_reg)
134 return ERROR_OK;
135
136 /* read and parse the device identification register */
137 target_read_u32(target, 0xFFFFFFF0, &device_ident_reg);
138
139 LOG_INFO("device_ident_reg = 0x%08" PRIx32 "", device_ident_reg);
140
141 if ((device_ident_reg & 7) == 0) {
142 LOG_WARNING("Cannot identify target as a TMS470 family.");
143 return ERROR_FLASH_OPERATION_FAILED;
144 }
145
146 silicon_version = (device_ident_reg >> 12) & 0xF;
147 technology_family = (device_ident_reg >> 11) & 1;
148 rom_flash = (device_ident_reg >> 10) & 1;
149 part_number = (device_ident_reg >> 3) & 0x7f;
150
151 free(bank->sectors);
152 bank->sectors = NULL;
153 bank->num_sectors = 0;
154
155 /*
156 * If the part number is known, determine if the flash bank is valid
157 * based on the base address being within the known flash bank
158 * ranges. Then fixup/complete the remaining fields of the flash
159 * bank structure.
160 */
161 switch (part_number) {
162 case 0x0a:
163 part_name = "TMS470R1A256";
164
165 if (bank->base >= 0x00040000) {
166 LOG_ERROR("No %s flash bank contains base address "
167 TARGET_ADDR_FMT ".",
168 part_name,
169 bank->base);
170 return ERROR_FLASH_OPERATION_FAILED;
171 }
172 tms470_info->ordinal = 0;
173 bank->base = 0x00000000;
174 bank->size = 256 * 1024;
175 bank->num_sectors = TMS470R1A256_NUM_SECTORS;
176 bank->sectors = malloc(sizeof(tms470r1a256_sectors));
177 if (!bank->sectors)
178 return ERROR_FLASH_OPERATION_FAILED;
179 (void)memcpy(bank->sectors, tms470r1a256_sectors, sizeof(tms470r1a256_sectors));
180 break;
181
182 case 0x2b:
183 part_name = "TMS470R1A288";
184
185 if (bank->base < 0x00008000) {
186 tms470_info->ordinal = 0;
187 bank->base = 0x00000000;
188 bank->size = 32 * 1024;
189 bank->num_sectors = TMS470R1A288_BANK0_NUM_SECTORS;
190 bank->sectors = malloc(sizeof(tms470r1a288_bank0_sectors));
191 if (!bank->sectors)
192 return ERROR_FLASH_OPERATION_FAILED;
193 (void)memcpy(bank->sectors, tms470r1a288_bank0_sectors,
194 sizeof(tms470r1a288_bank0_sectors));
195 } else if ((bank->base >= 0x00040000) && (bank->base < 0x00080000)) {
196 tms470_info->ordinal = 1;
197 bank->base = 0x00040000;
198 bank->size = 256 * 1024;
199 bank->num_sectors = TMS470R1A288_BANK1_NUM_SECTORS;
200 bank->sectors = malloc(sizeof(tms470r1a288_bank1_sectors));
201 if (!bank->sectors)
202 return ERROR_FLASH_OPERATION_FAILED;
203 (void)memcpy(bank->sectors, tms470r1a288_bank1_sectors,
204 sizeof(tms470r1a288_bank1_sectors));
205 } else {
206 LOG_ERROR("No %s flash bank contains base address " TARGET_ADDR_FMT ".",
207 part_name, bank->base);
208 return ERROR_FLASH_OPERATION_FAILED;
209 }
210 break;
211
212 case 0x2d:
213 part_name = "TMS470R1A384";
214
215 if (bank->base < 0x00020000) {
216 tms470_info->ordinal = 0;
217 bank->base = 0x00000000;
218 bank->size = 128 * 1024;
219 bank->num_sectors = TMS470R1A384_BANK0_NUM_SECTORS;
220 bank->sectors = malloc(sizeof(tms470r1a384_bank0_sectors));
221 if (!bank->sectors)
222 return ERROR_FLASH_OPERATION_FAILED;
223 (void)memcpy(bank->sectors, tms470r1a384_bank0_sectors,
224 sizeof(tms470r1a384_bank0_sectors));
225 } else if ((bank->base >= 0x00020000) && (bank->base < 0x00040000)) {
226 tms470_info->ordinal = 1;
227 bank->base = 0x00020000;
228 bank->size = 128 * 1024;
229 bank->num_sectors = TMS470R1A384_BANK1_NUM_SECTORS;
230 bank->sectors = malloc(sizeof(tms470r1a384_bank1_sectors));
231 if (!bank->sectors)
232 return ERROR_FLASH_OPERATION_FAILED;
233 (void)memcpy(bank->sectors, tms470r1a384_bank1_sectors,
234 sizeof(tms470r1a384_bank1_sectors));
235 } else if ((bank->base >= 0x00040000) && (bank->base < 0x00060000)) {
236 tms470_info->ordinal = 2;
237 bank->base = 0x00040000;
238 bank->size = 128 * 1024;
239 bank->num_sectors = TMS470R1A384_BANK2_NUM_SECTORS;
240 bank->sectors = malloc(sizeof(tms470r1a384_bank2_sectors));
241 if (!bank->sectors)
242 return ERROR_FLASH_OPERATION_FAILED;
243 (void)memcpy(bank->sectors, tms470r1a384_bank2_sectors,
244 sizeof(tms470r1a384_bank2_sectors));
245 } else {
246 LOG_ERROR("No %s flash bank contains base address " TARGET_ADDR_FMT ".",
247 part_name, bank->base);
248 return ERROR_FLASH_OPERATION_FAILED;
249 }
250 break;
251
252 default:
253 LOG_WARNING("Could not identify part 0x%02x as a member of the TMS470 family.",
254 (unsigned)part_number);
255 return ERROR_FLASH_OPERATION_FAILED;
256 }
257
258 /* turn off memory selects */
259 target_write_u32(target, 0xFFFFFFE4, 0x00000000);
260 target_write_u32(target, 0xFFFFFFE0, 0x00000000);
261
262 bank->chip_width = 32;
263 bank->bus_width = 32;
264
265 LOG_INFO("Identified %s, ver=%d, core=%s, nvmem=%s.",
266 part_name,
267 (int)(silicon_version),
268 (technology_family ? "1.8v" : "3.3v"),
269 (rom_flash ? "rom" : "flash"));
270
271 tms470_info->device_ident_reg = device_ident_reg;
272 tms470_info->silicon_version = silicon_version;
273 tms470_info->technology_family = technology_family;
274 tms470_info->rom_flash = rom_flash;
275 tms470_info->part_number = part_number;
276 tms470_info->part_name = part_name;
277
278 /*
279 * Disable reset on address access violation.
280 */
281 target_write_u32(target, 0xFFFFFFE0, 0x00004007);
282
283 return ERROR_OK;
284 }
285
286 /* ---------------------------------------------------------------------- */
287
288 static uint32_t keys_set;
289 static uint32_t flash_keys[4];
290
291 COMMAND_HANDLER(tms470_handle_flash_keyset_command)
292 {
293 if (CMD_ARGC > 4)
294 return ERROR_COMMAND_SYNTAX_ERROR;
295 else if (CMD_ARGC == 4) {
296 int i;
297
298 for (i = 0; i < 4; i++) {
299 int start = (strncmp(CMD_ARGV[i], "0x", 2) == 0) ? 2 : 0;
300
301 if (sscanf(&CMD_ARGV[i][start], "%" SCNx32 "", &flash_keys[i]) != 1) {
302 command_print(CMD, "could not process flash key %s",
303 CMD_ARGV[i]);
304 LOG_ERROR("could not process flash key %s", CMD_ARGV[i]);
305 return ERROR_COMMAND_SYNTAX_ERROR;
306 }
307 }
308
309 keys_set = 1;
310 } else if (CMD_ARGC != 0) {
311 command_print(CMD, "tms470 flash_keyset <key0> <key1> <key2> <key3>");
312 return ERROR_COMMAND_SYNTAX_ERROR;
313 }
314
315 if (keys_set) {
316 command_print(CMD,
317 "using flash keys 0x%08" PRIx32 ", 0x%08" PRIx32 ", 0x%08" PRIx32 ", 0x%08" PRIx32 "",
318 flash_keys[0],
319 flash_keys[1],
320 flash_keys[2],
321 flash_keys[3]);
322 } else
323 command_print(CMD, "flash keys not set");
324
325 return ERROR_OK;
326 }
327
328 static const uint32_t flash_keys_all_ones[] = { 0xFFFFFFFF, 0xFFFFFFFF,
329 0xFFFFFFFF, 0xFFFFFFFF,};
330
331 static const uint32_t flash_keys_all_zeros[] = { 0x00000000, 0x00000000,
332 0x00000000, 0x00000000,};
333
334 static const uint32_t flash_keys_mix1[] = { 0xf0fff0ff, 0xf0fff0ff,
335 0xf0fff0ff, 0xf0fff0ff};
336
337 static const uint32_t flash_keys_mix2[] = { 0x0000ffff, 0x0000ffff,
338 0x0000ffff, 0x0000ffff};
339
340 /* ---------------------------------------------------------------------- */
341
342 static int osc_mhz = 12;
343
344 COMMAND_HANDLER(tms470_handle_osc_megahertz_command)
345 {
346 if (CMD_ARGC > 1)
347 return ERROR_COMMAND_SYNTAX_ERROR;
348 else if (CMD_ARGC == 1)
349 sscanf(CMD_ARGV[0], "%d", &osc_mhz);
350
351 if (osc_mhz <= 0) {
352 LOG_ERROR("osc_megahertz must be positive and non-zero!");
353 command_print(CMD, "osc_megahertz must be positive and non-zero!");
354 osc_mhz = 12;
355 return ERROR_COMMAND_SYNTAX_ERROR;
356 }
357
358 command_print(CMD, "osc_megahertz=%d", osc_mhz);
359
360 return ERROR_OK;
361 }
362
363 /* ---------------------------------------------------------------------- */
364
365 static int plldis;
366
367 COMMAND_HANDLER(tms470_handle_plldis_command)
368 {
369 if (CMD_ARGC > 1)
370 return ERROR_COMMAND_SYNTAX_ERROR;
371 else if (CMD_ARGC == 1) {
372 sscanf(CMD_ARGV[0], "%d", &plldis);
373 plldis = plldis ? 1 : 0;
374 }
375
376 command_print(CMD, "plldis=%d", plldis);
377
378 return ERROR_OK;
379 }
380
381 /* ---------------------------------------------------------------------- */
382
383 static int tms470_check_flash_unlocked(struct target *target)
384 {
385 uint32_t fmbbusy;
386
387 target_read_u32(target, 0xFFE89C08, &fmbbusy);
388 LOG_INFO("tms470 fmbbusy = 0x%08" PRIx32 " -> %s",
389 fmbbusy,
390 fmbbusy & 0x8000 ? "unlocked" : "LOCKED");
391 return fmbbusy & 0x8000 ? ERROR_OK : ERROR_FLASH_OPERATION_FAILED;
392 }
393
394 /* ---------------------------------------------------------------------- */
395
396 static int tms470_try_flash_keys(struct target *target, const uint32_t *key_set)
397 {
398 uint32_t glbctrl, fmmstat;
399 int retval = ERROR_FLASH_OPERATION_FAILED;
400
401 /* set GLBCTRL.4 */
402 target_read_u32(target, 0xFFFFFFDC, &glbctrl);
403 target_write_u32(target, 0xFFFFFFDC, glbctrl | 0x10);
404
405 /* only perform the key match when 3VSTAT is clear */
406 target_read_u32(target, 0xFFE8BC0C, &fmmstat);
407 if (!(fmmstat & 0x08)) {
408 unsigned i;
409 uint32_t fmbptr, fmbac2, orig_fmregopt;
410
411 target_write_u32(target, 0xFFE8BC04, fmmstat & ~0x07);
412
413 /* wait for pump ready */
414 do {
415 target_read_u32(target, 0xFFE8A814, &fmbptr);
416 alive_sleep(1);
417 } while (!(fmbptr & 0x0200));
418
419 /* force max wait states */
420 target_read_u32(target, 0xFFE88004, &fmbac2);
421 target_write_u32(target, 0xFFE88004, fmbac2 | 0xff);
422
423 /* save current access mode, force normal read mode */
424 target_read_u32(target, 0xFFE89C00, &orig_fmregopt);
425 target_write_u32(target, 0xFFE89C00, 0x00);
426
427 for (i = 0; i < 4; i++) {
428 uint32_t tmp;
429
430 /* There is no point displaying the value of tmp, it is
431 * filtered by the chip. The purpose of this read is to
432 * prime the unlocking logic rather than read out the value.
433 */
434 target_read_u32(target, 0x00001FF0 + 4 * i, &tmp);
435
436 LOG_INFO("tms470 writing fmpkey = 0x%08" PRIx32 "", key_set[i]);
437 target_write_u32(target, 0xFFE89C0C, key_set[i]);
438 }
439
440 if (tms470_check_flash_unlocked(target) == ERROR_OK) {
441 /*
442 * There seems to be a side-effect of reading the FMPKEY
443 * register in that it re-enables the protection. So we
444 * re-enable it.
445 */
446 for (i = 0; i < 4; i++) {
447 uint32_t tmp;
448
449 target_read_u32(target, 0x00001FF0 + 4 * i, &tmp);
450 target_write_u32(target, 0xFFE89C0C, key_set[i]);
451 }
452 retval = ERROR_OK;
453 }
454
455 /* restore settings */
456 target_write_u32(target, 0xFFE89C00, orig_fmregopt);
457 target_write_u32(target, 0xFFE88004, fmbac2);
458 }
459
460 /* clear config bit */
461 target_write_u32(target, 0xFFFFFFDC, glbctrl);
462
463 return retval;
464 }
465
466 /* ---------------------------------------------------------------------- */
467
468 static int tms470_unlock_flash(struct flash_bank *bank)
469 {
470 struct target *target = bank->target;
471 const uint32_t *p_key_sets[5];
472 unsigned i, key_set_count;
473
474 if (keys_set) {
475 key_set_count = 5;
476 p_key_sets[0] = flash_keys;
477 p_key_sets[1] = flash_keys_all_ones;
478 p_key_sets[2] = flash_keys_all_zeros;
479 p_key_sets[3] = flash_keys_mix1;
480 p_key_sets[4] = flash_keys_mix2;
481 } else {
482 key_set_count = 4;
483 p_key_sets[0] = flash_keys_all_ones;
484 p_key_sets[1] = flash_keys_all_zeros;
485 p_key_sets[2] = flash_keys_mix1;
486 p_key_sets[3] = flash_keys_mix2;
487 }
488
489 for (i = 0; i < key_set_count; i++) {
490 if (tms470_try_flash_keys(target, p_key_sets[i]) == ERROR_OK) {
491 LOG_INFO("tms470 flash is unlocked");
492 return ERROR_OK;
493 }
494 }
495
496 LOG_WARNING("tms470 could not unlock flash memory protection level 2");
497 return ERROR_FLASH_OPERATION_FAILED;
498 }
499
500 /* ---------------------------------------------------------------------- */
501
502 static int tms470_flash_initialize_internal_state_machine(struct flash_bank *bank)
503 {
504 uint32_t fmmac2, fmmac1, fmmaxep, k, delay, glbctrl, sysclk;
505 struct target *target = bank->target;
506 struct tms470_flash_bank *tms470_info = bank->driver_priv;
507 int result = ERROR_OK;
508
509 /*
510 * Select the desired bank to be programmed by writing BANK[2:0] of
511 * FMMAC2.
512 */
513 target_read_u32(target, 0xFFE8BC04, &fmmac2);
514 fmmac2 &= ~0x0007;
515 fmmac2 |= (tms470_info->ordinal & 7);
516 target_write_u32(target, 0xFFE8BC04, fmmac2);
517 LOG_DEBUG("set fmmac2 = 0x%04" PRIx32 "", fmmac2);
518
519 /*
520 * Disable level 1 sector protection by setting bit 15 of FMMAC1.
521 */
522 target_read_u32(target, 0xFFE8BC00, &fmmac1);
523 fmmac1 |= 0x8000;
524 target_write_u32(target, 0xFFE8BC00, fmmac1);
525 LOG_DEBUG("set fmmac1 = 0x%04" PRIx32 "", fmmac1);
526
527 /*
528 * FMTCREG = 0x2fc0;
529 */
530 target_write_u32(target, 0xFFE8BC10, 0x2fc0);
531 LOG_DEBUG("set fmtcreg = 0x2fc0");
532
533 /*
534 * MAXPP = 50
535 */
536 target_write_u32(target, 0xFFE8A07C, 50);
537 LOG_DEBUG("set fmmaxpp = 50");
538
539 /*
540 * MAXCP = 0xf000 + 2000
541 */
542 target_write_u32(target, 0xFFE8A084, 0xf000 + 2000);
543 LOG_DEBUG("set fmmaxcp = 0x%04x", 0xf000 + 2000);
544
545 /*
546 * configure VHV
547 */
548 target_read_u32(target, 0xFFE8A080, &fmmaxep);
549 if (fmmaxep == 0xf000) {
550 fmmaxep = 0xf000 + 4095;
551 target_write_u32(target, 0xFFE8A80C, 0x9964);
552 LOG_DEBUG("set fmptr3 = 0x9964");
553 } else {
554 fmmaxep = 0xa000 + 4095;
555 target_write_u32(target, 0xFFE8A80C, 0x9b64);
556 LOG_DEBUG("set fmptr3 = 0x9b64");
557 }
558 target_write_u32(target, 0xFFE8A080, fmmaxep);
559 LOG_DEBUG("set fmmaxep = 0x%04" PRIx32 "", fmmaxep);
560
561 /*
562 * FMPTR4 = 0xa000
563 */
564 target_write_u32(target, 0xFFE8A810, 0xa000);
565 LOG_DEBUG("set fmptr4 = 0xa000");
566
567 /*
568 * FMPESETUP, delay parameter selected based on clock frequency.
569 *
570 * According to the TI App Note SPNU257 and flashing code, delay is
571 * int((sysclk(MHz) + 1) / 2), with a minimum of 5. The system
572 * clock is usually derived from the ZPLL module, and selected by
573 * the plldis global.
574 */
575 target_read_u32(target, 0xFFFFFFDC, &glbctrl);
576 sysclk = (plldis ? 1 : (glbctrl & 0x08) ? 4 : 8) * osc_mhz / (1 + (glbctrl & 7));
577 delay = (sysclk > 10) ? (sysclk + 1) / 2 : 5;
578 target_write_u32(target, 0xFFE8A018, (delay << 4) | (delay << 8));
579 LOG_DEBUG("set fmpsetup = 0x%04" PRIx32 "", (delay << 4) | (delay << 8));
580
581 /*
582 * FMPVEVACCESS, based on delay.
583 */
584 k = delay | (delay << 8);
585 target_write_u32(target, 0xFFE8A05C, k);
586 LOG_DEBUG("set fmpvevaccess = 0x%04" PRIx32 "", k);
587
588 /*
589 * FMPCHOLD, FMPVEVHOLD, FMPVEVSETUP, based on delay.
590 */
591 k <<= 1;
592 target_write_u32(target, 0xFFE8A034, k);
593 LOG_DEBUG("set fmpchold = 0x%04" PRIx32 "", k);
594 target_write_u32(target, 0xFFE8A040, k);
595 LOG_DEBUG("set fmpvevhold = 0x%04" PRIx32 "", k);
596 target_write_u32(target, 0xFFE8A024, k);
597 LOG_DEBUG("set fmpvevsetup = 0x%04" PRIx32 "", k);
598
599 /*
600 * FMCVACCESS, based on delay.
601 */
602 k = delay * 16;
603 target_write_u32(target, 0xFFE8A060, k);
604 LOG_DEBUG("set fmcvaccess = 0x%04" PRIx32 "", k);
605
606 /*
607 * FMCSETUP, based on delay.
608 */
609 k = 0x3000 | delay * 20;
610 target_write_u32(target, 0xFFE8A020, k);
611 LOG_DEBUG("set fmcsetup = 0x%04" PRIx32 "", k);
612
613 /*
614 * FMEHOLD, based on delay.
615 */
616 k = (delay * 20) << 2;
617 target_write_u32(target, 0xFFE8A038, k);
618 LOG_DEBUG("set fmehold = 0x%04" PRIx32 "", k);
619
620 /*
621 * PWIDTH, CWIDTH, EWIDTH, based on delay.
622 */
623 target_write_u32(target, 0xFFE8A050, delay * 8);
624 LOG_DEBUG("set fmpwidth = 0x%04" PRIx32 "", delay * 8);
625 target_write_u32(target, 0xFFE8A058, delay * 1000);
626 LOG_DEBUG("set fmcwidth = 0x%04" PRIx32 "", delay * 1000);
627 target_write_u32(target, 0xFFE8A054, delay * 5400);
628 LOG_DEBUG("set fmewidth = 0x%04" PRIx32 "", delay * 5400);
629
630 return result;
631 }
632
633 /* ---------------------------------------------------------------------- */
634
635 static int tms470_flash_status(struct flash_bank *bank)
636 {
637 struct target *target = bank->target;
638 int result = ERROR_OK;
639 uint32_t fmmstat;
640
641 target_read_u32(target, 0xFFE8BC0C, &fmmstat);
642 LOG_DEBUG("set fmmstat = 0x%04" PRIx32 "", fmmstat);
643
644 if (fmmstat & 0x0080) {
645 LOG_WARNING("tms470 flash command: erase still active after busy clear.");
646 result = ERROR_FLASH_OPERATION_FAILED;
647 }
648
649 if (fmmstat & 0x0040) {
650 LOG_WARNING("tms470 flash command: program still active after busy clear.");
651 result = ERROR_FLASH_OPERATION_FAILED;
652 }
653
654 if (fmmstat & 0x0020) {
655 LOG_WARNING("tms470 flash command: invalid data command.");
656 result = ERROR_FLASH_OPERATION_FAILED;
657 }
658
659 if (fmmstat & 0x0010) {
660 LOG_WARNING("tms470 flash command: program, erase or validate sector failed.");
661 result = ERROR_FLASH_OPERATION_FAILED;
662 }
663
664 if (fmmstat & 0x0008) {
665 LOG_WARNING("tms470 flash command: voltage instability detected.");
666 result = ERROR_FLASH_OPERATION_FAILED;
667 }
668
669 if (fmmstat & 0x0006) {
670 LOG_WARNING("tms470 flash command: command suspend detected.");
671 result = ERROR_FLASH_OPERATION_FAILED;
672 }
673
674 if (fmmstat & 0x0001) {
675 LOG_WARNING("tms470 flash command: sector was locked.");
676 result = ERROR_FLASH_OPERATION_FAILED;
677 }
678
679 return result;
680 }
681
682 /* ---------------------------------------------------------------------- */
683
684 static int tms470_erase_sector(struct flash_bank *bank, int sector)
685 {
686 uint32_t glbctrl, orig_fmregopt, fmbsea, fmbseb, fmmstat;
687 struct target *target = bank->target;
688 uint32_t flash_addr = bank->base + bank->sectors[sector].offset;
689 int result = ERROR_OK;
690
691 /*
692 * Set the bit GLBCTRL4 of the GLBCTRL register (in the System
693 * module) to enable writing to the flash registers }.
694 */
695 target_read_u32(target, 0xFFFFFFDC, &glbctrl);
696 target_write_u32(target, 0xFFFFFFDC, glbctrl | 0x10);
697 LOG_DEBUG("set glbctrl = 0x%08" PRIx32 "", glbctrl | 0x10);
698
699 /* Force normal read mode. */
700 target_read_u32(target, 0xFFE89C00, &orig_fmregopt);
701 target_write_u32(target, 0xFFE89C00, 0);
702 LOG_DEBUG("set fmregopt = 0x%08x", 0);
703
704 (void)tms470_flash_initialize_internal_state_machine(bank);
705
706 /*
707 * Select one or more bits in FMBSEA or FMBSEB to disable Level 1
708 * protection for the particular sector to be erased/written.
709 */
710 assert(sector >= 0);
711 if (sector < 16) {
712 target_read_u32(target, 0xFFE88008, &fmbsea);
713 target_write_u32(target, 0xFFE88008, fmbsea | (1 << sector));
714 LOG_DEBUG("set fmbsea = 0x%04" PRIx32 "", fmbsea | (1 << sector));
715 } else {
716 target_read_u32(target, 0xFFE8800C, &fmbseb);
717 target_write_u32(target, 0xFFE8800C, fmbseb | (1 << (sector - 16)));
718 LOG_DEBUG("set fmbseb = 0x%04" PRIx32 "", fmbseb | (1 << (sector - 16)));
719 }
720 bank->sectors[sector].is_protected = 0;
721
722 /*
723 * clear status register, sent erase command, kickoff erase
724 */
725 target_write_u16(target, flash_addr, 0x0040);
726 LOG_DEBUG("write *(uint16_t *)0x%08" PRIx32 "=0x0040", flash_addr);
727 target_write_u16(target, flash_addr, 0x0020);
728 LOG_DEBUG("write *(uint16_t *)0x%08" PRIx32 "=0x0020", flash_addr);
729 target_write_u16(target, flash_addr, 0xffff);
730 LOG_DEBUG("write *(uint16_t *)0x%08" PRIx32 "=0xffff", flash_addr);
731
732 /*
733 * Monitor FMMSTAT, busy until clear, then check and other flags for
734 * ultimate result of the operation.
735 */
736 do {
737 target_read_u32(target, 0xFFE8BC0C, &fmmstat);
738 if (fmmstat & 0x0100)
739 alive_sleep(1);
740 } while (fmmstat & 0x0100);
741
742 result = tms470_flash_status(bank);
743
744 if (sector < 16) {
745 target_write_u32(target, 0xFFE88008, fmbsea);
746 LOG_DEBUG("set fmbsea = 0x%04" PRIx32 "", fmbsea);
747 bank->sectors[sector].is_protected = fmbsea & (1 << sector) ? 0 : 1;
748 } else {
749 target_write_u32(target, 0xFFE8800C, fmbseb);
750 LOG_DEBUG("set fmbseb = 0x%04" PRIx32 "", fmbseb);
751 bank->sectors[sector].is_protected = fmbseb & (1 << (sector - 16)) ? 0 : 1;
752 }
753 target_write_u32(target, 0xFFE89C00, orig_fmregopt);
754 LOG_DEBUG("set fmregopt = 0x%08" PRIx32 "", orig_fmregopt);
755 target_write_u32(target, 0xFFFFFFDC, glbctrl);
756 LOG_DEBUG("set glbctrl = 0x%08" PRIx32 "", glbctrl);
757
758 return result;
759 }
760
761 /*----------------------------------------------------------------------
762 * Implementation of Flash Driver Interfaces
763 *---------------------------------------------------------------------- */
764
765 static const struct command_registration tms470_any_command_handlers[] = {
766 {
767 .name = "flash_keyset",
768 .usage = "<key0> <key1> <key2> <key3>",
769 .handler = tms470_handle_flash_keyset_command,
770 .mode = COMMAND_ANY,
771 .help = "tms470 flash_keyset <key0> <key1> <key2> <key3>",
772 },
773 {
774 .name = "osc_megahertz",
775 .usage = "<MHz>",
776 .handler = tms470_handle_osc_megahertz_command,
777 .mode = COMMAND_ANY,
778 .help = "tms470 osc_megahertz <MHz>",
779 },
780 {
781 .name = "plldis",
782 .usage = "<0 | 1>",
783 .handler = tms470_handle_plldis_command,
784 .mode = COMMAND_ANY,
785 .help = "tms470 plldis <0/1>",
786 },
787 COMMAND_REGISTRATION_DONE
788 };
789 static const struct command_registration tms470_command_handlers[] = {
790 {
791 .name = "tms470",
792 .mode = COMMAND_ANY,
793 .help = "TI tms470 flash command group",
794 .usage = "",
795 .chain = tms470_any_command_handlers,
796 },
797 COMMAND_REGISTRATION_DONE
798 };
799
800 /* ---------------------------------------------------------------------- */
801
802 static int tms470_erase(struct flash_bank *bank, unsigned int first,
803 unsigned int last)
804 {
805 struct tms470_flash_bank *tms470_info = bank->driver_priv;
806 int result = ERROR_OK;
807
808 if (bank->target->state != TARGET_HALTED) {
809 LOG_ERROR("Target not halted");
810 return ERROR_TARGET_NOT_HALTED;
811 }
812
813 tms470_read_part_info(bank);
814
815 if ((first >= bank->num_sectors) || (last >= bank->num_sectors) ||
816 (first > last)) {
817 LOG_ERROR("Sector range %u to %u invalid.", first, last);
818 return ERROR_FLASH_SECTOR_INVALID;
819 }
820
821 result = tms470_unlock_flash(bank);
822 if (result != ERROR_OK)
823 return result;
824
825 for (unsigned int sector = first; sector <= last; sector++) {
826 LOG_INFO("Erasing tms470 bank %u sector %u...", tms470_info->ordinal, sector);
827
828 result = tms470_erase_sector(bank, sector);
829
830 if (result != ERROR_OK) {
831 LOG_ERROR("tms470 could not erase flash sector.");
832 break;
833 } else
834 LOG_INFO("sector erased successfully.");
835 }
836
837 return result;
838 }
839
840 /* ---------------------------------------------------------------------- */
841
842 static int tms470_protect(struct flash_bank *bank, int set, unsigned int first,
843 unsigned int last)
844 {
845 struct tms470_flash_bank *tms470_info = bank->driver_priv;
846 struct target *target = bank->target;
847 uint32_t fmmac2, fmbsea, fmbseb;
848
849 if (target->state != TARGET_HALTED) {
850 LOG_ERROR("Target not halted");
851 return ERROR_TARGET_NOT_HALTED;
852 }
853
854 tms470_read_part_info(bank);
855
856 if ((first >= bank->num_sectors) || (last >= bank->num_sectors) ||
857 (first > last)) {
858 LOG_ERROR("Sector range %u to %u invalid.", first, last);
859 return ERROR_FLASH_SECTOR_INVALID;
860 }
861
862 /* enable the appropriate bank */
863 target_read_u32(target, 0xFFE8BC04, &fmmac2);
864 target_write_u32(target, 0xFFE8BC04, (fmmac2 & ~7) | tms470_info->ordinal);
865
866 /* get the original sector protection flags for this bank */
867 target_read_u32(target, 0xFFE88008, &fmbsea);
868 target_read_u32(target, 0xFFE8800C, &fmbseb);
869
870 for (unsigned int sector = 0; sector < bank->num_sectors; sector++) {
871 if (sector < 16) {
872 fmbsea = set ? fmbsea & ~(1 << sector) : fmbsea | (1 << sector);
873 bank->sectors[sector].is_protected = set ? 1 : 0;
874 } else {
875 fmbseb = set ? fmbseb &
876 ~(1 << (sector - 16)) : fmbseb | (1 << (sector - 16));
877 bank->sectors[sector].is_protected = set ? 1 : 0;
878 }
879 }
880
881 /* update the protection bits */
882 target_write_u32(target, 0xFFE88008, fmbsea);
883 target_write_u32(target, 0xFFE8800C, fmbseb);
884
885 return ERROR_OK;
886 }
887
888 /* ---------------------------------------------------------------------- */
889
890 static int tms470_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
891 {
892 struct target *target = bank->target;
893 uint32_t glbctrl, fmbac2, orig_fmregopt, fmbsea, fmbseb, fmmaxpp, fmmstat;
894 int result = ERROR_OK;
895 uint32_t i;
896
897 if (target->state != TARGET_HALTED) {
898 LOG_ERROR("Target not halted");
899 return ERROR_TARGET_NOT_HALTED;
900 }
901
902 tms470_read_part_info(bank);
903
904 LOG_INFO("Writing %" PRIu32 " bytes starting at " TARGET_ADDR_FMT,
905 count, bank->base + offset);
906
907 /* set GLBCTRL.4 */
908 target_read_u32(target, 0xFFFFFFDC, &glbctrl);
909 target_write_u32(target, 0xFFFFFFDC, glbctrl | 0x10);
910
911 (void)tms470_flash_initialize_internal_state_machine(bank);
912
913 /* force max wait states */
914 target_read_u32(target, 0xFFE88004, &fmbac2);
915 target_write_u32(target, 0xFFE88004, fmbac2 | 0xff);
916
917 /* save current access mode, force normal read mode */
918 target_read_u32(target, 0xFFE89C00, &orig_fmregopt);
919 target_write_u32(target, 0xFFE89C00, 0x00);
920
921 /*
922 * Disable Level 1 protection for all sectors to be erased/written.
923 */
924 target_read_u32(target, 0xFFE88008, &fmbsea);
925 target_write_u32(target, 0xFFE88008, 0xffff);
926 target_read_u32(target, 0xFFE8800C, &fmbseb);
927 target_write_u32(target, 0xFFE8800C, 0xffff);
928
929 /* read MAXPP */
930 target_read_u32(target, 0xFFE8A07C, &fmmaxpp);
931
932 for (i = 0; i < count; i += 2) {
933 uint32_t addr = bank->base + offset + i;
934 uint16_t word = (((uint16_t) buffer[i]) << 8) | (uint16_t) buffer[i + 1];
935
936 if (word != 0xffff) {
937 LOG_INFO("writing 0x%04x at 0x%08" PRIx32 "", word, addr);
938
939 /* clear status register */
940 target_write_u16(target, addr, 0x0040);
941 /* program flash command */
942 target_write_u16(target, addr, 0x0010);
943 /* burn the 16-bit word (big-endian) */
944 target_write_u16(target, addr, word);
945
946 /*
947 * Monitor FMMSTAT, busy until clear, then check and other flags
948 * for ultimate result of the operation.
949 */
950 do {
951 target_read_u32(target, 0xFFE8BC0C, &fmmstat);
952 if (fmmstat & 0x0100)
953 alive_sleep(1);
954 } while (fmmstat & 0x0100);
955
956 if (fmmstat & 0x3ff) {
957 LOG_ERROR("fmstat = 0x%04" PRIx32 "", fmmstat);
958 LOG_ERROR(
959 "Could not program word 0x%04x at address 0x%08" PRIx32 ".",
960 word,
961 addr);
962 result = ERROR_FLASH_OPERATION_FAILED;
963 break;
964 }
965 } else
966 LOG_INFO("skipping 0xffff at 0x%08" PRIx32 "", addr);
967 }
968
969 /* restore */
970 target_write_u32(target, 0xFFE88008, fmbsea);
971 target_write_u32(target, 0xFFE8800C, fmbseb);
972 target_write_u32(target, 0xFFE88004, fmbac2);
973 target_write_u32(target, 0xFFE89C00, orig_fmregopt);
974 target_write_u32(target, 0xFFFFFFDC, glbctrl);
975
976 return result;
977 }
978
979 /* ---------------------------------------------------------------------- */
980
981 static int tms470_probe(struct flash_bank *bank)
982 {
983 if (bank->target->state != TARGET_HALTED) {
984 LOG_WARNING("Cannot communicate... target not halted.");
985 return ERROR_TARGET_NOT_HALTED;
986 }
987
988 return tms470_read_part_info(bank);
989 }
990
991 static int tms470_auto_probe(struct flash_bank *bank)
992 {
993 struct tms470_flash_bank *tms470_info = bank->driver_priv;
994
995 if (tms470_info->device_ident_reg)
996 return ERROR_OK;
997 return tms470_probe(bank);
998 }
999
1000 /* ---------------------------------------------------------------------- */
1001
1002 static int tms470_erase_check(struct flash_bank *bank)
1003 {
1004 struct target *target = bank->target;
1005 struct tms470_flash_bank *tms470_info = bank->driver_priv;
1006 int result = ERROR_OK;
1007 uint32_t fmmac2, fmbac2, glbctrl, orig_fmregopt;
1008 static uint8_t buffer[64 * 1024];
1009
1010 if (target->state != TARGET_HALTED) {
1011 LOG_ERROR("Target not halted");
1012 return ERROR_TARGET_NOT_HALTED;
1013 }
1014
1015 if (!tms470_info->device_ident_reg)
1016 tms470_read_part_info(bank);
1017
1018 /* set GLBCTRL.4 */
1019 target_read_u32(target, 0xFFFFFFDC, &glbctrl);
1020 target_write_u32(target, 0xFFFFFFDC, glbctrl | 0x10);
1021
1022 /* save current access mode, force normal read mode */
1023 target_read_u32(target, 0xFFE89C00, &orig_fmregopt);
1024 target_write_u32(target, 0xFFE89C00, 0x00);
1025
1026 /* enable the appropriate bank */
1027 target_read_u32(target, 0xFFE8BC04, &fmmac2);
1028 target_write_u32(target, 0xFFE8BC04, (fmmac2 & ~7) | tms470_info->ordinal);
1029
1030 /* TCR = 0 */
1031 target_write_u32(target, 0xFFE8BC10, 0x2fc0);
1032
1033 /* clear TEZ in fmbrdy */
1034 target_write_u32(target, 0xFFE88010, 0x0b);
1035
1036 /* save current wait states, force max */
1037 target_read_u32(target, 0xFFE88004, &fmbac2);
1038 target_write_u32(target, 0xFFE88004, fmbac2 | 0xff);
1039
1040 /*
1041 * The TI primitives inspect the flash memory by reading one 32-bit
1042 * word at a time. Here we read an entire sector and inspect it in
1043 * an attempt to reduce the JTAG overhead.
1044 */
1045 for (unsigned int sector = 0; sector < bank->num_sectors; sector++) {
1046 uint32_t i, addr = bank->base + bank->sectors[sector].offset;
1047
1048 LOG_INFO("checking flash bank %u sector %u", tms470_info->ordinal, sector);
1049
1050 target_read_buffer(target, addr, bank->sectors[sector].size, buffer);
1051
1052 bank->sectors[sector].is_erased = 1;
1053 for (i = 0; i < bank->sectors[sector].size; i++) {
1054 if (buffer[i] != 0xff) {
1055 bank->sectors[sector].is_erased = 0;
1056 break;
1057 }
1058 }
1059 if (bank->sectors[sector].is_erased != 1) {
1060 result = ERROR_FLASH_SECTOR_NOT_ERASED;
1061 break;
1062 } else
1063 LOG_INFO("sector erased");
1064 }
1065
1066 /* reset TEZ, wait states, read mode, GLBCTRL.4 */
1067 target_write_u32(target, 0xFFE88010, 0x0f);
1068 target_write_u32(target, 0xFFE88004, fmbac2);
1069 target_write_u32(target, 0xFFE89C00, orig_fmregopt);
1070 target_write_u32(target, 0xFFFFFFDC, glbctrl);
1071
1072 return result;
1073 }
1074
1075 /* ---------------------------------------------------------------------- */
1076
1077 static int tms470_protect_check(struct flash_bank *bank)
1078 {
1079 struct target *target = bank->target;
1080 struct tms470_flash_bank *tms470_info = bank->driver_priv;
1081 int result = ERROR_OK;
1082 uint32_t fmmac2, fmbsea, fmbseb;
1083
1084 if (target->state != TARGET_HALTED) {
1085 LOG_ERROR("Target not halted");
1086 return ERROR_TARGET_NOT_HALTED;
1087 }
1088
1089 if (!tms470_info->device_ident_reg)
1090 tms470_read_part_info(bank);
1091
1092 /* enable the appropriate bank */
1093 target_read_u32(target, 0xFFE8BC04, &fmmac2);
1094 target_write_u32(target, 0xFFE8BC04, (fmmac2 & ~7) | tms470_info->ordinal);
1095
1096 target_read_u32(target, 0xFFE88008, &fmbsea);
1097 target_read_u32(target, 0xFFE8800C, &fmbseb);
1098
1099 for (unsigned int sector = 0; sector < bank->num_sectors; sector++) {
1100 int protected;
1101
1102 if (sector < 16) {
1103 protected = fmbsea & (1 << sector) ? 0 : 1;
1104 bank->sectors[sector].is_protected = protected;
1105 } else {
1106 protected = fmbseb & (1 << (sector - 16)) ? 0 : 1;
1107 bank->sectors[sector].is_protected = protected;
1108 }
1109
1110 LOG_DEBUG("bank %u sector %u is %s",
1111 tms470_info->ordinal,
1112 sector,
1113 protected ? "protected" : "not protected");
1114 }
1115
1116 return result;
1117 }
1118
1119 /* ---------------------------------------------------------------------- */
1120
1121 static int get_tms470_info(struct flash_bank *bank, struct command_invocation *cmd)
1122 {
1123 struct tms470_flash_bank *tms470_info = bank->driver_priv;
1124
1125 if (!tms470_info->device_ident_reg)
1126 tms470_read_part_info(bank);
1127
1128 if (!tms470_info->device_ident_reg) {
1129 command_print_sameline(cmd, "Cannot identify target as a TMS470\n");
1130 return ERROR_FLASH_OPERATION_FAILED;
1131 }
1132
1133 command_print_sameline(cmd, "\ntms470 information: Chip is %s\n", tms470_info->part_name);
1134 command_print_sameline(cmd, "Flash protection level 2 is %s\n",
1135 tms470_check_flash_unlocked(bank->target) == ERROR_OK ? "disabled" : "enabled");
1136
1137 return ERROR_OK;
1138 }
1139
1140 /* ---------------------------------------------------------------------- */
1141
1142 /*
1143 * flash bank tms470 <base> <size> <chip_width> <bus_width> <target>
1144 * [options...]
1145 */
1146
1147 FLASH_BANK_COMMAND_HANDLER(tms470_flash_bank_command)
1148 {
1149 bank->driver_priv = malloc(sizeof(struct tms470_flash_bank));
1150
1151 if (!bank->driver_priv)
1152 return ERROR_FLASH_OPERATION_FAILED;
1153
1154 (void)memset(bank->driver_priv, 0, sizeof(struct tms470_flash_bank));
1155
1156 return ERROR_OK;
1157 }
1158
1159 const struct flash_driver tms470_flash = {
1160 .name = "tms470",
1161 .commands = tms470_command_handlers,
1162 .flash_bank_command = tms470_flash_bank_command,
1163 .erase = tms470_erase,
1164 .protect = tms470_protect,
1165 .write = tms470_write,
1166 .read = default_flash_read,
1167 .probe = tms470_probe,
1168 .auto_probe = tms470_auto_probe,
1169 .erase_check = tms470_erase_check,
1170 .protect_check = tms470_protect_check,
1171 .info = get_tms470_info,
1172 .free_driver_priv = default_flash_free_driver_priv,
1173 };

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)