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