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