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

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)