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

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)