flash: format stm32f2x driver defines
[fw/openocd] / src / flash / nor / stm32f2x.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) 2011 Ã˜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
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include "imp.h"
32 #include <helper/binarybuffer.h>
33 #include <target/algorithm.h>
34 #include <target/armv7m.h>
35
36 /* Regarding performance:
37  *
38  * Short story - it might be best to leave the performance at
39  * current levels.
40  *
41  * You may see a jump in speed if you change to using
42  * 32bit words for the block programming.
43  *
44  * Its a shame you cannot use the double word as its
45  * even faster - but you require external VPP for that mode.
46  *
47  * Having said all that 16bit writes give us the widest vdd
48  * operating range, so may be worth adding a note to that effect.
49  *
50  */
51
52 /* Danger!!!! The STM32F1x and STM32F2x series actually have
53  * quite different flash controllers.
54  *
55  * What's more scary is that the names of the registers and their
56  * addresses are the same, but the actual bits and what they do are
57  * can be very different.
58  *
59  * To reduce testing complexity and dangers of regressions,
60  * a seperate file is used for stm32fx2x.
61  *
62  * 1mByte part with 4 x 16, 1 x 64, 7 x 128kBytes sectors
63  *
64  * What's the protection page size???
65  *
66  * Tested with STM3220F-EVAL board.
67  *
68  * STM32F21xx series for reference.
69  *
70  * RM0033
71  * http://www.st.com/internet/mcu/product/250192.jsp
72  *
73  * PM0059
74  * www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/
75  * PROGRAMMING_MANUAL/CD00233952.pdf
76  *
77  * STM32F1x series - notice that this code was copy, pasted and knocked
78  * into a stm32f2x driver, so in case something has been converted or
79  * bugs haven't been fixed, here are the original manuals:
80  *
81  * RM0008 - Reference manual
82  *
83  * RM0042, the Flash programming manual for low-, medium- high-density and
84  * connectivity line STM32F10x devices
85  *
86  * PM0068, the Flash programming manual for XL-density STM32F10x devices.
87  *
88  */
89
90 /* Erase time can be as high as 1000ms, 10x this and it's toast... */
91 #define FLASH_ERASE_TIMEOUT 10000
92 #define FLASH_WRITE_TIMEOUT 5
93
94 #define STM32_FLASH_BASE    0x40023c00
95 #define STM32_FLASH_ACR     0x40023c00
96 #define STM32_FLASH_KEYR    0x40023c04
97 #define STM32_FLASH_OPTKEYR 0x40023c08
98 #define STM32_FLASH_SR      0x40023c0C
99 #define STM32_FLASH_CR      0x40023c10
100 #define STM32_FLASH_OPTCR   0x40023c14
101 #define STM32_FLASH_OBR     0x40023c1C
102
103 /* option byte location */
104
105 #define STM32_OB_RDP        0x1FFFF800
106 #define STM32_OB_USER       0x1FFFF802
107 #define STM32_OB_DATA0      0x1FFFF804
108 #define STM32_OB_DATA1      0x1FFFF806
109 #define STM32_OB_WRP0       0x1FFFF808
110 #define STM32_OB_WRP1       0x1FFFF80A
111 #define STM32_OB_WRP2       0x1FFFF80C
112 #define STM32_OB_WRP3       0x1FFFF80E
113
114 /* FLASH_CR register bits */
115
116 #define FLASH_PG       (1 << 0)
117 #define FLASH_SER      (1 << 1)
118 #define FLASH_MER      (1 << 2)
119 #define FLASH_MER1     (1 << 15)
120 #define FLASH_STRT     (1 << 16)
121 #define FLASH_PSIZE_8  (0 << 8)
122 #define FLASH_PSIZE_16 (1 << 8)
123 #define FLASH_PSIZE_32 (2 << 8)
124 #define FLASH_PSIZE_64 (3 << 8)
125 #define FLASH_SNB(a)   ((a) << 3)
126 #define FLASH_LOCK     (1 << 31)
127
128 /* FLASH_SR register bits */
129
130 #define FLASH_BSY      (1 << 16)
131 #define FLASH_PGSERR   (1 << 7) /* Programming sequence error */
132 #define FLASH_PGPERR   (1 << 6) /* Programming parallelism error */
133 #define FLASH_PGAERR   (1 << 5) /* Programming alignment error */
134 #define FLASH_WRPERR   (1 << 4) /* Write protection error */
135 #define FLASH_OPERR    (1 << 1) /* Operation error */
136
137 #define FLASH_ERROR (FLASH_PGSERR | FLASH_PGPERR | FLASH_PGAERR | FLASH_WRPERR | FLASH_OPERR)
138
139 /* STM32_FLASH_OBR bit definitions (reading) */
140
141 #define OPT_ERROR      0
142 #define OPT_READOUT    1
143 #define OPT_RDWDGSW    2
144 #define OPT_RDRSTSTOP  3
145 #define OPT_RDRSTSTDBY 4
146 #define OPT_BFB2       5        /* dual flash bank only */
147
148 /* register unlock keys */
149
150 #define KEY1           0x45670123
151 #define KEY2           0xCDEF89AB
152
153 struct stm32x_flash_bank {
154         int probed;
155 };
156
157 /* flash bank stm32x <base> <size> 0 0 <target#>
158  */
159 FLASH_BANK_COMMAND_HANDLER(stm32x_flash_bank_command)
160 {
161         struct stm32x_flash_bank *stm32x_info;
162
163         if (CMD_ARGC < 6)
164                 return ERROR_COMMAND_SYNTAX_ERROR;
165
166         stm32x_info = malloc(sizeof(struct stm32x_flash_bank));
167         bank->driver_priv = stm32x_info;
168
169         stm32x_info->probed = 0;
170
171         return ERROR_OK;
172 }
173
174 static inline int stm32x_get_flash_reg(struct flash_bank *bank, uint32_t reg)
175 {
176         return reg;
177 }
178
179 static inline int stm32x_get_flash_status(struct flash_bank *bank, uint32_t *status)
180 {
181         struct target *target = bank->target;
182         return target_read_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_SR), status);
183 }
184
185 static int stm32x_wait_status_busy(struct flash_bank *bank, int timeout)
186 {
187         struct target *target = bank->target;
188         uint32_t status;
189         int retval = ERROR_OK;
190
191         /* wait for busy to clear */
192         for (;;) {
193                 retval = stm32x_get_flash_status(bank, &status);
194                 if (retval != ERROR_OK)
195                         return retval;
196                 LOG_DEBUG("status: 0x%" PRIx32 "", status);
197                 if ((status & FLASH_BSY) == 0)
198                         break;
199                 if (timeout-- <= 0) {
200                         LOG_ERROR("timed out waiting for flash");
201                         return ERROR_FAIL;
202                 }
203                 alive_sleep(1);
204         }
205
206
207         if (status & FLASH_WRPERR) {
208                 LOG_ERROR("stm32x device protected");
209                 retval = ERROR_FAIL;
210         }
211
212         /* Clear but report errors */
213         if (status & FLASH_ERROR) {
214                 /* If this operation fails, we ignore it and report the original
215                  * retval
216                  */
217                 target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_SR),
218                                 status & FLASH_ERROR);
219         }
220         return retval;
221 }
222
223 static int stm32x_unlock_reg(struct target *target)
224 {
225         uint32_t ctrl;
226
227         /* first check if not already unlocked
228          * otherwise writing on STM32_FLASH_KEYR will fail
229          */
230         int retval = target_read_u32(target, STM32_FLASH_CR, &ctrl);
231         if (retval != ERROR_OK)
232                 return retval;
233
234         if ((ctrl & FLASH_LOCK) == 0)
235                 return ERROR_OK;
236
237         /* unlock flash registers */
238         retval = target_write_u32(target, STM32_FLASH_KEYR, KEY1);
239         if (retval != ERROR_OK)
240                 return retval;
241
242         retval = target_write_u32(target, STM32_FLASH_KEYR, KEY2);
243         if (retval != ERROR_OK)
244                 return retval;
245
246         retval = target_read_u32(target, STM32_FLASH_CR, &ctrl);
247         if (retval != ERROR_OK)
248                 return retval;
249
250         if (ctrl & FLASH_LOCK) {
251                 LOG_ERROR("flash not unlocked STM32_FLASH_CR: %x", ctrl);
252                 return ERROR_TARGET_FAILURE;
253         }
254
255         return ERROR_OK;
256 }
257
258 static int stm32x_protect_check(struct flash_bank *bank)
259 {
260         return ERROR_OK;
261 }
262
263 static int stm32x_erase(struct flash_bank *bank, int first, int last)
264 {
265         struct target *target = bank->target;
266         int i;
267
268         if (bank->target->state != TARGET_HALTED) {
269                 LOG_ERROR("Target not halted");
270                 return ERROR_TARGET_NOT_HALTED;
271         }
272
273         int retval;
274         retval = stm32x_unlock_reg(target);
275         if (retval != ERROR_OK)
276                 return retval;
277
278         /*
279         Sector Erase
280         To erase a sector, follow the procedure below:
281         1. Check that no Flash memory operation is ongoing by checking the BSY bit in the
282           FLASH_SR register
283         2. Set the SER bit and select the sector (out of the 12 sectors in the main memory block)
284           you wish to erase (SNB) in the FLASH_CR register
285         3. Set the STRT bit in the FLASH_CR register
286         4. Wait for the BSY bit to be cleared
287          */
288
289         for (i = first; i <= last; i++) {
290                 retval = target_write_u32(target,
291                                 stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_SER | FLASH_SNB(i) | FLASH_STRT);
292                 if (retval != ERROR_OK)
293                         return retval;
294
295                 retval = stm32x_wait_status_busy(bank, FLASH_ERASE_TIMEOUT);
296                 if (retval != ERROR_OK)
297                         return retval;
298
299                 bank->sectors[i].is_erased = 1;
300         }
301
302         retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_LOCK);
303         if (retval != ERROR_OK)
304                 return retval;
305
306         return ERROR_OK;
307 }
308
309 static int stm32x_protect(struct flash_bank *bank, int set, int first, int last)
310 {
311         return ERROR_OK;
312 }
313
314 static int stm32x_write_block(struct flash_bank *bank, uint8_t *buffer,
315                 uint32_t offset, uint32_t count)
316 {
317         struct target *target = bank->target;
318         uint32_t buffer_size = 16384;
319         struct working_area *write_algorithm;
320         struct working_area *source;
321         uint32_t address = bank->base + offset;
322         struct reg_param reg_params[5];
323         struct armv7m_algorithm armv7m_info;
324         int retval = ERROR_OK;
325
326         /* see contrib/loaders/flash/stm32f2x.S for src */
327
328         static const uint8_t stm32x_flash_write_code[] = {
329                                                                         /* wait_fifo: */
330                 0xD0, 0xF8, 0x00, 0x80,         /* ldr          r8, [r0, #0] */
331                 0xB8, 0xF1, 0x00, 0x0F,         /* cmp          r8, #0 */
332                 0x1A, 0xD0,                                     /* beq          exit */
333                 0x47, 0x68,                                     /* ldr          r7, [r0, #4] */
334                 0x47, 0x45,                                     /* cmp          r7, r8 */
335                 0xF7, 0xD0,                                     /* beq          wait_fifo */
336
337                 0xDF, 0xF8, 0x30, 0x60,         /* ldr          r6, STM32_PROG16 */
338                 0x26, 0x61,                                     /* str          r6, [r4, #STM32_FLASH_CR_OFFSET] */
339                 0x37, 0xF8, 0x02, 0x6B,         /* ldrh         r6, [r7], #0x02 */
340                 0x22, 0xF8, 0x02, 0x6B,         /* strh         r6, [r2], #0x02 */
341                                                                         /* busy: */
342                 0xE6, 0x68,                                     /* ldr          r6, [r4, #STM32_FLASH_SR_OFFSET] */
343                 0x16, 0xF4, 0x80, 0x3F,         /* tst          r6, #0x10000 */
344                 0xFB, 0xD1,                                     /* bne          busy */
345                 0x16, 0xF0, 0xF0, 0x0F,         /* tst          r6, #0xf0 */
346                 0x07, 0xD1,                                     /* bne          error */
347
348                 0x8F, 0x42,                                     /* cmp          r7, r1 */
349                 0x28, 0xBF,                                     /* it           cs */
350                 0x00, 0xF1, 0x08, 0x07,         /* addcs        r7, r0, #8 */
351                 0x47, 0x60,                                     /* str          r7, [r0, #4] */
352                 0x01, 0x3B,                                     /* subs         r3, r3, #1 */
353                 0x13, 0xB1,                                     /* cbz          r3, exit */
354                 0xE1, 0xE7,                                     /* b            wait_fifo */
355                                                                         /* error: */
356                 0x00, 0x21,                                     /* movs         r1, #0 */
357                 0x41, 0x60,                                     /* str          r1, [r0, #4] */
358                                                                         /* exit: */
359                 0x30, 0x46,                                     /* mov          r0, r6 */
360                 0x00, 0xBE,                                     /* bkpt         #0x00 */
361
362                 /* <STM32_PROG16>: */
363                 0x01, 0x01, 0x00, 0x00,         /* .word        0x00000101 */
364         };
365
366         if (target_alloc_working_area(target, sizeof(stm32x_flash_write_code),
367                         &write_algorithm) != ERROR_OK) {
368                 LOG_WARNING("no working area available, can't do block memory writes");
369                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
370         };
371
372         retval = target_write_buffer(target, write_algorithm->address,
373                         sizeof(stm32x_flash_write_code),
374                         (uint8_t *)stm32x_flash_write_code);
375         if (retval != ERROR_OK)
376                 return retval;
377
378         /* memory buffer */
379         while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {
380                 buffer_size /= 2;
381                 if (buffer_size <= 256) {
382                         /* we already allocated the writing code, but failed to get a
383                          * buffer, free the algorithm */
384                         target_free_working_area(target, write_algorithm);
385
386                         LOG_WARNING("no large enough working area available, can't do block memory writes");
387                         return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
388                 }
389         };
390
391         armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
392         armv7m_info.core_mode = ARMV7M_MODE_ANY;
393
394         init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);         /* buffer start, status (out) */
395         init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);            /* buffer end */
396         init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);            /* target address */
397         init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);            /* count (halfword-16bit) */
398         init_reg_param(&reg_params[4], "r4", 32, PARAM_OUT);            /* flash base */
399
400         buf_set_u32(reg_params[0].value, 0, 32, source->address);
401         buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size);
402         buf_set_u32(reg_params[2].value, 0, 32, address);
403         buf_set_u32(reg_params[3].value, 0, 32, count);
404         buf_set_u32(reg_params[4].value, 0, 32, STM32_FLASH_BASE);
405
406         retval = target_run_flash_async_algorithm(target, buffer, count, 2,
407                         0, NULL,
408                         5, reg_params,
409                         source->address, source->size,
410                         write_algorithm->address, 0,
411                         &armv7m_info);
412
413         if (retval == ERROR_FLASH_OPERATION_FAILED) {
414                 LOG_ERROR("error executing stm32x flash write algorithm");
415
416                 uint32_t error = buf_get_u32(reg_params[0].value, 0, 32) & FLASH_ERROR;
417
418                 if (error & FLASH_WRPERR)
419                         LOG_ERROR("flash memory write protected");
420
421                 if (error != 0) {
422                         LOG_ERROR("flash write failed = %08x", error);
423                         /* Clear but report errors */
424                         target_write_u32(target, STM32_FLASH_SR, error);
425                         retval = ERROR_FAIL;
426                 }
427         }
428
429         target_free_working_area(target, source);
430         target_free_working_area(target, write_algorithm);
431
432         destroy_reg_param(&reg_params[0]);
433         destroy_reg_param(&reg_params[1]);
434         destroy_reg_param(&reg_params[2]);
435         destroy_reg_param(&reg_params[3]);
436         destroy_reg_param(&reg_params[4]);
437
438         return retval;
439 }
440
441 static int stm32x_write(struct flash_bank *bank, uint8_t *buffer,
442                 uint32_t offset, uint32_t count)
443 {
444         struct target *target = bank->target;
445         uint32_t words_remaining = (count / 2);
446         uint32_t bytes_remaining = (count & 0x00000001);
447         uint32_t address = bank->base + offset;
448         uint32_t bytes_written = 0;
449         int retval;
450
451         if (bank->target->state != TARGET_HALTED) {
452                 LOG_ERROR("Target not halted");
453                 return ERROR_TARGET_NOT_HALTED;
454         }
455
456         if (offset & 0x1) {
457                 LOG_WARNING("offset 0x%" PRIx32 " breaks required 2-byte alignment", offset);
458                 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
459         }
460
461         retval = stm32x_unlock_reg(target);
462         if (retval != ERROR_OK)
463                 return retval;
464
465         /* multiple half words (2-byte) to be programmed? */
466         if (words_remaining > 0) {
467                 /* try using a block write */
468                 retval = stm32x_write_block(bank, buffer, offset, words_remaining);
469                 if (retval != ERROR_OK) {
470                         if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
471                                 /* if block write failed (no sufficient working area),
472                                  * we use normal (slow) single dword accesses */
473                                 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
474                         }
475                 } else {
476                         buffer += words_remaining * 2;
477                         address += words_remaining * 2;
478                         words_remaining = 0;
479                 }
480         }
481
482         if ((retval != ERROR_OK) && (retval != ERROR_TARGET_RESOURCE_NOT_AVAILABLE))
483                 return retval;
484
485         /*
486         Standard programming
487         The Flash memory programming sequence is as follows:
488         1. Check that no main Flash memory operation is ongoing by checking the BSY bit in the
489           FLASH_SR register.
490         2. Set the PG bit in the FLASH_CR register
491         3. Perform the data write operation(s) to the desired memory address (inside main
492           memory block or OTP area):
493         â€“ â€“ Half-word access in case of x16 parallelism
494         â€“ Word access in case of x32 parallelism
495         â€“
496         4.
497         Byte access in case of x8 parallelism
498         Double word access in case of x64 parallelism
499         Wait for the BSY bit to be cleared
500         */
501         while (words_remaining > 0) {
502                 uint16_t value;
503                 memcpy(&value, buffer + bytes_written, sizeof(uint16_t));
504
505                 retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR),
506                                 FLASH_PG | FLASH_PSIZE_16);
507                 if (retval != ERROR_OK)
508                         return retval;
509
510                 retval = target_write_u16(target, address, value);
511                 if (retval != ERROR_OK)
512                         return retval;
513
514                 retval = stm32x_wait_status_busy(bank, FLASH_WRITE_TIMEOUT);
515                 if (retval != ERROR_OK)
516                         return retval;
517
518                 bytes_written += 2;
519                 words_remaining--;
520                 address += 2;
521         }
522
523         if (bytes_remaining) {
524                 retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR),
525                                 FLASH_PG | FLASH_PSIZE_8);
526                 if (retval != ERROR_OK)
527                         return retval;
528                 retval = target_write_u8(target, address, buffer[bytes_written]);
529                 if (retval != ERROR_OK)
530                         return retval;
531
532                 retval = stm32x_wait_status_busy(bank, FLASH_WRITE_TIMEOUT);
533                 if (retval != ERROR_OK)
534                         return retval;
535         }
536
537         return target_write_u32(target, STM32_FLASH_CR, FLASH_LOCK);
538 }
539
540 static void setup_sector(struct flash_bank *bank, int start, int num, int size)
541 {
542         for (int i = start; i < (start + num) ; i++) {
543                 bank->sectors[i].offset = bank->size;
544                 bank->sectors[i].size = size;
545                 bank->size += bank->sectors[i].size;
546         }
547 }
548
549 static int stm32x_get_device_id(struct flash_bank *bank, uint32_t *device_id)
550 {
551         /* this checks for a stm32f4x errata issue where a
552          * stm32f2x DBGMCU_IDCODE is incorrectly returned.
553          * If the issue is detected target is forced to stm32f4x Rev A.
554          * Only effects Rev A silicon */
555
556         struct target *target = bank->target;
557         uint32_t cpuid;
558
559         /* read stm32 device id register */
560         int retval = target_read_u32(target, 0xE0042000, device_id);
561         if (retval != ERROR_OK)
562                 return retval;
563
564         if ((*device_id & 0xfff) == 0x411) {
565                 /* read CPUID reg to check core type */
566                 retval = target_read_u32(target, 0xE000ED00, &cpuid);
567                 if (retval != ERROR_OK)
568                         return retval;
569
570                 /* check for cortex_m4 */
571                 if (((cpuid >> 4) & 0xFFF) == 0xC24) {
572                         *device_id &= ~((0xFFFF << 16) | 0xfff);
573                         *device_id |= (0x1000 << 16) | 0x413;
574                         LOG_INFO("stm32f4x errata detected - fixing incorrect MCU_IDCODE");
575                 }
576         }
577         return retval;
578 }
579
580 static int stm32x_probe(struct flash_bank *bank)
581 {
582         struct target *target = bank->target;
583         struct stm32x_flash_bank *stm32x_info = bank->driver_priv;
584         int i;
585         uint16_t flash_size_in_kb;
586         uint16_t max_flash_size_in_kb;
587         uint32_t device_id;
588         uint32_t base_address = 0x08000000;
589
590         stm32x_info->probed = 0;
591
592         /* read stm32 device id register */
593         int retval = stm32x_get_device_id(bank, &device_id);
594         if (retval != ERROR_OK)
595                 return retval;
596         LOG_INFO("device id = 0x%08" PRIx32 "", device_id);
597
598         /* set max flash size depending on family */
599         switch (device_id & 0xfff) {
600         case 0x411:
601         case 0x413:
602                 max_flash_size_in_kb = 1024;
603                 break;
604         case 0x419:
605                 max_flash_size_in_kb = 2048;
606                 break;
607         default:
608                 LOG_WARNING("Cannot identify target as a STM32 family.");
609                 return ERROR_FAIL;
610         }
611
612         /* get flash size from target. */
613         retval = target_read_u16(target, 0x1FFF7A22, &flash_size_in_kb);
614
615         /* failed reading flash size or flash size invalid (early silicon),
616          * default to max target family */
617         if (retval != ERROR_OK || flash_size_in_kb == 0xffff || flash_size_in_kb == 0) {
618                 LOG_WARNING("STM32 flash size failed, probe inaccurate - assuming %dk flash",
619                         max_flash_size_in_kb);
620                 flash_size_in_kb = max_flash_size_in_kb;
621         }
622
623         LOG_INFO("flash size = %dkbytes", flash_size_in_kb);
624
625         /* did we assign flash size? */
626         assert(flash_size_in_kb != 0xffff);
627
628         /* calculate numbers of pages */
629         int num_pages = (flash_size_in_kb / 128) + 4;
630
631         /* check for larger 2048 bytes devices */
632         if (flash_size_in_kb > 1024)
633                 num_pages += 4;
634
635         /* check that calculation result makes sense */
636         assert(num_pages > 0);
637
638         if (bank->sectors) {
639                 free(bank->sectors);
640                 bank->sectors = NULL;
641         }
642
643         bank->base = base_address;
644         bank->num_sectors = num_pages;
645         bank->sectors = malloc(sizeof(struct flash_sector) * num_pages);
646         bank->size = 0;
647
648         /* fixed memory */
649         setup_sector(bank, 0, 4, 16 * 1024);
650         setup_sector(bank, 4, 1, 64 * 1024);
651
652         /* dynamic memory */
653         setup_sector(bank, 4 + 1, MAX(12, num_pages) - 5, 128 * 1024);
654
655         if (num_pages > 12) {
656
657                 /* fixed memory for larger devices */
658                 setup_sector(bank, 12, 4, 16 * 1024);
659                 setup_sector(bank, 16, 1, 64 * 1024);
660
661                 /* dynamic memory for larger devices */
662                 setup_sector(bank, 16 + 1, num_pages - 5 - 12, 128 * 1024);
663         }
664
665         for (i = 0; i < num_pages; i++) {
666                 bank->sectors[i].is_erased = -1;
667                 bank->sectors[i].is_protected = 0;
668         }
669
670         stm32x_info->probed = 1;
671
672         return ERROR_OK;
673 }
674
675 static int stm32x_auto_probe(struct flash_bank *bank)
676 {
677         struct stm32x_flash_bank *stm32x_info = bank->driver_priv;
678         if (stm32x_info->probed)
679                 return ERROR_OK;
680         return stm32x_probe(bank);
681 }
682
683 static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size)
684 {
685         uint32_t device_id;
686         int printed;
687
688         /* read stm32 device id register */
689         int retval = stm32x_get_device_id(bank, &device_id);
690         if (retval != ERROR_OK)
691                 return retval;
692
693         if ((device_id & 0xfff) == 0x411) {
694                 printed = snprintf(buf, buf_size, "stm32f2x - Rev: ");
695                 buf += printed;
696                 buf_size -= printed;
697
698                 switch (device_id >> 16) {
699                         case 0x1000:
700                                 snprintf(buf, buf_size, "A");
701                                 break;
702
703                         case 0x2000:
704                                 snprintf(buf, buf_size, "B");
705                                 break;
706
707                         case 0x1001:
708                                 snprintf(buf, buf_size, "Z");
709                                 break;
710
711                         case 0x2001:
712                                 snprintf(buf, buf_size, "Y");
713                                 break;
714
715                         case 0x2003:
716                                 snprintf(buf, buf_size, "X");
717                                 break;
718
719                         default:
720                                 snprintf(buf, buf_size, "unknown");
721                                 break;
722                 }
723         } else if (((device_id & 0xfff) == 0x413) ||
724                         ((device_id & 0xfff) == 0x419)) {
725                 printed = snprintf(buf, buf_size, "stm32f4x - Rev: ");
726                 buf += printed;
727                 buf_size -= printed;
728
729                 switch (device_id >> 16) {
730                         case 0x1000:
731                                 snprintf(buf, buf_size, "A");
732                                 break;
733
734                         case 0x1001:
735                                 snprintf(buf, buf_size, "Z");
736                                 break;
737
738                         default:
739                                 snprintf(buf, buf_size, "unknown");
740                                 break;
741                 }
742         } else {
743                 snprintf(buf, buf_size, "Cannot identify target as a stm32x\n");
744                 return ERROR_FAIL;
745         }
746
747         return ERROR_OK;
748 }
749
750 static int stm32x_mass_erase(struct flash_bank *bank)
751 {
752         int retval;
753         struct target *target = bank->target;
754
755         if (target->state != TARGET_HALTED) {
756                 LOG_ERROR("Target not halted");
757                 return ERROR_TARGET_NOT_HALTED;
758         }
759
760         retval = stm32x_unlock_reg(target);
761         if (retval != ERROR_OK)
762                 return retval;
763
764         /* mass erase flash memory */
765         if (bank->num_sectors > 12)
766                 retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_MER | FLASH_MER1);
767         else
768                 retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_MER);
769         if (retval != ERROR_OK)
770                 return retval;
771         retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR),
772                 FLASH_MER | FLASH_STRT);
773         if (retval != ERROR_OK)
774                 return retval;
775
776         retval = stm32x_wait_status_busy(bank, 30000);
777         if (retval != ERROR_OK)
778                 return retval;
779
780         retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_LOCK);
781         if (retval != ERROR_OK)
782                 return retval;
783
784         return ERROR_OK;
785 }
786
787 COMMAND_HANDLER(stm32x_handle_mass_erase_command)
788 {
789         int i;
790
791         if (CMD_ARGC < 1) {
792                 command_print(CMD_CTX, "stm32x mass_erase <bank>");
793                 return ERROR_COMMAND_SYNTAX_ERROR;
794         }
795
796         struct flash_bank *bank;
797         int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
798         if (ERROR_OK != retval)
799                 return retval;
800
801         retval = stm32x_mass_erase(bank);
802         if (retval == ERROR_OK) {
803                 /* set all sectors as erased */
804                 for (i = 0; i < bank->num_sectors; i++)
805                         bank->sectors[i].is_erased = 1;
806
807                 command_print(CMD_CTX, "stm32x mass erase complete");
808         } else {
809                 command_print(CMD_CTX, "stm32x mass erase failed");
810         }
811
812         return retval;
813 }
814
815 static const struct command_registration stm32x_exec_command_handlers[] = {
816         {
817                 .name = "mass_erase",
818                 .handler = stm32x_handle_mass_erase_command,
819                 .mode = COMMAND_EXEC,
820                 .usage = "bank_id",
821                 .help = "Erase entire flash device.",
822         },
823         COMMAND_REGISTRATION_DONE
824 };
825
826 static const struct command_registration stm32x_command_handlers[] = {
827         {
828                 .name = "stm32f2x",
829                 .mode = COMMAND_ANY,
830                 .help = "stm32f2x flash command group",
831                 .usage = "",
832                 .chain = stm32x_exec_command_handlers,
833         },
834         COMMAND_REGISTRATION_DONE
835 };
836
837 struct flash_driver stm32f2x_flash = {
838         .name = "stm32f2x",
839         .commands = stm32x_command_handlers,
840         .flash_bank_command = stm32x_flash_bank_command,
841         .erase = stm32x_erase,
842         .protect = stm32x_protect,
843         .write = stm32x_write,
844         .read = default_flash_read,
845         .probe = stm32x_probe,
846         .auto_probe = stm32x_auto_probe,
847         .erase_check = default_flash_blank_check,
848         .protect_check = stm32x_protect_check,
849         .info = get_stm32x_info,
850 };