target_t -> struct target
[fw/openocd] / src / flash / 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  *   This program is free software; you can redistribute it and/or modify  *
9  *   it under the terms of the GNU General Public License as published by  *
10  *   the Free Software Foundation; either version 2 of the License, or     *
11  *   (at your option) any later version.                                   *
12  *                                                                         *
13  *   This program is distributed in the hope that it will be useful,       *
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
16  *   GNU General Public License for more details.                          *
17  *                                                                         *
18  *   You should have received a copy of the GNU General Public License     *
19  *   along with this program; if not, write to the                         *
20  *   Free Software Foundation, Inc.,                                       *
21  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
22  ***************************************************************************/
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "str7x.h"
28 #include "armv4_5.h"
29 #include "binarybuffer.h"
30
31
32 struct str7x_mem_layout mem_layout_str7bank0[] = {
33         {0x00000000, 0x02000, 0x01},
34         {0x00002000, 0x02000, 0x02},
35         {0x00004000, 0x02000, 0x04},
36         {0x00006000, 0x02000, 0x08},
37         {0x00008000, 0x08000, 0x10},
38         {0x00010000, 0x10000, 0x20},
39         {0x00020000, 0x10000, 0x40},
40         {0x00030000, 0x10000, 0x80}
41 };
42
43 struct str7x_mem_layout mem_layout_str7bank1[] = {
44         {0x00000000, 0x02000, 0x10000},
45         {0x00002000, 0x02000, 0x20000}
46 };
47
48 static int str7x_get_flash_adr(struct flash_bank_s *bank, uint32_t reg)
49 {
50         struct str7x_flash_bank *str7x_info = bank->driver_priv;
51         return (str7x_info->register_base | reg);
52 }
53
54 static int str7x_build_block_list(struct flash_bank_s *bank)
55 {
56         struct str7x_flash_bank *str7x_info = bank->driver_priv;
57
58         int i;
59         int num_sectors;
60         int b0_sectors = 0, b1_sectors = 0;
61
62         switch (bank->size)
63         {
64                 case 16 * 1024:
65                         b1_sectors = 2;
66                         break;
67                 case 64 * 1024:
68                         b0_sectors = 5;
69                         break;
70                 case 128 * 1024:
71                         b0_sectors = 6;
72                         break;
73                 case 256 * 1024:
74                         b0_sectors = 8;
75                         break;
76                 default:
77                         LOG_ERROR("BUG: unknown bank->size encountered");
78                         exit(-1);
79         }
80
81         num_sectors = b0_sectors + b1_sectors;
82
83         bank->num_sectors = num_sectors;
84         bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);
85         str7x_info->sector_bits = malloc(sizeof(uint32_t) * num_sectors);
86
87         num_sectors = 0;
88
89         for (i = 0; i < b0_sectors; i++)
90         {
91                 bank->sectors[num_sectors].offset = mem_layout_str7bank0[i].sector_start;
92                 bank->sectors[num_sectors].size = mem_layout_str7bank0[i].sector_size;
93                 bank->sectors[num_sectors].is_erased = -1;
94                 bank->sectors[num_sectors].is_protected = 1;
95                 str7x_info->sector_bits[num_sectors++] = mem_layout_str7bank0[i].sector_bit;
96         }
97
98         for (i = 0; i < b1_sectors; i++)
99         {
100                 bank->sectors[num_sectors].offset = mem_layout_str7bank1[i].sector_start;
101                 bank->sectors[num_sectors].size = mem_layout_str7bank1[i].sector_size;
102                 bank->sectors[num_sectors].is_erased = -1;
103                 bank->sectors[num_sectors].is_protected = 1;
104                 str7x_info->sector_bits[num_sectors++] = mem_layout_str7bank1[i].sector_bit;
105         }
106
107         return ERROR_OK;
108 }
109
110 /* flash bank str7x <base> <size> 0 0 <target#> <str71_variant>
111  */
112 FLASH_BANK_COMMAND_HANDLER(str7x_flash_bank_command)
113 {
114         struct str7x_flash_bank *str7x_info;
115
116         if (argc < 7)
117         {
118                 LOG_WARNING("incomplete flash_bank str7x configuration");
119                 return ERROR_FLASH_BANK_INVALID;
120         }
121
122         str7x_info = malloc(sizeof(struct str7x_flash_bank));
123         bank->driver_priv = str7x_info;
124
125         /* set default bits for str71x flash */
126         str7x_info->busy_bits = (FLASH_LOCK | FLASH_BSYA1 | FLASH_BSYA0);
127         str7x_info->disable_bit = (1 << 1);
128
129         if (strcmp(args[6], "STR71x") == 0)
130         {
131                 str7x_info->register_base = 0x40100000;
132         }
133         else if (strcmp(args[6], "STR73x") == 0)
134         {
135                 str7x_info->register_base = 0x80100000;
136                 str7x_info->busy_bits = (FLASH_LOCK | FLASH_BSYA0);
137         }
138         else if (strcmp(args[6], "STR75x") == 0)
139         {
140                 str7x_info->register_base = 0x20100000;
141                 str7x_info->disable_bit = (1 << 0);
142         }
143         else
144         {
145                 LOG_ERROR("unknown STR7x variant: '%s'", args[6]);
146                 free(str7x_info);
147                 return ERROR_FLASH_BANK_INVALID;
148         }
149
150         str7x_build_block_list(bank);
151
152         str7x_info->write_algorithm = NULL;
153
154         return ERROR_OK;
155 }
156
157 static uint32_t str7x_status(struct flash_bank_s *bank)
158 {
159         struct target *target = bank->target;
160         uint32_t retval;
161
162         target_read_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), &retval);
163
164         return retval;
165 }
166
167 static uint32_t str7x_result(struct flash_bank_s *bank)
168 {
169         struct target *target = bank->target;
170         uint32_t retval;
171
172         target_read_u32(target, str7x_get_flash_adr(bank, FLASH_ER), &retval);
173
174         return retval;
175 }
176
177 static int str7x_protect_check(struct flash_bank_s *bank)
178 {
179         struct str7x_flash_bank *str7x_info = bank->driver_priv;
180         struct target *target = bank->target;
181
182         int i;
183         uint32_t retval;
184
185         if (bank->target->state != TARGET_HALTED)
186         {
187                 LOG_ERROR("Target not halted");
188                 return ERROR_TARGET_NOT_HALTED;
189         }
190
191         target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVWPAR), &retval);
192
193         for (i = 0; i < bank->num_sectors; i++)
194         {
195                 if (retval & str7x_info->sector_bits[i])
196                         bank->sectors[i].is_protected = 0;
197                 else
198                         bank->sectors[i].is_protected = 1;
199         }
200
201         return ERROR_OK;
202 }
203
204 static int str7x_erase(struct flash_bank_s *bank, int first, int last)
205 {
206         struct str7x_flash_bank *str7x_info = bank->driver_priv;
207         struct target *target = bank->target;
208
209         int i;
210         uint32_t cmd;
211         uint32_t retval;
212         uint32_t sectors = 0;
213
214         if (bank->target->state != TARGET_HALTED)
215         {
216                 LOG_ERROR("Target not halted");
217                 return ERROR_TARGET_NOT_HALTED;
218         }
219
220         for (i = first; i <= last; i++)
221         {
222                 sectors |= str7x_info->sector_bits[i];
223         }
224
225         LOG_DEBUG("sectors: 0x%" PRIx32 "", sectors);
226
227         /* clear FLASH_ER register */
228         target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
229
230         cmd = FLASH_SER;
231         target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
232
233         cmd = sectors;
234         target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR1), cmd);
235
236         cmd = FLASH_SER | FLASH_WMS;
237         target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
238
239         while (((retval = str7x_status(bank)) & str7x_info->busy_bits)) {
240                 alive_sleep(1);
241         }
242
243         retval = str7x_result(bank);
244
245         if (retval)
246         {
247                 LOG_ERROR("error erasing flash bank, FLASH_ER: 0x%" PRIx32 "", retval);
248                 return ERROR_FLASH_OPERATION_FAILED;
249         }
250
251         for (i = first; i <= last; i++)
252                 bank->sectors[i].is_erased = 1;
253
254         return ERROR_OK;
255 }
256
257 static int str7x_protect(struct flash_bank_s *bank, int set, int first, int last)
258 {
259         struct str7x_flash_bank *str7x_info = bank->driver_priv;
260         struct target *target = bank->target;
261         int i;
262         uint32_t cmd;
263         uint32_t retval;
264         uint32_t protect_blocks;
265
266         if (bank->target->state != TARGET_HALTED)
267         {
268                 LOG_ERROR("Target not halted");
269                 return ERROR_TARGET_NOT_HALTED;
270         }
271
272         protect_blocks = 0xFFFFFFFF;
273
274         if (set)
275         {
276                 for (i = first; i <= last; i++)
277                         protect_blocks &= ~(str7x_info->sector_bits[i]);
278         }
279
280         /* clear FLASH_ER register */
281         target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
282
283         cmd = FLASH_SPR;
284         target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
285
286         cmd = str7x_get_flash_adr(bank, FLASH_NVWPAR);
287         target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), cmd);
288
289         cmd = protect_blocks;
290         target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), cmd);
291
292         cmd = FLASH_SPR | FLASH_WMS;
293         target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
294
295         while (((retval = str7x_status(bank)) & str7x_info->busy_bits)) {
296                 alive_sleep(1);
297         }
298
299         retval = str7x_result(bank);
300
301         LOG_DEBUG("retval: 0x%8.8" PRIx32 "", retval);
302
303         if (retval & FLASH_ERER)
304                 return ERROR_FLASH_SECTOR_NOT_ERASED;
305         else if (retval & FLASH_WPF)
306                 return ERROR_FLASH_OPERATION_FAILED;
307
308         return ERROR_OK;
309 }
310
311 static int str7x_write_block(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
312 {
313         struct str7x_flash_bank *str7x_info = bank->driver_priv;
314         struct target *target = bank->target;
315         uint32_t buffer_size = 8192;
316         struct working_area *source;
317         uint32_t address = bank->base + offset;
318         struct reg_param reg_params[6];
319         struct armv4_5_algorithm armv4_5_info;
320         int retval = ERROR_OK;
321
322         uint32_t str7x_flash_write_code[] = {
323                                         /* write:                               */
324                 0xe3a04201, /*  mov r4, #0x10000000     */
325                 0xe5824000, /*  str r4, [r2, #0x0]      */
326                 0xe5821010, /*  str r1, [r2, #0x10]     */
327                 0xe4904004, /*  ldr r4, [r0], #4        */
328                 0xe5824008, /*  str r4, [r2, #0x8]      */
329                 0xe4904004, /*  ldr r4, [r0], #4        */
330                 0xe582400c, /*  str r4, [r2, #0xc]      */
331                 0xe3a04209, /*  mov r4, #0x90000000     */
332                 0xe5824000, /*  str r4, [r2, #0x0]      */
333                             /* busy:                            */
334                 0xe5924000, /*  ldr r4, [r2, #0x0]      */
335                 0xe1140005,     /*      tst r4, r5                      */
336                 0x1afffffc, /*  bne busy                        */
337                 0xe5924014, /*  ldr r4, [r2, #0x14]     */
338                 0xe31400ff, /*  tst r4, #0xff           */
339                 0x03140c01, /*  tsteq r4, #0x100        */
340                 0x1a000002, /*  bne exit                        */
341                 0xe2811008, /*  add r1, r1, #0x8        */
342                 0xe2533001, /*  subs r3, r3, #1         */
343                 0x1affffec, /*  bne write                       */
344                                         /* exit:                                */
345                 0xeafffffe, /*  b exit                          */
346         };
347
348         /* flash write code */
349         if (target_alloc_working_area(target, 4 * 20, &str7x_info->write_algorithm) != ERROR_OK)
350         {
351                 LOG_WARNING("no working area available, can't do block memory writes");
352                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
353         };
354
355         target_write_buffer(target, str7x_info->write_algorithm->address, 20 * 4, (uint8_t*)str7x_flash_write_code);
356
357         /* memory buffer */
358         while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
359         {
360                 buffer_size /= 2;
361                 if (buffer_size <= 256)
362                 {
363                         /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
364                         if (str7x_info->write_algorithm)
365                                 target_free_working_area(target, str7x_info->write_algorithm);
366
367                         LOG_WARNING("no large enough working area available, can't do block memory writes");
368                         return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
369                 }
370         }
371
372         armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
373         armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
374         armv4_5_info.core_state = ARMV4_5_STATE_ARM;
375
376         init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
377         init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
378         init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
379         init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
380         init_reg_param(&reg_params[4], "r4", 32, PARAM_IN);
381         init_reg_param(&reg_params[5], "r5", 32, PARAM_OUT);
382
383         while (count > 0)
384         {
385                 uint32_t thisrun_count = (count > (buffer_size / 8)) ? (buffer_size / 8) : count;
386
387                 target_write_buffer(target, source->address, thisrun_count * 8, buffer);
388
389                 buf_set_u32(reg_params[0].value, 0, 32, source->address);
390                 buf_set_u32(reg_params[1].value, 0, 32, address);
391                 buf_set_u32(reg_params[2].value, 0, 32, str7x_get_flash_adr(bank, FLASH_CR0));
392                 buf_set_u32(reg_params[3].value, 0, 32, thisrun_count);
393                 buf_set_u32(reg_params[5].value, 0, 32, str7x_info->busy_bits);
394
395                 if ((retval = target_run_algorithm(target, 0, NULL, 6, reg_params, str7x_info->write_algorithm->address, str7x_info->write_algorithm->address + (19 * 4), 10000, &armv4_5_info)) != ERROR_OK)
396                 {
397                         LOG_ERROR("error executing str7x flash write algorithm");
398                         retval = ERROR_FLASH_OPERATION_FAILED;
399                         break;
400                 }
401
402                 if (buf_get_u32(reg_params[4].value, 0, 32) != 0x00)
403                 {
404                         retval = ERROR_FLASH_OPERATION_FAILED;
405                         break;
406                 }
407
408                 buffer += thisrun_count * 8;
409                 address += thisrun_count * 8;
410                 count -= thisrun_count;
411         }
412
413         target_free_working_area(target, source);
414         target_free_working_area(target, str7x_info->write_algorithm);
415
416         destroy_reg_param(&reg_params[0]);
417         destroy_reg_param(&reg_params[1]);
418         destroy_reg_param(&reg_params[2]);
419         destroy_reg_param(&reg_params[3]);
420         destroy_reg_param(&reg_params[4]);
421         destroy_reg_param(&reg_params[5]);
422
423         return retval;
424 }
425
426 static int str7x_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
427 {
428         struct target *target = bank->target;
429         struct str7x_flash_bank *str7x_info = bank->driver_priv;
430         uint32_t dwords_remaining = (count / 8);
431         uint32_t bytes_remaining = (count & 0x00000007);
432         uint32_t address = bank->base + offset;
433         uint32_t bytes_written = 0;
434         uint32_t cmd;
435         int retval;
436         uint32_t check_address = offset;
437         int i;
438
439         if (bank->target->state != TARGET_HALTED)
440         {
441                 LOG_ERROR("Target not halted");
442                 return ERROR_TARGET_NOT_HALTED;
443         }
444
445         if (offset & 0x7)
446         {
447                 LOG_WARNING("offset 0x%" PRIx32 " breaks required 8-byte alignment", offset);
448                 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
449         }
450
451         for (i = 0; i < bank->num_sectors; i++)
452         {
453                 uint32_t sec_start = bank->sectors[i].offset;
454                 uint32_t sec_end = sec_start + bank->sectors[i].size;
455
456                 /* check if destination falls within the current sector */
457                 if ((check_address >= sec_start) && (check_address < sec_end))
458                 {
459                         /* check if destination ends in the current sector */
460                         if (offset + count < sec_end)
461                                 check_address = offset + count;
462                         else
463                                 check_address = sec_end;
464                 }
465         }
466
467         if (check_address != offset + count)
468                 return ERROR_FLASH_DST_OUT_OF_BANK;
469
470         /* clear FLASH_ER register */
471         target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
472
473         /* multiple dwords (8-byte) to be programmed? */
474         if (dwords_remaining > 0)
475         {
476                 /* try using a block write */
477                 if ((retval = str7x_write_block(bank, buffer, offset, dwords_remaining)) != ERROR_OK)
478                 {
479                         if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
480                         {
481                                 /* if block write failed (no sufficient working area),
482                                  * we use normal (slow) single dword accesses */
483                                 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
484                         }
485                         else if (retval == ERROR_FLASH_OPERATION_FAILED)
486                         {
487                                 /* if an error occured, we examine the reason, and quit */
488                                 retval = str7x_result(bank);
489
490                                 LOG_ERROR("flash writing failed with error code: 0x%x", retval);
491                                 return ERROR_FLASH_OPERATION_FAILED;
492                         }
493                 }
494                 else
495                 {
496                         buffer += dwords_remaining * 8;
497                         address += dwords_remaining * 8;
498                         dwords_remaining = 0;
499                 }
500         }
501
502         while (dwords_remaining > 0)
503         {
504                 /* command */
505                 cmd = FLASH_DWPG;
506                 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
507
508                 /* address */
509                 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);
510
511                 /* data word 1 */
512                 target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0), 4, 1, buffer + bytes_written);
513                 bytes_written += 4;
514
515                 /* data word 2 */
516                 target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1), 4, 1, buffer + bytes_written);
517                 bytes_written += 4;
518
519                 /* start programming cycle */
520                 cmd = FLASH_DWPG | FLASH_WMS;
521                 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
522
523                 while (((retval = str7x_status(bank)) & str7x_info->busy_bits))
524                 {
525                         alive_sleep(1);
526                 }
527
528                 retval = str7x_result(bank);
529
530                 if (retval & FLASH_PGER)
531                         return ERROR_FLASH_OPERATION_FAILED;
532                 else if (retval & FLASH_WPF)
533                         return ERROR_FLASH_OPERATION_FAILED;
534
535                 dwords_remaining--;
536                 address += 8;
537         }
538
539         if (bytes_remaining)
540         {
541                 uint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
542                 int i = 0;
543
544                 while (bytes_remaining > 0)
545                 {
546                         last_dword[i++] = *(buffer + bytes_written);
547                         bytes_remaining--;
548                         bytes_written++;
549                 }
550
551                 /* command */
552                 cmd = FLASH_DWPG;
553                 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
554
555                 /* address */
556                 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);
557
558                 /* data word 1 */
559                 target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0), 4, 1, last_dword);
560                 bytes_written += 4;
561
562                 /* data word 2 */
563                 target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1), 4, 1, last_dword + 4);
564                 bytes_written += 4;
565
566                 /* start programming cycle */
567                 cmd = FLASH_DWPG | FLASH_WMS;
568                 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
569
570                 while (((retval = str7x_status(bank)) & str7x_info->busy_bits))
571                 {
572                         alive_sleep(1);
573                 }
574
575                 retval = str7x_result(bank);
576
577                 if (retval & FLASH_PGER)
578                         return ERROR_FLASH_OPERATION_FAILED;
579                 else if (retval & FLASH_WPF)
580                         return ERROR_FLASH_OPERATION_FAILED;
581         }
582
583         return ERROR_OK;
584 }
585
586 static int str7x_probe(struct flash_bank_s *bank)
587 {
588         return ERROR_OK;
589 }
590
591 #if 0
592 COMMAND_HANDLER(str7x_handle_part_id_command)
593 {
594         return ERROR_OK;
595 }
596 #endif
597
598 static int str7x_info(struct flash_bank_s *bank, char *buf, int buf_size)
599 {
600         snprintf(buf, buf_size, "str7x flash driver info");
601         return ERROR_OK;
602 }
603
604 COMMAND_HANDLER(str7x_handle_disable_jtag_command)
605 {
606         struct target *target = NULL;
607         struct str7x_flash_bank *str7x_info = NULL;
608
609         uint32_t flash_cmd;
610         uint16_t ProtectionLevel = 0;
611         uint16_t ProtectionRegs;
612
613         if (argc < 1)
614         {
615                 command_print(cmd_ctx, "str7x disable_jtag <bank>");
616                 return ERROR_OK;
617         }
618
619         flash_bank_t *bank;
620         int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank);
621         if (ERROR_OK != retval)
622                 return retval;
623
624         str7x_info = bank->driver_priv;
625
626         target = bank->target;
627
628         if (target->state != TARGET_HALTED)
629         {
630                 LOG_ERROR("Target not halted");
631                 return ERROR_TARGET_NOT_HALTED;
632         }
633
634         /* first we get protection status */
635         uint32_t reg;
636         target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR0), &reg);
637
638         if (!(reg & str7x_info->disable_bit))
639         {
640                 ProtectionLevel = 1;
641         }
642
643         target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR1), &reg);
644         ProtectionRegs = ~(reg >> 16);
645
646         while (((ProtectionRegs) != 0) && (ProtectionLevel < 16))
647         {
648                 ProtectionRegs >>= 1;
649                 ProtectionLevel++;
650         }
651
652         if (ProtectionLevel == 0)
653         {
654                 flash_cmd = FLASH_SPR;
655                 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
656                 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFB8);
657                 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), 0xFFFFFFFD);
658                 flash_cmd = FLASH_SPR | FLASH_WMS;
659                 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
660         }
661         else
662         {
663                 flash_cmd = FLASH_SPR;
664                 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
665                 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFBC);
666                 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), ~(1 << (15 + ProtectionLevel)));
667                 flash_cmd = FLASH_SPR | FLASH_WMS;
668                 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
669         }
670
671         return ERROR_OK;
672 }
673
674 static int str7x_register_commands(struct command_context_s *cmd_ctx)
675 {
676         command_t *str7x_cmd = register_command(cmd_ctx, NULL, "str7x",
677                         NULL, COMMAND_ANY, "str7x flash specific commands");
678
679         register_command(cmd_ctx, str7x_cmd, "disable_jtag",
680                         str7x_handle_disable_jtag_command, COMMAND_EXEC,
681                         "disable jtag access");
682
683         return ERROR_OK;
684 }
685
686 struct flash_driver str7x_flash = {
687                 .name = "str7x",
688                 .register_commands = &str7x_register_commands,
689                 .flash_bank_command = &str7x_flash_bank_command,
690                 .erase = &str7x_erase,
691                 .protect = &str7x_protect,
692                 .write = &str7x_write,
693                 .probe = &str7x_probe,
694                 .auto_probe = &str7x_probe,
695                 .erase_check = &default_flash_blank_check,
696                 .protect_check = &str7x_protect_check,
697                 .info = &str7x_info,
698         };