]> git.sur5r.net Git - openocd/blob - src/flash/nor/str7x.c
FLASH/NOR: Remove useless file str7x.h
[openocd] / src / flash / nor / str7x.c
1 /***************************************************************************
2  *   Copyright (C) 2005 by Dominic Rath                                    *
3  *   Dominic.Rath@gmx.de                                                   *
4  *                                                                         *
5  *   Copyright (C) 2008 by Spencer Oliver                                  *
6  *   spen@spen-soft.co.uk                                                  *
7  *                                                                         *
8  *   Copyright (C) 2010 Ã˜yvind Harboe                                      *
9  *   oyvind.harboe@zylin.com                                               *
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  *   This program is distributed in the hope that it will be useful,       *
17  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
18  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
19  *   GNU General Public License for more details.                          *
20  *                                                                         *
21  *   You should have received a copy of the GNU General Public License     *
22  *   along with this program; if not, write to the                         *
23  *   Free Software Foundation, Inc.,                                       *
24  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
25  ***************************************************************************/
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include "imp.h"
31 #include <target/arm.h>
32 #include <helper/binarybuffer.h>
33 #include <target/algorithm.h>
34
35
36 /*  Flash registers */
37
38 #define FLASH_CR0               0x00000000
39 #define FLASH_CR1               0x00000004
40 #define FLASH_DR0               0x00000008
41 #define FLASH_DR1               0x0000000C
42 #define FLASH_AR                0x00000010
43 #define FLASH_ER                0x00000014
44 #define FLASH_NVWPAR    0x0000DFB0
45 #define FLASH_NVAPR0    0x0000DFB8
46 #define FLASH_NVAPR1    0x0000DFBC
47
48 /* FLASH_CR0 register bits */
49
50 #define FLASH_WMS               0x80000000
51 #define FLASH_SUSP              0x40000000
52 #define FLASH_WPG               0x20000000
53 #define FLASH_DWPG              0x10000000
54 #define FLASH_SER               0x08000000
55 #define FLASH_SPR               0x01000000
56 #define FLASH_BER               0x04000000
57 #define FLASH_MER               0x02000000
58 #define FLASH_LOCK              0x00000010
59 #define FLASH_BSYA1             0x00000004
60 #define FLASH_BSYA0             0x00000002
61
62 /* FLASH_CR1 register bits */
63
64 #define FLASH_B1S               0x02000000
65 #define FLASH_B0S               0x01000000
66 #define FLASH_B1F1              0x00020000
67 #define FLASH_B1F0              0x00010000
68 #define FLASH_B0F7              0x00000080
69 #define FLASH_B0F6              0x00000040
70 #define FLASH_B0F5              0x00000020
71 #define FLASH_B0F4              0x00000010
72 #define FLASH_B0F3              0x00000008
73 #define FLASH_B0F2              0x00000004
74 #define FLASH_B0F1              0x00000002
75 #define FLASH_B0F0              0x00000001
76
77 /* FLASH_ER register bits */
78
79 #define FLASH_WPF               0x00000100
80 #define FLASH_RESER             0x00000080
81 #define FLASH_SEQER             0x00000040
82 #define FLASH_10ER              0x00000008
83 #define FLASH_PGER              0x00000004
84 #define FLASH_ERER              0x00000002
85 #define FLASH_ERR               0x00000001
86
87
88 struct str7x_flash_bank
89 {
90         uint32_t *sector_bits;
91         uint32_t disable_bit;
92         uint32_t busy_bits;
93         uint32_t register_base;
94         struct working_area *write_algorithm;
95 };
96
97 struct str7x_mem_layout {
98         uint32_t sector_start;
99         uint32_t sector_size;
100         uint32_t sector_bit;
101 };
102
103 enum str7x_status_codes
104 {
105         STR7X_CMD_SUCCESS = 0,
106         STR7X_INVALID_COMMAND = 1,
107         STR7X_SRC_ADDR_ERROR = 2,
108         STR7X_DST_ADDR_ERROR = 3,
109         STR7X_SRC_ADDR_NOT_MAPPED = 4,
110         STR7X_DST_ADDR_NOT_MAPPED = 5,
111         STR7X_COUNT_ERROR = 6,
112         STR7X_INVALID_SECTOR = 7,
113         STR7X_SECTOR_NOT_BLANK = 8,
114         STR7X_SECTOR_NOT_PREPARED = 9,
115         STR7X_COMPARE_ERROR = 10,
116         STR7X_BUSY = 11
117 };
118
119 static struct str7x_mem_layout mem_layout_str7bank0[] = {
120         {0x00000000, 0x02000, 0x01},
121         {0x00002000, 0x02000, 0x02},
122         {0x00004000, 0x02000, 0x04},
123         {0x00006000, 0x02000, 0x08},
124         {0x00008000, 0x08000, 0x10},
125         {0x00010000, 0x10000, 0x20},
126         {0x00020000, 0x10000, 0x40},
127         {0x00030000, 0x10000, 0x80}
128 };
129
130 static struct str7x_mem_layout mem_layout_str7bank1[] = {
131         {0x00000000, 0x02000, 0x10000},
132         {0x00002000, 0x02000, 0x20000}
133 };
134
135 static int str7x_get_flash_adr(struct flash_bank *bank, uint32_t reg)
136 {
137         struct str7x_flash_bank *str7x_info = bank->driver_priv;
138         return (str7x_info->register_base | reg);
139 }
140
141 static int str7x_build_block_list(struct flash_bank *bank)
142 {
143         struct str7x_flash_bank *str7x_info = bank->driver_priv;
144
145         int i;
146         int num_sectors;
147         int b0_sectors = 0, b1_sectors = 0;
148
149         switch (bank->size)
150         {
151                 case 16 * 1024:
152                         b1_sectors = 2;
153                         break;
154                 case 64 * 1024:
155                         b0_sectors = 5;
156                         break;
157                 case 128 * 1024:
158                         b0_sectors = 6;
159                         break;
160                 case 256 * 1024:
161                         b0_sectors = 8;
162                         break;
163                 default:
164                         LOG_ERROR("BUG: unknown bank->size encountered");
165                         exit(-1);
166         }
167
168         num_sectors = b0_sectors + b1_sectors;
169
170         bank->num_sectors = num_sectors;
171         bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);
172         str7x_info->sector_bits = malloc(sizeof(uint32_t) * num_sectors);
173
174         num_sectors = 0;
175
176         for (i = 0; i < b0_sectors; i++)
177         {
178                 bank->sectors[num_sectors].offset = mem_layout_str7bank0[i].sector_start;
179                 bank->sectors[num_sectors].size = mem_layout_str7bank0[i].sector_size;
180                 bank->sectors[num_sectors].is_erased = -1;
181                 /* the reset_init handler marks all the sectors unprotected,
182                  * matching hardware after reset; keep the driver in sync
183                  */
184                 bank->sectors[num_sectors].is_protected = 0;
185                 str7x_info->sector_bits[num_sectors++] = mem_layout_str7bank0[i].sector_bit;
186         }
187
188         for (i = 0; i < b1_sectors; i++)
189         {
190                 bank->sectors[num_sectors].offset = mem_layout_str7bank1[i].sector_start;
191                 bank->sectors[num_sectors].size = mem_layout_str7bank1[i].sector_size;
192                 bank->sectors[num_sectors].is_erased = -1;
193                 /* the reset_init handler marks all the sectors unprotected,
194                  * matching hardware after reset; keep the driver in sync
195                  */
196                 bank->sectors[num_sectors].is_protected = 0;
197                 str7x_info->sector_bits[num_sectors++] = mem_layout_str7bank1[i].sector_bit;
198         }
199
200         return ERROR_OK;
201 }
202
203 /* flash bank str7x <base> <size> 0 0 <target#> <str71_variant>
204  */
205 FLASH_BANK_COMMAND_HANDLER(str7x_flash_bank_command)
206 {
207         struct str7x_flash_bank *str7x_info;
208
209         if (CMD_ARGC < 7)
210         {
211                 LOG_WARNING("incomplete flash_bank str7x configuration");
212                 return ERROR_FLASH_BANK_INVALID;
213         }
214
215         str7x_info = malloc(sizeof(struct str7x_flash_bank));
216         bank->driver_priv = str7x_info;
217
218         /* set default bits for str71x flash */
219         str7x_info->busy_bits = (FLASH_LOCK | FLASH_BSYA1 | FLASH_BSYA0);
220         str7x_info->disable_bit = (1 << 1);
221
222         if (strcmp(CMD_ARGV[6], "STR71x") == 0)
223         {
224                 str7x_info->register_base = 0x40100000;
225         }
226         else if (strcmp(CMD_ARGV[6], "STR73x") == 0)
227         {
228                 str7x_info->register_base = 0x80100000;
229                 str7x_info->busy_bits = (FLASH_LOCK | FLASH_BSYA0);
230         }
231         else if (strcmp(CMD_ARGV[6], "STR75x") == 0)
232         {
233                 str7x_info->register_base = 0x20100000;
234                 str7x_info->disable_bit = (1 << 0);
235         }
236         else
237         {
238                 LOG_ERROR("unknown STR7x variant: '%s'", CMD_ARGV[6]);
239                 free(str7x_info);
240                 return ERROR_FLASH_BANK_INVALID;
241         }
242
243         str7x_build_block_list(bank);
244
245         str7x_info->write_algorithm = NULL;
246
247         return ERROR_OK;
248 }
249
250 /* wait for flash to become idle or report errors.
251
252    FIX!!! what's the maximum timeout??? The documentation doesn't
253    state any maximum time.... by inspection it seems > 1000ms is to be
254    expected.
255
256    10000ms is long enough that it should cover anything, yet not
257    quite be equivalent to an infinite loop.
258
259  */
260 static int str7x_waitbusy(struct flash_bank *bank)
261 {
262         int err;
263         int i;
264         struct target *target = bank->target;
265         struct str7x_flash_bank *str7x_info = bank->driver_priv;
266
267         for (i = 0 ; i < 10000; i++)
268         {
269                 uint32_t retval;
270                 err = target_read_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), &retval);
271                 if (err != ERROR_OK)
272                         return err;
273
274                 if ((retval & str7x_info->busy_bits) == 0)
275                         return ERROR_OK;
276
277                 alive_sleep(1);
278         }
279         LOG_ERROR("Timed out waiting for str7x flash");
280         return ERROR_FAIL;
281 }
282
283
284 static int str7x_result(struct flash_bank *bank)
285 {
286         struct target *target = bank->target;
287         uint32_t retval;
288
289         int err;
290         err = target_read_u32(target, str7x_get_flash_adr(bank, FLASH_ER), &retval);
291         if (err != ERROR_OK)
292                 return err;
293
294         if (retval & FLASH_WPF)
295         {
296                 LOG_ERROR("str7x hw write protection set");
297                 err = ERROR_FAIL;
298         }
299         if (retval & FLASH_RESER)
300         {
301                 LOG_ERROR("str7x suspended program erase not resumed");
302                 err = ERROR_FAIL;
303         }
304         if (retval & FLASH_10ER)
305         {
306                 LOG_ERROR("str7x trying to set bit to 1 when it is already 0");
307                 err = ERROR_FAIL;
308         }
309         if (retval & FLASH_PGER)
310         {
311                 LOG_ERROR("str7x program error");
312                 err = ERROR_FAIL;
313         }
314         if (retval & FLASH_ERER)
315         {
316                 LOG_ERROR("str7x erase error");
317                 err = ERROR_FAIL;
318         }
319         if (err == ERROR_OK)
320         {
321                 if (retval & FLASH_ERR)
322                 {
323                         /* this should always be set if one of the others are set... */
324                         LOG_ERROR("str7x write operation failed / bad setup");
325                         err = ERROR_FAIL;
326                 }
327         }
328         if (err != ERROR_OK)
329         {
330                 LOG_ERROR("FLASH_ER register contents: 0x%" PRIx32, retval);
331         }
332
333         return retval;
334 }
335
336 static int str7x_protect_check(struct flash_bank *bank)
337 {
338         struct str7x_flash_bank *str7x_info = bank->driver_priv;
339         struct target *target = bank->target;
340
341         int i;
342         uint32_t retval;
343
344         if (bank->target->state != TARGET_HALTED)
345         {
346                 LOG_ERROR("Target not halted");
347                 return ERROR_TARGET_NOT_HALTED;
348         }
349
350         target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVWPAR), &retval);
351
352         for (i = 0; i < bank->num_sectors; i++)
353         {
354                 if (retval & str7x_info->sector_bits[i])
355                         bank->sectors[i].is_protected = 0;
356                 else
357                         bank->sectors[i].is_protected = 1;
358         }
359
360         return ERROR_OK;
361 }
362
363 static int str7x_erase(struct flash_bank *bank, int first, int last)
364 {
365         struct str7x_flash_bank *str7x_info = bank->driver_priv;
366         struct target *target = bank->target;
367
368         int i;
369         uint32_t cmd;
370         uint32_t sectors = 0;
371         int err;
372
373         if (bank->target->state != TARGET_HALTED)
374         {
375                 LOG_ERROR("Target not halted");
376                 return ERROR_TARGET_NOT_HALTED;
377         }
378
379         for (i = first; i <= last; i++)
380         {
381                 sectors |= str7x_info->sector_bits[i];
382         }
383
384         LOG_DEBUG("sectors: 0x%" PRIx32 "", sectors);
385
386         /* clear FLASH_ER register */
387         err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
388         if (err != ERROR_OK)
389                 return err;
390
391         cmd = FLASH_SER;
392         err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
393         if (err != ERROR_OK)
394                 return err;
395
396         cmd = sectors;
397         err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR1), cmd);
398         if (err != ERROR_OK)
399                 return err;
400
401         cmd = FLASH_SER | FLASH_WMS;
402         err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
403         if (err != ERROR_OK)
404                 return err;
405
406         err = str7x_waitbusy(bank);
407         if (err != ERROR_OK)
408                 return err;
409
410         err = str7x_result(bank);
411         if (err != ERROR_OK)
412                 return err;
413
414         for (i = first; i <= last; i++)
415                 bank->sectors[i].is_erased = 1;
416
417         return ERROR_OK;
418 }
419
420 static int str7x_protect(struct flash_bank *bank, int set, int first, int last)
421 {
422         struct str7x_flash_bank *str7x_info = bank->driver_priv;
423         struct target *target = bank->target;
424         int i;
425         uint32_t cmd;
426         uint32_t protect_blocks;
427
428         if (bank->target->state != TARGET_HALTED)
429         {
430                 LOG_ERROR("Target not halted");
431                 return ERROR_TARGET_NOT_HALTED;
432         }
433
434         protect_blocks = 0xFFFFFFFF;
435
436         if (set)
437         {
438                 for (i = first; i <= last; i++)
439                         protect_blocks &= ~(str7x_info->sector_bits[i]);
440         }
441
442         /* clear FLASH_ER register */
443         int err;
444         err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
445         if (err != ERROR_OK)
446                 return err;
447
448         cmd = FLASH_SPR;
449         err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
450         if (err != ERROR_OK)
451                 return err;
452
453         cmd = str7x_get_flash_adr(bank, FLASH_NVWPAR);
454         err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), cmd);
455         if (err != ERROR_OK)
456                 return err;
457
458         cmd = protect_blocks;
459         err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), cmd);
460         if (err != ERROR_OK)
461                 return err;
462
463         cmd = FLASH_SPR | FLASH_WMS;
464         err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
465         if (err != ERROR_OK)
466                 return err;
467
468         err = str7x_waitbusy(bank);
469         if (err != ERROR_OK)
470                 return err;
471
472         err = str7x_result(bank);
473         if (err != ERROR_OK)
474                 return err;
475
476         return ERROR_OK;
477 }
478
479 static int str7x_write_block(struct flash_bank *bank, uint8_t *buffer,
480                 uint32_t offset, uint32_t count)
481 {
482         struct str7x_flash_bank *str7x_info = bank->driver_priv;
483         struct target *target = bank->target;
484         uint32_t buffer_size = 32768;
485         struct working_area *source;
486         uint32_t address = bank->base + offset;
487         struct reg_param reg_params[6];
488         struct arm_algorithm armv4_5_info;
489         int retval = ERROR_OK;
490
491         /* see contib/loaders/flash/str7x.s for src */
492
493         static const uint32_t str7x_flash_write_code[] = {
494                                         /* write:                               */
495                 0xe3a04201, /*  mov r4, #0x10000000     */
496                 0xe5824000, /*  str r4, [r2, #0x0]      */
497                 0xe5821010, /*  str r1, [r2, #0x10]     */
498                 0xe4904004, /*  ldr r4, [r0], #4        */
499                 0xe5824008, /*  str r4, [r2, #0x8]      */
500                 0xe4904004, /*  ldr r4, [r0], #4        */
501                 0xe582400c, /*  str r4, [r2, #0xc]      */
502                 0xe3a04209, /*  mov r4, #0x90000000     */
503                 0xe5824000, /*  str r4, [r2, #0x0]      */
504                             /* busy:                            */
505                 0xe5924000, /*  ldr r4, [r2, #0x0]      */
506                 0xe1140005,     /*      tst r4, r5                      */
507                 0x1afffffc, /*  bne busy                        */
508                 0xe5924014, /*  ldr r4, [r2, #0x14]     */
509                 0xe31400ff, /*  tst r4, #0xff           */
510                 0x03140c01, /*  tsteq r4, #0x100        */
511                 0x1a000002, /*  bne exit                        */
512                 0xe2811008, /*  add r1, r1, #0x8        */
513                 0xe2533001, /*  subs r3, r3, #1         */
514                 0x1affffec, /*  bne write                       */
515                                         /* exit:                                */
516                 0xeafffffe, /*  b exit                          */
517         };
518
519         /* flash write code */
520         if (target_alloc_working_area_try(target, sizeof(str7x_flash_write_code),
521                         &str7x_info->write_algorithm) != ERROR_OK)
522         {
523                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
524         };
525
526         target_write_buffer(target, str7x_info->write_algorithm->address,
527                         sizeof(str7x_flash_write_code),
528                         (uint8_t*)str7x_flash_write_code);
529
530         /* memory buffer */
531         while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK)
532         {
533                 buffer_size /= 2;
534                 if (buffer_size <= 256)
535                 {
536                         /* if we already allocated the writing code, but failed to get a
537                          * buffer, free the algorithm */
538                         if (str7x_info->write_algorithm)
539                                 target_free_working_area(target, str7x_info->write_algorithm);
540
541                         LOG_WARNING("no large enough working area available, can't do block memory writes");
542                         return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
543                 }
544         }
545
546         armv4_5_info.common_magic = ARM_COMMON_MAGIC;
547         armv4_5_info.core_mode = ARM_MODE_SVC;
548         armv4_5_info.core_state = ARM_STATE_ARM;
549
550         init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
551         init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
552         init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
553         init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
554         init_reg_param(&reg_params[4], "r4", 32, PARAM_IN);
555         init_reg_param(&reg_params[5], "r5", 32, PARAM_OUT);
556
557         while (count > 0)
558         {
559                 uint32_t thisrun_count = (count > (buffer_size / 8)) ? (buffer_size / 8) : count;
560
561                 target_write_buffer(target, source->address, thisrun_count * 8, buffer);
562
563                 buf_set_u32(reg_params[0].value, 0, 32, source->address);
564                 buf_set_u32(reg_params[1].value, 0, 32, address);
565                 buf_set_u32(reg_params[2].value, 0, 32, str7x_get_flash_adr(bank, FLASH_CR0));
566                 buf_set_u32(reg_params[3].value, 0, 32, thisrun_count);
567                 buf_set_u32(reg_params[5].value, 0, 32, str7x_info->busy_bits);
568
569                 if ((retval = target_run_algorithm(target, 0, NULL, 6, reg_params,
570                                 str7x_info->write_algorithm->address,
571                                 str7x_info->write_algorithm->address + (sizeof(str7x_flash_write_code) - 4),
572                                 10000, &armv4_5_info)) != ERROR_OK)
573                 {
574                         break;
575                 }
576
577                 if (buf_get_u32(reg_params[4].value, 0, 32) != 0x00)
578                 {
579                         retval = str7x_result(bank);
580                         break;
581                 }
582
583                 buffer += thisrun_count * 8;
584                 address += thisrun_count * 8;
585                 count -= thisrun_count;
586         }
587
588         target_free_working_area(target, source);
589         target_free_working_area(target, str7x_info->write_algorithm);
590
591         destroy_reg_param(&reg_params[0]);
592         destroy_reg_param(&reg_params[1]);
593         destroy_reg_param(&reg_params[2]);
594         destroy_reg_param(&reg_params[3]);
595         destroy_reg_param(&reg_params[4]);
596         destroy_reg_param(&reg_params[5]);
597
598         return retval;
599 }
600
601 static int str7x_write(struct flash_bank *bank, uint8_t *buffer,
602                 uint32_t offset, uint32_t count)
603 {
604         struct target *target = bank->target;
605         uint32_t dwords_remaining = (count / 8);
606         uint32_t bytes_remaining = (count & 0x00000007);
607         uint32_t address = bank->base + offset;
608         uint32_t bytes_written = 0;
609         uint32_t cmd;
610         int retval;
611         uint32_t check_address = offset;
612         int i;
613
614         if (bank->target->state != TARGET_HALTED)
615         {
616                 LOG_ERROR("Target not halted");
617                 return ERROR_TARGET_NOT_HALTED;
618         }
619
620         if (offset & 0x7)
621         {
622                 LOG_WARNING("offset 0x%" PRIx32 " breaks required 8-byte alignment", offset);
623                 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
624         }
625
626         for (i = 0; i < bank->num_sectors; i++)
627         {
628                 uint32_t sec_start = bank->sectors[i].offset;
629                 uint32_t sec_end = sec_start + bank->sectors[i].size;
630
631                 /* check if destination falls within the current sector */
632                 if ((check_address >= sec_start) && (check_address < sec_end))
633                 {
634                         /* check if destination ends in the current sector */
635                         if (offset + count < sec_end)
636                                 check_address = offset + count;
637                         else
638                                 check_address = sec_end;
639                 }
640         }
641
642         if (check_address != offset + count)
643                 return ERROR_FLASH_DST_OUT_OF_BANK;
644
645         /* clear FLASH_ER register */
646         target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
647
648         /* multiple dwords (8-byte) to be programmed? */
649         if (dwords_remaining > 0)
650         {
651                 /* try using a block write */
652                 if ((retval = str7x_write_block(bank, buffer, offset,
653                                 dwords_remaining)) != ERROR_OK)
654                 {
655                         if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
656                         {
657                                 /* if block write failed (no sufficient working area),
658                                  * we use normal (slow) single dword accesses */
659                                 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
660                         } else
661                         {
662                                 return retval;
663                         }
664                 }
665                 else
666                 {
667                         buffer += dwords_remaining * 8;
668                         address += dwords_remaining * 8;
669                         dwords_remaining = 0;
670                 }
671         }
672
673         while (dwords_remaining > 0)
674         {
675                 /* command */
676                 cmd = FLASH_DWPG;
677                 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
678
679                 /* address */
680                 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);
681
682                 /* data word 1 */
683                 target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0),
684                                 4, 1, buffer + bytes_written);
685                 bytes_written += 4;
686
687                 /* data word 2 */
688                 target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1),
689                                 4, 1, buffer + bytes_written);
690                 bytes_written += 4;
691
692                 /* start programming cycle */
693                 cmd = FLASH_DWPG | FLASH_WMS;
694                 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
695
696                 int err;
697                 err = str7x_waitbusy(bank);
698                 if (err != ERROR_OK)
699                         return err;
700
701                 err = str7x_result(bank);
702                 if (err != ERROR_OK)
703                         return err;
704
705                 dwords_remaining--;
706                 address += 8;
707         }
708
709         if (bytes_remaining)
710         {
711                 uint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
712                 i = 0;
713
714                 while (bytes_remaining > 0)
715                 {
716                         last_dword[i++] = *(buffer + bytes_written);
717                         bytes_remaining--;
718                         bytes_written++;
719                 }
720
721                 /* command */
722                 cmd = FLASH_DWPG;
723                 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
724
725                 /* address */
726                 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);
727
728                 /* data word 1 */
729                 target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0),
730                                 4, 1, last_dword);
731                 bytes_written += 4;
732
733                 /* data word 2 */
734                 target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1),
735                                 4, 1, last_dword + 4);
736                 bytes_written += 4;
737
738                 /* start programming cycle */
739                 cmd = FLASH_DWPG | FLASH_WMS;
740                 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
741
742                 int err;
743                 err = str7x_waitbusy(bank);
744                 if (err != ERROR_OK)
745                         return err;
746
747                 err = str7x_result(bank);
748                 if (err != ERROR_OK)
749                         return err;
750         }
751
752         return ERROR_OK;
753 }
754
755 static int str7x_probe(struct flash_bank *bank)
756 {
757         return ERROR_OK;
758 }
759
760 #if 0
761 COMMAND_HANDLER(str7x_handle_part_id_command)
762 {
763         return ERROR_OK;
764 }
765 #endif
766
767 static int get_str7x_info(struct flash_bank *bank, char *buf, int buf_size)
768 {
769         snprintf(buf, buf_size, "str7x flash driver info");
770         /* STR7x flash doesn't support sector protection interrogation.
771          * FLASH_NVWPAR acts as a write only register; its read value
772          * doesn't reflect the actual protection state of the sectors.
773          */
774         LOG_WARNING("STR7x flash lock information might not be correct "
775                         "due to hardware limitations.");
776         return ERROR_OK;
777 }
778
779 COMMAND_HANDLER(str7x_handle_disable_jtag_command)
780 {
781         struct target *target = NULL;
782         struct str7x_flash_bank *str7x_info = NULL;
783
784         uint32_t flash_cmd;
785         uint16_t ProtectionLevel = 0;
786         uint16_t ProtectionRegs;
787
788         if (CMD_ARGC < 1)
789         {
790                 command_print(CMD_CTX, "str7x disable_jtag <bank>");
791                 return ERROR_OK;
792         }
793
794         struct flash_bank *bank;
795         int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
796         if (ERROR_OK != retval)
797                 return retval;
798
799         str7x_info = bank->driver_priv;
800
801         target = bank->target;
802
803         if (target->state != TARGET_HALTED)
804         {
805                 LOG_ERROR("Target not halted");
806                 return ERROR_TARGET_NOT_HALTED;
807         }
808
809         /* first we get protection status */
810         uint32_t reg;
811         target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR0), &reg);
812
813         if (!(reg & str7x_info->disable_bit))
814         {
815                 ProtectionLevel = 1;
816         }
817
818         target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR1), &reg);
819         ProtectionRegs = ~(reg >> 16);
820
821         while (((ProtectionRegs) != 0) && (ProtectionLevel < 16))
822         {
823                 ProtectionRegs >>= 1;
824                 ProtectionLevel++;
825         }
826
827         if (ProtectionLevel == 0)
828         {
829                 flash_cmd = FLASH_SPR;
830                 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
831                 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFB8);
832                 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), 0xFFFFFFFD);
833                 flash_cmd = FLASH_SPR | FLASH_WMS;
834                 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
835         }
836         else
837         {
838                 flash_cmd = FLASH_SPR;
839                 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
840                 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFBC);
841                 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0),
842                                 ~(1 << (15 + ProtectionLevel)));
843                 flash_cmd = FLASH_SPR | FLASH_WMS;
844                 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
845         }
846
847         return ERROR_OK;
848 }
849
850 static const struct command_registration str7x_exec_command_handlers[] = {
851         {
852                 .name = "disable_jtag",
853                 .handler = str7x_handle_disable_jtag_command,
854                 .mode = COMMAND_EXEC,
855                 .help = "disable jtag access",
856         },
857         COMMAND_REGISTRATION_DONE
858 };
859
860 static const struct command_registration str7x_command_handlers[] = {
861         {
862                 .name = "str7x",
863                 .mode = COMMAND_ANY,
864                 .help = "str7x flash command group",
865                 .chain = str7x_exec_command_handlers,
866         },
867         COMMAND_REGISTRATION_DONE
868 };
869
870 struct flash_driver str7x_flash = {
871         .name = "str7x",
872         .commands = str7x_command_handlers,
873         .flash_bank_command = str7x_flash_bank_command,
874         .erase = str7x_erase,
875         .protect = str7x_protect,
876         .write = str7x_write,
877         .read = default_flash_read,
878         .probe = str7x_probe,
879         .auto_probe = str7x_probe,
880         .erase_check = default_flash_blank_check,
881         .protect_check = str7x_protect_check,
882         .info = get_str7x_info,
883 };