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