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