b28aee434625ce86e692b18cf003a76cc6ef43ca
[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 .chain = tms470_any_command_handlers,
867 },
868 COMMAND_REGISTRATION_DONE
869 };
870
871 /* ---------------------------------------------------------------------- */
872
873 static int tms470_erase(struct flash_bank *bank, int first, int last)
874 {
875 struct tms470_flash_bank *tms470_info = bank->driver_priv;
876 int sector, result = ERROR_OK;
877
878 if (bank->target->state != TARGET_HALTED)
879 {
880 LOG_ERROR("Target not halted");
881 return ERROR_TARGET_NOT_HALTED;
882 }
883
884 tms470_read_part_info(bank);
885
886 if ((first < 0) || (first >= bank->num_sectors) || (last < 0) || (last >= bank->num_sectors) || (first > last))
887 {
888 LOG_ERROR("Sector range %d to %d invalid.", first, last);
889 return ERROR_FLASH_SECTOR_INVALID;
890 }
891
892 result = tms470_unlock_flash(bank);
893 if (result != ERROR_OK)
894 {
895 return result;
896 }
897
898 for (sector = first; sector <= last; sector++)
899 {
900 LOG_INFO("Erasing tms470 bank %d sector %d...", tms470_info->ordinal, sector);
901
902 result = tms470_erase_sector(bank, sector);
903
904 if (result != ERROR_OK)
905 {
906 LOG_ERROR("tms470 could not erase flash sector.");
907 break;
908 }
909 else
910 {
911 LOG_INFO("sector erased successfully.");
912 }
913 }
914
915 return result;
916 }
917
918 /* ---------------------------------------------------------------------- */
919
920 static int tms470_protect(struct flash_bank *bank, int set, int first, int last)
921 {
922 struct tms470_flash_bank *tms470_info = bank->driver_priv;
923 struct target *target = bank->target;
924 uint32_t fmmac2, fmbsea, fmbseb;
925 int sector;
926
927 if (target->state != TARGET_HALTED)
928 {
929 LOG_ERROR("Target not halted");
930 return ERROR_TARGET_NOT_HALTED;
931 }
932
933 tms470_read_part_info(bank);
934
935 if ((first < 0) || (first >= bank->num_sectors) || (last < 0) || (last >= bank->num_sectors) || (first > last))
936 {
937 LOG_ERROR("Sector range %d to %d invalid.", first, last);
938 return ERROR_FLASH_SECTOR_INVALID;
939 }
940
941 /* enable the appropriate bank */
942 target_read_u32(target, 0xFFE8BC04, &fmmac2);
943 target_write_u32(target, 0xFFE8BC04, (fmmac2 & ~7) | tms470_info->ordinal);
944
945 /* get the original sector proection flags for this bank */
946 target_read_u32(target, 0xFFE88008, &fmbsea);
947 target_read_u32(target, 0xFFE8800C, &fmbseb);
948
949 for (sector = 0; sector < bank->num_sectors; sector++)
950 {
951 if (sector < 16)
952 {
953 fmbsea = set ? fmbsea & ~(1 << sector) : fmbsea | (1 << sector);
954 bank->sectors[sector].is_protected = set ? 1 : 0;
955 }
956 else
957 {
958 fmbseb = set ? fmbseb & ~(1 << (sector - 16)) : fmbseb | (1 << (sector - 16));
959 bank->sectors[sector].is_protected = set ? 1 : 0;
960 }
961 }
962
963 /* update the protection bits */
964 target_write_u32(target, 0xFFE88008, fmbsea);
965 target_write_u32(target, 0xFFE8800C, fmbseb);
966
967 return ERROR_OK;
968 }
969
970 /* ---------------------------------------------------------------------- */
971
972 static int tms470_write(struct flash_bank *bank, uint8_t * buffer, uint32_t offset, uint32_t count)
973 {
974 struct target *target = bank->target;
975 uint32_t glbctrl, fmbac2, orig_fmregopt, fmbsea, fmbseb, fmmaxpp, fmmstat;
976 int result = ERROR_OK;
977 uint32_t i;
978
979 if (target->state != TARGET_HALTED)
980 {
981 LOG_ERROR("Target not halted");
982 return ERROR_TARGET_NOT_HALTED;
983 }
984
985 tms470_read_part_info(bank);
986
987 LOG_INFO("Writing %" PRId32 " bytes starting at 0x%08" PRIx32 "", count, bank->base + offset);
988
989 /* set GLBCTRL.4 */
990 target_read_u32(target, 0xFFFFFFDC, &glbctrl);
991 target_write_u32(target, 0xFFFFFFDC, glbctrl | 0x10);
992
993 (void)tms470_flash_initialize_internal_state_machine(bank);
994
995 /* force max wait states */
996 target_read_u32(target, 0xFFE88004, &fmbac2);
997 target_write_u32(target, 0xFFE88004, fmbac2 | 0xff);
998
999 /* save current access mode, force normal read mode */
1000 target_read_u32(target, 0xFFE89C00, &orig_fmregopt);
1001 target_write_u32(target, 0xFFE89C00, 0x00);
1002
1003 /*
1004 * Disable Level 1 protection for all sectors to be erased/written.
1005 */
1006 target_read_u32(target, 0xFFE88008, &fmbsea);
1007 target_write_u32(target, 0xFFE88008, 0xffff);
1008 target_read_u32(target, 0xFFE8800C, &fmbseb);
1009 target_write_u32(target, 0xFFE8800C, 0xffff);
1010
1011 /* read MAXPP */
1012 target_read_u32(target, 0xFFE8A07C, &fmmaxpp);
1013
1014 for (i = 0; i < count; i += 2)
1015 {
1016 uint32_t addr = bank->base + offset + i;
1017 uint16_t word = (((uint16_t) buffer[i]) << 8) | (uint16_t) buffer[i + 1];
1018
1019 if (word != 0xffff)
1020 {
1021 LOG_INFO("writing 0x%04x at 0x%08" PRIx32 "", word, addr);
1022
1023 /* clear status register */
1024 target_write_u16(target, addr, 0x0040);
1025 /* program flash command */
1026 target_write_u16(target, addr, 0x0010);
1027 /* burn the 16-bit word (big-endian) */
1028 target_write_u16(target, addr, word);
1029
1030 /*
1031 * Monitor FMMSTAT, busy until clear, then check and other flags
1032 * for ultimate result of the operation.
1033 */
1034 do
1035 {
1036 target_read_u32(target, 0xFFE8BC0C, &fmmstat);
1037 if (fmmstat & 0x0100)
1038 {
1039 alive_sleep(1);
1040 }
1041 }
1042 while (fmmstat & 0x0100);
1043
1044 if (fmmstat & 0x3ff)
1045 {
1046 LOG_ERROR("fmstat = 0x%04" PRIx32 "", fmmstat);
1047 LOG_ERROR("Could not program word 0x%04x at address 0x%08" PRIx32 ".", word, addr);
1048 result = ERROR_FLASH_OPERATION_FAILED;
1049 break;
1050 }
1051 }
1052 else
1053 {
1054 LOG_INFO("skipping 0xffff at 0x%08" PRIx32 "", addr);
1055 }
1056 }
1057
1058 /* restore */
1059 target_write_u32(target, 0xFFE88008, fmbsea);
1060 target_write_u32(target, 0xFFE8800C, fmbseb);
1061 target_write_u32(target, 0xFFE88004, fmbac2);
1062 target_write_u32(target, 0xFFE89C00, orig_fmregopt);
1063 target_write_u32(target, 0xFFFFFFDC, glbctrl);
1064
1065 return result;
1066 }
1067
1068 /* ---------------------------------------------------------------------- */
1069
1070 static int tms470_probe(struct flash_bank *bank)
1071 {
1072 if (bank->target->state != TARGET_HALTED)
1073 {
1074 LOG_WARNING("Cannot communicate... target not halted.");
1075 return ERROR_TARGET_NOT_HALTED;
1076 }
1077
1078 return tms470_read_part_info(bank);
1079 }
1080
1081 static int tms470_auto_probe(struct flash_bank *bank)
1082 {
1083 struct tms470_flash_bank *tms470_info = bank->driver_priv;
1084
1085 if (tms470_info->device_ident_reg)
1086 return ERROR_OK;
1087 return tms470_probe(bank);
1088 }
1089
1090 /* ---------------------------------------------------------------------- */
1091
1092 static int tms470_erase_check(struct flash_bank *bank)
1093 {
1094 struct target *target = bank->target;
1095 struct tms470_flash_bank *tms470_info = bank->driver_priv;
1096 int sector, result = ERROR_OK;
1097 uint32_t fmmac2, fmbac2, glbctrl, orig_fmregopt;
1098 static uint8_t buffer[64 * 1024];
1099
1100 if (target->state != TARGET_HALTED)
1101 {
1102 LOG_ERROR("Target not halted");
1103 return ERROR_TARGET_NOT_HALTED;
1104 }
1105
1106 if (!tms470_info->device_ident_reg)
1107 {
1108 tms470_read_part_info(bank);
1109 }
1110
1111 /* set GLBCTRL.4 */
1112 target_read_u32(target, 0xFFFFFFDC, &glbctrl);
1113 target_write_u32(target, 0xFFFFFFDC, glbctrl | 0x10);
1114
1115 /* save current access mode, force normal read mode */
1116 target_read_u32(target, 0xFFE89C00, &orig_fmregopt);
1117 target_write_u32(target, 0xFFE89C00, 0x00);
1118
1119 /* enable the appropriate bank */
1120 target_read_u32(target, 0xFFE8BC04, &fmmac2);
1121 target_write_u32(target, 0xFFE8BC04, (fmmac2 & ~7) | tms470_info->ordinal);
1122
1123 /* TCR = 0 */
1124 target_write_u32(target, 0xFFE8BC10, 0x2fc0);
1125
1126 /* clear TEZ in fmbrdy */
1127 target_write_u32(target, 0xFFE88010, 0x0b);
1128
1129 /* save current wait states, force max */
1130 target_read_u32(target, 0xFFE88004, &fmbac2);
1131 target_write_u32(target, 0xFFE88004, fmbac2 | 0xff);
1132
1133 /*
1134 * The TI primitives inspect the flash memory by reading one 32-bit
1135 * word at a time. Here we read an entire sector and inspect it in
1136 * an attempt to reduce the JTAG overhead.
1137 */
1138 for (sector = 0; sector < bank->num_sectors; sector++)
1139 {
1140 if (bank->sectors[sector].is_erased != 1)
1141 {
1142 uint32_t i, addr = bank->base + bank->sectors[sector].offset;
1143
1144 LOG_INFO("checking flash bank %d sector %d", tms470_info->ordinal, sector);
1145
1146 target_read_buffer(target, addr, bank->sectors[sector].size, buffer);
1147
1148 bank->sectors[sector].is_erased = 1;
1149 for (i = 0; i < bank->sectors[sector].size; i++)
1150 {
1151 if (buffer[i] != 0xff)
1152 {
1153 LOG_WARNING("tms470 bank %d, sector %d, not erased.", tms470_info->ordinal, sector);
1154 LOG_WARNING("at location 0x%08" PRIx32 ": flash data is 0x%02x.", addr + i, buffer[i]);
1155
1156 bank->sectors[sector].is_erased = 0;
1157 break;
1158 }
1159 }
1160 }
1161 if (bank->sectors[sector].is_erased != 1)
1162 {
1163 result = ERROR_FLASH_SECTOR_NOT_ERASED;
1164 break;
1165 }
1166 else
1167 {
1168 LOG_INFO("sector erased");
1169 }
1170 }
1171
1172 /* reset TEZ, wait states, read mode, GLBCTRL.4 */
1173 target_write_u32(target, 0xFFE88010, 0x0f);
1174 target_write_u32(target, 0xFFE88004, fmbac2);
1175 target_write_u32(target, 0xFFE89C00, orig_fmregopt);
1176 target_write_u32(target, 0xFFFFFFDC, glbctrl);
1177
1178 return result;
1179 }
1180
1181 /* ---------------------------------------------------------------------- */
1182
1183 static int tms470_protect_check(struct flash_bank *bank)
1184 {
1185 struct target *target = bank->target;
1186 struct tms470_flash_bank *tms470_info = bank->driver_priv;
1187 int sector, result = ERROR_OK;
1188 uint32_t fmmac2, fmbsea, fmbseb;
1189
1190 if (target->state != TARGET_HALTED)
1191 {
1192 LOG_ERROR("Target not halted");
1193 return ERROR_TARGET_NOT_HALTED;
1194 }
1195
1196 if (!tms470_info->device_ident_reg)
1197 {
1198 tms470_read_part_info(bank);
1199 }
1200
1201 /* enable the appropriate bank */
1202 target_read_u32(target, 0xFFE8BC04, &fmmac2);
1203 target_write_u32(target, 0xFFE8BC04, (fmmac2 & ~7) | tms470_info->ordinal);
1204
1205 target_read_u32(target, 0xFFE88008, &fmbsea);
1206 target_read_u32(target, 0xFFE8800C, &fmbseb);
1207
1208 for (sector = 0; sector < bank->num_sectors; sector++)
1209 {
1210 int protected;
1211
1212 if (sector < 16)
1213 {
1214 protected = fmbsea & (1 << sector) ? 0 : 1;
1215 bank->sectors[sector].is_protected = protected;
1216 }
1217 else
1218 {
1219 protected = fmbseb & (1 << (sector - 16)) ? 0 : 1;
1220 bank->sectors[sector].is_protected = protected;
1221 }
1222
1223 LOG_DEBUG("bank %d sector %d is %s", tms470_info->ordinal, sector, protected ? "protected" : "not protected");
1224 }
1225
1226 return result;
1227 }
1228
1229 /* ---------------------------------------------------------------------- */
1230
1231 static int get_tms470_info(struct flash_bank *bank, char *buf, int buf_size)
1232 {
1233 int used = 0;
1234 struct tms470_flash_bank *tms470_info = bank->driver_priv;
1235
1236 if (!tms470_info->device_ident_reg)
1237 {
1238 tms470_read_part_info(bank);
1239 }
1240
1241 if (!tms470_info->device_ident_reg)
1242 {
1243 (void)snprintf(buf, buf_size, "Cannot identify target as a TMS470\n");
1244 return ERROR_FLASH_OPERATION_FAILED;
1245 }
1246
1247 used = snprintf(buf, buf_size, "\ntms470 information: Chip is %s\n", tms470_info->part_name);
1248 buf += used;
1249 buf_size -= used;
1250
1251 snprintf(buf, buf_size, "Flash protection level 2 is %s\n", tms470_check_flash_unlocked(bank->target) == ERROR_OK ? "disabled" : "enabled");
1252
1253 return ERROR_OK;
1254 }
1255
1256 /* ---------------------------------------------------------------------- */
1257
1258 /*
1259 * flash bank tms470 <base> <size> <chip_width> <bus_width> <target>
1260 * [options...]
1261 */
1262
1263 FLASH_BANK_COMMAND_HANDLER(tms470_flash_bank_command)
1264 {
1265 bank->driver_priv = malloc(sizeof(struct tms470_flash_bank));
1266
1267 if (!bank->driver_priv)
1268 {
1269 return ERROR_FLASH_OPERATION_FAILED;
1270 }
1271
1272 (void)memset(bank->driver_priv, 0, sizeof(struct tms470_flash_bank));
1273
1274 return ERROR_OK;
1275 }
1276
1277 struct flash_driver tms470_flash = {
1278 .name = "tms470",
1279 .commands = tms470_command_handlers,
1280 .flash_bank_command = tms470_flash_bank_command,
1281 .erase = tms470_erase,
1282 .protect = tms470_protect,
1283 .write = tms470_write,
1284 .read = default_flash_read,
1285 .probe = tms470_probe,
1286 .auto_probe = tms470_auto_probe,
1287 .erase_check = tms470_erase_check,
1288 .protect_check = tms470_protect_check,
1289 .info = get_tms470_info,
1290 };

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)