bf708be2d90d889a4c277dfb1bf4aa2e048f7349
[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 command_print(CMD_CTX, "tms470 flash_keyset <key0> <key1> <key2> <key3>");
317 return ERROR_COMMAND_SYNTAX_ERROR;
318 }
319 else if (CMD_ARGC == 4)
320 {
321 int i;
322
323 for (i = 0; i < 4; i++)
324 {
325 int start = (0 == strncmp(CMD_ARGV[i], "0x", 2)) ? 2 : 0;
326
327 if (1 != sscanf(&CMD_ARGV[i][start], "%" SCNx32 "", &flashKeys[i]))
328 {
329 command_print(CMD_CTX, "could not process flash key %s", CMD_ARGV[i]);
330 LOG_ERROR("could not process flash key %s", CMD_ARGV[i]);
331 return ERROR_COMMAND_SYNTAX_ERROR;
332 }
333 }
334
335 keysSet = 1;
336 }
337 else if (CMD_ARGC != 0)
338 {
339 command_print(CMD_CTX, "tms470 flash_keyset <key0> <key1> <key2> <key3>");
340 return ERROR_COMMAND_SYNTAX_ERROR;
341 }
342
343 if (keysSet)
344 {
345 command_print(CMD_CTX, "using flash keys 0x%08" PRIx32 ", 0x%08" PRIx32 ", 0x%08" PRIx32 ", 0x%08" PRIx32 "",
346 flashKeys[0], flashKeys[1], flashKeys[2], flashKeys[3]);
347 }
348 else
349 {
350 command_print(CMD_CTX, "flash keys not set");
351 }
352
353 return ERROR_OK;
354 }
355
356 static const uint32_t FLASH_KEYS_ALL_ONES[] = { 0xFFFFFFFF, 0xFFFFFFFF,
357 0xFFFFFFFF, 0xFFFFFFFF,
358 };
359
360 static const uint32_t FLASH_KEYS_ALL_ZEROS[] = { 0x00000000, 0x00000000,
361 0x00000000, 0x00000000,
362 };
363
364 static const uint32_t FLASH_KEYS_MIX1[] = { 0xf0fff0ff, 0xf0fff0ff,
365 0xf0fff0ff, 0xf0fff0ff
366 };
367
368 static const uint32_t FLASH_KEYS_MIX2[] = { 0x0000ffff, 0x0000ffff,
369 0x0000ffff, 0x0000ffff
370 };
371
372 /* ---------------------------------------------------------------------- */
373
374 static int oscMHz = 12;
375
376 COMMAND_HANDLER(tms470_handle_osc_megahertz_command)
377 {
378 if (CMD_ARGC > 1)
379 {
380 command_print(CMD_CTX, "tms470 osc_megahertz <MHz>");
381 return ERROR_COMMAND_SYNTAX_ERROR;
382 }
383 else if (CMD_ARGC == 1)
384 {
385 sscanf(CMD_ARGV[0], "%d", &oscMHz);
386 }
387
388 if (oscMHz <= 0)
389 {
390 LOG_ERROR("osc_megahertz must be positive and non-zero!");
391 command_print(CMD_CTX, "osc_megahertz must be positive and non-zero!");
392 oscMHz = 12;
393 return ERROR_COMMAND_SYNTAX_ERROR;
394 }
395
396 command_print(CMD_CTX, "osc_megahertz=%d", oscMHz);
397
398 return ERROR_OK;
399 }
400
401 /* ---------------------------------------------------------------------- */
402
403 static int plldis = 0;
404
405 COMMAND_HANDLER(tms470_handle_plldis_command)
406 {
407 if (CMD_ARGC > 1)
408 {
409 command_print(CMD_CTX, "tms470 plldis <0 | 1>");
410 return ERROR_COMMAND_SYNTAX_ERROR;
411 }
412 else if (CMD_ARGC == 1)
413 {
414 sscanf(CMD_ARGV[0], "%d", &plldis);
415 plldis = plldis ? 1 : 0;
416 }
417
418 command_print(CMD_CTX, "plldis=%d", plldis);
419
420 return ERROR_OK;
421 }
422
423 /* ---------------------------------------------------------------------- */
424
425 static int tms470_check_flash_unlocked(struct target * target)
426 {
427 uint32_t fmbbusy;
428
429 target_read_u32(target, 0xFFE89C08, &fmbbusy);
430 LOG_INFO("tms470 fmbbusy = 0x%08" PRIx32 " -> %s", fmbbusy, fmbbusy & 0x8000 ? "unlocked" : "LOCKED");
431 return fmbbusy & 0x8000 ? ERROR_OK : ERROR_FLASH_OPERATION_FAILED;
432 }
433
434 /* ---------------------------------------------------------------------- */
435
436 static int tms470_try_flash_keys(struct target * target, const uint32_t * key_set)
437 {
438 uint32_t glbctrl, fmmstat;
439 int retval = ERROR_FLASH_OPERATION_FAILED;
440
441 /* set GLBCTRL.4 */
442 target_read_u32(target, 0xFFFFFFDC, &glbctrl);
443 target_write_u32(target, 0xFFFFFFDC, glbctrl | 0x10);
444
445 /* only perform the key match when 3VSTAT is clear */
446 target_read_u32(target, 0xFFE8BC0C, &fmmstat);
447 if (!(fmmstat & 0x08))
448 {
449 unsigned i;
450 uint32_t fmbptr, fmbac2, orig_fmregopt;
451
452 target_write_u32(target, 0xFFE8BC04, fmmstat & ~0x07);
453
454 /* wait for pump ready */
455 do
456 {
457 target_read_u32(target, 0xFFE8A814, &fmbptr);
458 alive_sleep(1);
459 }
460 while (!(fmbptr & 0x0200));
461
462 /* force max wait states */
463 target_read_u32(target, 0xFFE88004, &fmbac2);
464 target_write_u32(target, 0xFFE88004, fmbac2 | 0xff);
465
466 /* save current access mode, force normal read mode */
467 target_read_u32(target, 0xFFE89C00, &orig_fmregopt);
468 target_write_u32(target, 0xFFE89C00, 0x00);
469
470 for (i = 0; i < 4; i++)
471 {
472 uint32_t tmp;
473
474 /* There is no point displaying the value of tmp, it is
475 * filtered by the chip. The purpose of this read is to
476 * prime the unlocking logic rather than read out the value.
477 */
478 target_read_u32(target, 0x00001FF0 + 4 * i, &tmp);
479
480 LOG_INFO("tms470 writing fmpkey = 0x%08" PRIx32 "", key_set[i]);
481 target_write_u32(target, 0xFFE89C0C, key_set[i]);
482 }
483
484 if (ERROR_OK == tms470_check_flash_unlocked(target))
485 {
486 /*
487 * There seems to be a side-effect of reading the FMPKEY
488 * register in that it re-enables the protection. So we
489 * re-enable it.
490 */
491 for (i = 0; i < 4; i++)
492 {
493 uint32_t tmp;
494
495 target_read_u32(target, 0x00001FF0 + 4 * i, &tmp);
496 target_write_u32(target, 0xFFE89C0C, key_set[i]);
497 }
498 retval = ERROR_OK;
499 }
500
501 /* restore settings */
502 target_write_u32(target, 0xFFE89C00, orig_fmregopt);
503 target_write_u32(target, 0xFFE88004, fmbac2);
504 }
505
506 /* clear config bit */
507 target_write_u32(target, 0xFFFFFFDC, glbctrl);
508
509 return retval;
510 }
511
512 /* ---------------------------------------------------------------------- */
513
514 static int tms470_unlock_flash(struct flash_bank *bank)
515 {
516 struct target *target = bank->target;
517 const uint32_t *p_key_sets[5];
518 unsigned i, key_set_count;
519
520 if (keysSet)
521 {
522 key_set_count = 5;
523 p_key_sets[0] = flashKeys;
524 p_key_sets[1] = FLASH_KEYS_ALL_ONES;
525 p_key_sets[2] = FLASH_KEYS_ALL_ZEROS;
526 p_key_sets[3] = FLASH_KEYS_MIX1;
527 p_key_sets[4] = FLASH_KEYS_MIX2;
528 }
529 else
530 {
531 key_set_count = 4;
532 p_key_sets[0] = FLASH_KEYS_ALL_ONES;
533 p_key_sets[1] = FLASH_KEYS_ALL_ZEROS;
534 p_key_sets[2] = FLASH_KEYS_MIX1;
535 p_key_sets[3] = FLASH_KEYS_MIX2;
536 }
537
538 for (i = 0; i < key_set_count; i++)
539 {
540 if (tms470_try_flash_keys(target, p_key_sets[i]) == ERROR_OK)
541 {
542 LOG_INFO("tms470 flash is unlocked");
543 return ERROR_OK;
544 }
545 }
546
547 LOG_WARNING("tms470 could not unlock flash memory protection level 2");
548 return ERROR_FLASH_OPERATION_FAILED;
549 }
550
551 /* ---------------------------------------------------------------------- */
552
553 static int tms470_flash_initialize_internal_state_machine(struct flash_bank *bank)
554 {
555 uint32_t fmmac2, fmmac1, fmmaxep, k, delay, glbctrl, sysclk;
556 struct target *target = bank->target;
557 struct tms470_flash_bank *tms470_info = bank->driver_priv;
558 int result = ERROR_OK;
559
560 /*
561 * Select the desired bank to be programmed by writing BANK[2:0] of
562 * FMMAC2.
563 */
564 target_read_u32(target, 0xFFE8BC04, &fmmac2);
565 fmmac2 &= ~0x0007;
566 fmmac2 |= (tms470_info->ordinal & 7);
567 target_write_u32(target, 0xFFE8BC04, fmmac2);
568 LOG_DEBUG("set fmmac2 = 0x%04" PRIx32 "", fmmac2);
569
570 /*
571 * Disable level 1 sector protection by setting bit 15 of FMMAC1.
572 */
573 target_read_u32(target, 0xFFE8BC00, &fmmac1);
574 fmmac1 |= 0x8000;
575 target_write_u32(target, 0xFFE8BC00, fmmac1);
576 LOG_DEBUG("set fmmac1 = 0x%04" PRIx32 "", fmmac1);
577
578 /*
579 * FMTCREG = 0x2fc0;
580 */
581 target_write_u32(target, 0xFFE8BC10, 0x2fc0);
582 LOG_DEBUG("set fmtcreg = 0x2fc0");
583
584 /*
585 * MAXPP = 50
586 */
587 target_write_u32(target, 0xFFE8A07C, 50);
588 LOG_DEBUG("set fmmaxpp = 50");
589
590 /*
591 * MAXCP = 0xf000 + 2000
592 */
593 target_write_u32(target, 0xFFE8A084, 0xf000 + 2000);
594 LOG_DEBUG("set fmmaxcp = 0x%04x", 0xf000 + 2000);
595
596 /*
597 * configure VHV
598 */
599 target_read_u32(target, 0xFFE8A080, &fmmaxep);
600 if (fmmaxep == 0xf000)
601 {
602 fmmaxep = 0xf000 + 4095;
603 target_write_u32(target, 0xFFE8A80C, 0x9964);
604 LOG_DEBUG("set fmptr3 = 0x9964");
605 }
606 else
607 {
608 fmmaxep = 0xa000 + 4095;
609 target_write_u32(target, 0xFFE8A80C, 0x9b64);
610 LOG_DEBUG("set fmptr3 = 0x9b64");
611 }
612 target_write_u32(target, 0xFFE8A080, fmmaxep);
613 LOG_DEBUG("set fmmaxep = 0x%04" PRIx32 "", fmmaxep);
614
615 /*
616 * FMPTR4 = 0xa000
617 */
618 target_write_u32(target, 0xFFE8A810, 0xa000);
619 LOG_DEBUG("set fmptr4 = 0xa000");
620
621 /*
622 * FMPESETUP, delay parameter selected based on clock frequency.
623 *
624 * According to the TI App Note SPNU257 and flashing code, delay is
625 * int((sysclk(MHz) + 1) / 2), with a minimum of 5. The system
626 * clock is usually derived from the ZPLL module, and selected by
627 * the plldis global.
628 */
629 target_read_u32(target, 0xFFFFFFDC, &glbctrl);
630 sysclk = (plldis ? 1 : (glbctrl & 0x08) ? 4 : 8) * oscMHz / (1 + (glbctrl & 7));
631 delay = (sysclk > 10) ? (sysclk + 1) / 2 : 5;
632 target_write_u32(target, 0xFFE8A018, (delay << 4) | (delay << 8));
633 LOG_DEBUG("set fmpsetup = 0x%04" PRIx32 "", (delay << 4) | (delay << 8));
634
635 /*
636 * FMPVEVACCESS, based on delay.
637 */
638 k = delay | (delay << 8);
639 target_write_u32(target, 0xFFE8A05C, k);
640 LOG_DEBUG("set fmpvevaccess = 0x%04" PRIx32 "", k);
641
642 /*
643 * FMPCHOLD, FMPVEVHOLD, FMPVEVSETUP, based on delay.
644 */
645 k <<= 1;
646 target_write_u32(target, 0xFFE8A034, k);
647 LOG_DEBUG("set fmpchold = 0x%04" PRIx32 "", k);
648 target_write_u32(target, 0xFFE8A040, k);
649 LOG_DEBUG("set fmpvevhold = 0x%04" PRIx32 "", k);
650 target_write_u32(target, 0xFFE8A024, k);
651 LOG_DEBUG("set fmpvevsetup = 0x%04" PRIx32 "", k);
652
653 /*
654 * FMCVACCESS, based on delay.
655 */
656 k = delay * 16;
657 target_write_u32(target, 0xFFE8A060, k);
658 LOG_DEBUG("set fmcvaccess = 0x%04" PRIx32 "", k);
659
660 /*
661 * FMCSETUP, based on delay.
662 */
663 k = 0x3000 | delay * 20;
664 target_write_u32(target, 0xFFE8A020, k);
665 LOG_DEBUG("set fmcsetup = 0x%04" PRIx32 "", k);
666
667 /*
668 * FMEHOLD, based on delay.
669 */
670 k = (delay * 20) << 2;
671 target_write_u32(target, 0xFFE8A038, k);
672 LOG_DEBUG("set fmehold = 0x%04" PRIx32 "", k);
673
674 /*
675 * PWIDTH, CWIDTH, EWIDTH, based on delay.
676 */
677 target_write_u32(target, 0xFFE8A050, delay * 8);
678 LOG_DEBUG("set fmpwidth = 0x%04" PRIx32 "", delay * 8);
679 target_write_u32(target, 0xFFE8A058, delay * 1000);
680 LOG_DEBUG("set fmcwidth = 0x%04" PRIx32 "", delay * 1000);
681 target_write_u32(target, 0xFFE8A054, delay * 5400);
682 LOG_DEBUG("set fmewidth = 0x%04" PRIx32 "", delay * 5400);
683
684 return result;
685 }
686
687 /* ---------------------------------------------------------------------- */
688
689 static int tms470_flash_status(struct flash_bank *bank)
690 {
691 struct target *target = bank->target;
692 int result = ERROR_OK;
693 uint32_t fmmstat;
694
695 target_read_u32(target, 0xFFE8BC0C, &fmmstat);
696 LOG_DEBUG("set fmmstat = 0x%04" PRIx32 "", fmmstat);
697
698 if (fmmstat & 0x0080)
699 {
700 LOG_WARNING("tms470 flash command: erase still active after busy clear.");
701 result = ERROR_FLASH_OPERATION_FAILED;
702 }
703
704 if (fmmstat & 0x0040)
705 {
706 LOG_WARNING("tms470 flash command: program still active after busy clear.");
707 result = ERROR_FLASH_OPERATION_FAILED;
708 }
709
710 if (fmmstat & 0x0020)
711 {
712 LOG_WARNING("tms470 flash command: invalid data command.");
713 result = ERROR_FLASH_OPERATION_FAILED;
714 }
715
716 if (fmmstat & 0x0010)
717 {
718 LOG_WARNING("tms470 flash command: program, erase or validate sector failed.");
719 result = ERROR_FLASH_OPERATION_FAILED;
720 }
721
722 if (fmmstat & 0x0008)
723 {
724 LOG_WARNING("tms470 flash command: voltage instability detected.");
725 result = ERROR_FLASH_OPERATION_FAILED;
726 }
727
728 if (fmmstat & 0x0006)
729 {
730 LOG_WARNING("tms470 flash command: command suspend detected.");
731 result = ERROR_FLASH_OPERATION_FAILED;
732 }
733
734 if (fmmstat & 0x0001)
735 {
736 LOG_WARNING("tms470 flash command: sector was locked.");
737 result = ERROR_FLASH_OPERATION_FAILED;
738 }
739
740 return result;
741 }
742
743 /* ---------------------------------------------------------------------- */
744
745 static int tms470_erase_sector(struct flash_bank *bank, int sector)
746 {
747 uint32_t glbctrl, orig_fmregopt, fmbsea, fmbseb, fmmstat;
748 struct target *target = bank->target;
749 uint32_t flashAddr = bank->base + bank->sectors[sector].offset;
750 int result = ERROR_OK;
751
752 /*
753 * Set the bit GLBCTRL4 of the GLBCTRL register (in the System
754 * module) to enable writing to the flash registers }.
755 */
756 target_read_u32(target, 0xFFFFFFDC, &glbctrl);
757 target_write_u32(target, 0xFFFFFFDC, glbctrl | 0x10);
758 LOG_DEBUG("set glbctrl = 0x%08" PRIx32 "", glbctrl | 0x10);
759
760 /* Force normal read mode. */
761 target_read_u32(target, 0xFFE89C00, &orig_fmregopt);
762 target_write_u32(target, 0xFFE89C00, 0);
763 LOG_DEBUG("set fmregopt = 0x%08x", 0);
764
765 (void)tms470_flash_initialize_internal_state_machine(bank);
766
767 /*
768 * Select one or more bits in FMBSEA or FMBSEB to disable Level 1
769 * protection for the particular sector to be erased/written.
770 */
771 if (sector < 16)
772 {
773 target_read_u32(target, 0xFFE88008, &fmbsea);
774 target_write_u32(target, 0xFFE88008, fmbsea | (1 << sector));
775 LOG_DEBUG("set fmbsea = 0x%04" PRIx32 "", fmbsea | (1 << sector));
776 }
777 else
778 {
779 target_read_u32(target, 0xFFE8800C, &fmbseb);
780 target_write_u32(target, 0xFFE8800C, fmbseb | (1 << (sector - 16)));
781 LOG_DEBUG("set fmbseb = 0x%04" PRIx32 "", fmbseb | (1 << (sector - 16)));
782 }
783 bank->sectors[sector].is_protected = 0;
784
785 /*
786 * clear status regiser, sent erase command, kickoff erase
787 */
788 target_write_u16(target, flashAddr, 0x0040);
789 LOG_DEBUG("write *(uint16_t *)0x%08" PRIx32 "=0x0040", flashAddr);
790 target_write_u16(target, flashAddr, 0x0020);
791 LOG_DEBUG("write *(uint16_t *)0x%08" PRIx32 "=0x0020", flashAddr);
792 target_write_u16(target, flashAddr, 0xffff);
793 LOG_DEBUG("write *(uint16_t *)0x%08" PRIx32 "=0xffff", flashAddr);
794
795 /*
796 * Monitor FMMSTAT, busy until clear, then check and other flags for
797 * ultimate result of the operation.
798 */
799 do
800 {
801 target_read_u32(target, 0xFFE8BC0C, &fmmstat);
802 if (fmmstat & 0x0100)
803 {
804 alive_sleep(1);
805 }
806 }
807 while (fmmstat & 0x0100);
808
809 result = tms470_flash_status(bank);
810
811 if (sector < 16)
812 {
813 target_write_u32(target, 0xFFE88008, fmbsea);
814 LOG_DEBUG("set fmbsea = 0x%04" PRIx32 "", fmbsea);
815 bank->sectors[sector].is_protected = fmbsea & (1 << sector) ? 0 : 1;
816 }
817 else
818 {
819 target_write_u32(target, 0xFFE8800C, fmbseb);
820 LOG_DEBUG("set fmbseb = 0x%04" PRIx32 "", fmbseb);
821 bank->sectors[sector].is_protected = fmbseb & (1 << (sector - 16)) ? 0 : 1;
822 }
823 target_write_u32(target, 0xFFE89C00, orig_fmregopt);
824 LOG_DEBUG("set fmregopt = 0x%08" PRIx32 "", orig_fmregopt);
825 target_write_u32(target, 0xFFFFFFDC, glbctrl);
826 LOG_DEBUG("set glbctrl = 0x%08" PRIx32 "", glbctrl);
827
828 if (result == ERROR_OK)
829 {
830 bank->sectors[sector].is_erased = 1;
831 }
832
833 return result;
834 }
835
836 /* ----------------------------------------------------------------------
837 Implementation of Flash Driver Interfaces
838 ---------------------------------------------------------------------- */
839
840 static const struct command_registration tms470_any_command_handlers[] = {
841 {
842 .name = "flash_keyset",
843 .handler = tms470_handle_flash_keyset_command,
844 .mode = COMMAND_ANY,
845 .help = "tms470 flash_keyset <key0> <key1> <key2> <key3>",
846 },
847 {
848 .name = "osc_megahertz",
849 .handler = tms470_handle_osc_megahertz_command,
850 .mode = COMMAND_ANY,
851 .help = "tms470 osc_megahertz <MHz>",
852 },
853 {
854 .name = "plldis",
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)