]> git.gag.com Git - fw/openocd/blob - src/flash/nor/em357.c
topic: add reset functions for SWD
[fw/openocd] / src / flash / nor / em357.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 by Erik Botö
9  *   erik.boto@pelagicore.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 /* em357 register locations */
37
38 #define EM357_FLASH_ACR         0x40008000
39 #define EM357_FLASH_KEYR        0x40008004
40 #define EM357_FLASH_OPTKEYR     0x40008008
41 #define EM357_FLASH_SR          0x4000800C
42 #define EM357_FLASH_CR          0x40008010
43 #define EM357_FLASH_AR          0x40008014
44 #define EM357_FLASH_OBR         0x4000801C
45 #define EM357_FLASH_WRPR        0x40008020
46
47 #define EM357_FPEC_CLK          0x4000402c
48 /* option byte location */
49
50 #define EM357_OB_RDP            0x08040800
51 #define EM357_OB_WRP0           0x08040808
52 #define EM357_OB_WRP1           0x0804080A
53 #define EM357_OB_WRP2           0x0804080C
54
55 /* FLASH_CR register bits */
56
57 #define FLASH_PG                (1 << 0)
58 #define FLASH_PER               (1 << 1)
59 #define FLASH_MER               (1 << 2)
60 #define FLASH_OPTPG             (1 << 4)
61 #define FLASH_OPTER             (1 << 5)
62 #define FLASH_STRT              (1 << 6)
63 #define FLASH_LOCK              (1 << 7)
64 #define FLASH_OPTWRE    (1 << 9)
65
66 /* FLASH_SR register bits */
67
68 #define FLASH_BSY               (1 << 0)
69 #define FLASH_PGERR             (1 << 2)
70 #define FLASH_WRPRTERR  (1 << 4)
71 #define FLASH_EOP               (1 << 5)
72
73 /* EM357_FLASH_OBR bit definitions (reading) */
74
75 #define OPT_ERROR               0
76 #define OPT_READOUT             1
77
78 /* register unlock keys */
79
80 #define KEY1                    0x45670123
81 #define KEY2                    0xCDEF89AB
82
83 struct em357_options {
84         uint16_t RDP;
85         uint16_t user_options;
86         uint16_t protection[3];
87 };
88
89 struct em357_flash_bank {
90         struct em357_options option_bytes;
91         struct working_area *write_algorithm;
92         int ppage_size;
93         int probed;
94 };
95
96 static int em357_mass_erase(struct flash_bank *bank);
97
98 /* flash bank em357 <base> <size> 0 0 <target#>
99  */
100 FLASH_BANK_COMMAND_HANDLER(em357_flash_bank_command)
101 {
102         struct em357_flash_bank *em357_info;
103
104         if (CMD_ARGC < 6)
105                 return ERROR_COMMAND_SYNTAX_ERROR;
106
107         em357_info = malloc(sizeof(struct em357_flash_bank));
108         bank->driver_priv = em357_info;
109
110         em357_info->write_algorithm = NULL;
111         em357_info->probed = 0;
112
113         return ERROR_OK;
114 }
115
116 static inline int em357_get_flash_status(struct flash_bank *bank, uint32_t *status)
117 {
118         struct target *target = bank->target;
119         return target_read_u32(target, EM357_FLASH_SR, status);
120 }
121
122 static int em357_wait_status_busy(struct flash_bank *bank, int timeout)
123 {
124         struct target *target = bank->target;
125         uint32_t status;
126         int retval = ERROR_OK;
127
128         /* wait for busy to clear */
129         for (;; ) {
130                 retval = em357_get_flash_status(bank, &status);
131                 if (retval != ERROR_OK)
132                         return retval;
133                 LOG_DEBUG("status: 0x%" PRIx32 "", status);
134                 if ((status & FLASH_BSY) == 0)
135                         break;
136                 if (timeout-- <= 0) {
137                         LOG_ERROR("timed out waiting for flash");
138                         return ERROR_FAIL;
139                 }
140                 alive_sleep(1);
141         }
142
143         if (status & FLASH_WRPRTERR) {
144                 LOG_ERROR("em357 device protected");
145                 retval = ERROR_FAIL;
146         }
147
148         if (status & FLASH_PGERR) {
149                 LOG_ERROR("em357 device programming failed");
150                 retval = ERROR_FAIL;
151         }
152
153         /* Clear but report errors */
154         if (status & (FLASH_WRPRTERR | FLASH_PGERR)) {
155                 /* If this operation fails, we ignore it and report the original
156                  * retval
157                  */
158                 target_write_u32(target, EM357_FLASH_SR, FLASH_WRPRTERR | FLASH_PGERR);
159         }
160         return retval;
161 }
162
163 static int em357_read_options(struct flash_bank *bank)
164 {
165         uint32_t optiondata;
166         struct em357_flash_bank *em357_info = NULL;
167         struct target *target = bank->target;
168
169         em357_info = bank->driver_priv;
170
171         /* read current option bytes */
172         int retval = target_read_u32(target, EM357_FLASH_OBR, &optiondata);
173         if (retval != ERROR_OK)
174                 return retval;
175
176         em357_info->option_bytes.user_options = (uint16_t)0xFFFC | ((optiondata >> 2) & 0x03);
177         em357_info->option_bytes.RDP = (optiondata & (1 << OPT_READOUT)) ? 0xFFFF : 0x5AA5;
178
179         if (optiondata & (1 << OPT_READOUT))
180                 LOG_INFO("Device Security Bit Set");
181
182         /* each bit refers to a 4bank protection */
183         retval = target_read_u32(target, EM357_FLASH_WRPR, &optiondata);
184         if (retval != ERROR_OK)
185                 return retval;
186
187         em357_info->option_bytes.protection[0] = (uint16_t)optiondata;
188         em357_info->option_bytes.protection[1] = (uint16_t)(optiondata >> 8);
189         em357_info->option_bytes.protection[2] = (uint16_t)(optiondata >> 16);
190
191         return ERROR_OK;
192 }
193
194 static int em357_erase_options(struct flash_bank *bank)
195 {
196         struct em357_flash_bank *em357_info = NULL;
197         struct target *target = bank->target;
198
199         em357_info = bank->driver_priv;
200
201         /* read current options */
202         em357_read_options(bank);
203
204         /* unlock flash registers */
205         int retval = target_write_u32(target, EM357_FLASH_KEYR, KEY1);
206         if (retval != ERROR_OK)
207                 return retval;
208
209         retval = target_write_u32(target, EM357_FLASH_KEYR, KEY2);
210         if (retval != ERROR_OK)
211                 return retval;
212
213         /* unlock option flash registers */
214         retval = target_write_u32(target, EM357_FLASH_OPTKEYR, KEY1);
215         if (retval != ERROR_OK)
216                 return retval;
217         retval = target_write_u32(target, EM357_FLASH_OPTKEYR, KEY2);
218         if (retval != ERROR_OK)
219                 return retval;
220
221         /* erase option bytes */
222         retval = target_write_u32(target, EM357_FLASH_CR, FLASH_OPTER | FLASH_OPTWRE);
223         if (retval != ERROR_OK)
224                 return retval;
225         retval = target_write_u32(target, EM357_FLASH_CR, FLASH_OPTER | FLASH_STRT | FLASH_OPTWRE);
226         if (retval != ERROR_OK)
227                 return retval;
228
229         retval = em357_wait_status_busy(bank, 10);
230         if (retval != ERROR_OK)
231                 return retval;
232
233         /* clear readout protection and complementary option bytes
234          * this will also force a device unlock if set */
235         em357_info->option_bytes.RDP = 0x5AA5;
236
237         return ERROR_OK;
238 }
239
240 static int em357_write_options(struct flash_bank *bank)
241 {
242         struct em357_flash_bank *em357_info = NULL;
243         struct target *target = bank->target;
244
245         em357_info = bank->driver_priv;
246
247         /* unlock flash registers */
248         int retval = target_write_u32(target, EM357_FLASH_KEYR, KEY1);
249         if (retval != ERROR_OK)
250                 return retval;
251         retval = target_write_u32(target, EM357_FLASH_KEYR, KEY2);
252         if (retval != ERROR_OK)
253                 return retval;
254
255         /* unlock option flash registers */
256         retval = target_write_u32(target, EM357_FLASH_OPTKEYR, KEY1);
257         if (retval != ERROR_OK)
258                 return retval;
259         retval = target_write_u32(target, EM357_FLASH_OPTKEYR, KEY2);
260         if (retval != ERROR_OK)
261                 return retval;
262
263         /* program option bytes */
264         retval = target_write_u32(target, EM357_FLASH_CR, FLASH_OPTPG | FLASH_OPTWRE);
265         if (retval != ERROR_OK)
266                 return retval;
267
268         retval = em357_wait_status_busy(bank, 10);
269         if (retval != ERROR_OK)
270                 return retval;
271
272         /* write protection byte 1 */
273         retval = target_write_u16(target, EM357_OB_WRP0, em357_info->option_bytes.protection[0]);
274         if (retval != ERROR_OK)
275                 return retval;
276
277         retval = em357_wait_status_busy(bank, 10);
278         if (retval != ERROR_OK)
279                 return retval;
280
281         /* write protection byte 2 */
282         retval = target_write_u16(target, EM357_OB_WRP1, em357_info->option_bytes.protection[1]);
283         if (retval != ERROR_OK)
284                 return retval;
285
286         retval = em357_wait_status_busy(bank, 10);
287         if (retval != ERROR_OK)
288                 return retval;
289
290         /* write protection byte 3 */
291         retval = target_write_u16(target, EM357_OB_WRP2, em357_info->option_bytes.protection[2]);
292         if (retval != ERROR_OK)
293                 return retval;
294
295         retval = em357_wait_status_busy(bank, 10);
296         if (retval != ERROR_OK)
297                 return retval;
298
299         /* write readout protection bit */
300         retval = target_write_u16(target, EM357_OB_RDP, em357_info->option_bytes.RDP);
301         if (retval != ERROR_OK)
302                 return retval;
303
304         retval = em357_wait_status_busy(bank, 10);
305         if (retval != ERROR_OK)
306                 return retval;
307
308         retval = target_write_u32(target, EM357_FLASH_CR, FLASH_LOCK);
309         if (retval != ERROR_OK)
310                 return retval;
311
312         return ERROR_OK;
313 }
314
315 static int em357_protect_check(struct flash_bank *bank)
316 {
317         struct target *target = bank->target;
318         struct em357_flash_bank *em357_info = bank->driver_priv;
319
320         uint32_t protection;
321         int i, s;
322         int num_bits;
323         int set;
324
325         if (target->state != TARGET_HALTED) {
326                 LOG_ERROR("Target not halted");
327                 return ERROR_TARGET_NOT_HALTED;
328         }
329
330         /* each bit refers to a 4bank protection (bit 0-23) */
331         int retval = target_read_u32(target, EM357_FLASH_WRPR, &protection);
332         if (retval != ERROR_OK)
333                 return retval;
334
335         /* each protection bit is for 4 * 2K pages */
336         num_bits = (bank->num_sectors / em357_info->ppage_size);
337
338         for (i = 0; i < num_bits; i++) {
339                 set = 1;
340                 if (protection & (1 << i))
341                         set = 0;
342
343                 for (s = 0; s < em357_info->ppage_size; s++)
344                         bank->sectors[(i * em357_info->ppage_size) + s].is_protected = set;
345         }
346
347         return ERROR_OK;
348 }
349
350 static int em357_erase(struct flash_bank *bank, int first, int last)
351 {
352         struct target *target = bank->target;
353         int i;
354
355         if (bank->target->state != TARGET_HALTED) {
356                 LOG_ERROR("Target not halted");
357                 return ERROR_TARGET_NOT_HALTED;
358         }
359
360         if ((first == 0) && (last == (bank->num_sectors - 1)))
361                 return em357_mass_erase(bank);
362
363         /* unlock flash registers */
364         int retval = target_write_u32(target, EM357_FLASH_KEYR, KEY1);
365         if (retval != ERROR_OK)
366                 return retval;
367         retval = target_write_u32(target, EM357_FLASH_KEYR, KEY2);
368         if (retval != ERROR_OK)
369                 return retval;
370
371         for (i = first; i <= last; i++) {
372                 retval = target_write_u32(target, EM357_FLASH_CR, FLASH_PER);
373                 if (retval != ERROR_OK)
374                         return retval;
375                 retval = target_write_u32(target, EM357_FLASH_AR,
376                                 bank->base + bank->sectors[i].offset);
377                 if (retval != ERROR_OK)
378                         return retval;
379                 retval = target_write_u32(target, EM357_FLASH_CR, FLASH_PER | FLASH_STRT);
380                 if (retval != ERROR_OK)
381                         return retval;
382
383                 retval = em357_wait_status_busy(bank, 100);
384                 if (retval != ERROR_OK)
385                         return retval;
386
387                 bank->sectors[i].is_erased = 1;
388         }
389
390         retval = target_write_u32(target, EM357_FLASH_CR, FLASH_LOCK);
391         if (retval != ERROR_OK)
392                 return retval;
393
394         return ERROR_OK;
395 }
396
397 static int em357_protect(struct flash_bank *bank, int set, int first, int last)
398 {
399         struct em357_flash_bank *em357_info = NULL;
400         struct target *target = bank->target;
401         uint16_t prot_reg[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
402         int i, reg, bit;
403         int status;
404         uint32_t protection;
405
406         em357_info = bank->driver_priv;
407
408         if (target->state != TARGET_HALTED) {
409                 LOG_ERROR("Target not halted");
410                 return ERROR_TARGET_NOT_HALTED;
411         }
412
413         if ((first % em357_info->ppage_size) != 0) {
414                 LOG_WARNING("aligned start protect sector to a %d sector boundary",
415                         em357_info->ppage_size);
416                 first = first - (first % em357_info->ppage_size);
417         }
418         if (((last + 1) % em357_info->ppage_size) != 0) {
419                 LOG_WARNING("aligned end protect sector to a %d sector boundary",
420                         em357_info->ppage_size);
421                 last++;
422                 last = last - (last % em357_info->ppage_size);
423                 last--;
424         }
425
426         /* each bit refers to a 4bank protection */
427         int retval = target_read_u32(target, EM357_FLASH_WRPR, &protection);
428         if (retval != ERROR_OK)
429                 return retval;
430
431         prot_reg[0] = (uint16_t)protection;
432         prot_reg[1] = (uint16_t)(protection >> 8);
433         prot_reg[2] = (uint16_t)(protection >> 16);
434
435         for (i = first; i <= last; i++) {
436                 reg = (i / em357_info->ppage_size) / 8;
437                 bit = (i / em357_info->ppage_size) - (reg * 8);
438
439                 LOG_WARNING("reg, bit: %d, %d", reg, bit);
440                 if (set)
441                         prot_reg[reg] &= ~(1 << bit);
442                 else
443                         prot_reg[reg] |= (1 << bit);
444         }
445
446         status = em357_erase_options(bank);
447         if (retval != ERROR_OK)
448                 return status;
449
450         em357_info->option_bytes.protection[0] = prot_reg[0];
451         em357_info->option_bytes.protection[1] = prot_reg[1];
452         em357_info->option_bytes.protection[2] = prot_reg[2];
453
454         return em357_write_options(bank);
455 }
456
457 static int em357_write_block(struct flash_bank *bank, uint8_t *buffer,
458         uint32_t offset, uint32_t count)
459 {
460         struct em357_flash_bank *em357_info = bank->driver_priv;
461         struct target *target = bank->target;
462         uint32_t buffer_size = 16384;
463         struct working_area *source;
464         uint32_t address = bank->base + offset;
465         struct reg_param reg_params[4];
466         struct armv7m_algorithm armv7m_info;
467         int retval = ERROR_OK;
468
469         /* see contib/loaders/flash/stm32x.s for src, the same is used here except for
470          * a modified *_FLASH_BASE */
471
472         static const uint8_t em357_flash_write_code[] = {
473                 /* #define EM357_FLASH_CR_OFFSET        0x10
474                  * #define EM357_FLASH_SR_OFFSET        0x0C
475                  * write: */
476                 0x08, 0x4c,                                     /* ldr  r4, EM357_FLASH_BASE */
477                 0x1c, 0x44,                                     /* add  r4, r3 */
478                 /* write_half_word: */
479                 0x01, 0x23,                                     /* movs r3, #0x01 */
480                 0x23, 0x61,                                     /* str  r3, [r4,
481                                                                  *#EM357_FLASH_CR_OFFSET] */
482                 0x30, 0xf8, 0x02, 0x3b,         /* ldrh r3, [r0], #0x02 */
483                 0x21, 0xf8, 0x02, 0x3b,         /* strh r3, [r1], #0x02 */
484                 /* busy: */
485                 0xe3, 0x68,                                     /* ldr  r3, [r4,
486                                                                  *#EM357_FLASH_SR_OFFSET] */
487                 0x13, 0xf0, 0x01, 0x0f,         /* tst  r3, #0x01 */
488                 0xfb, 0xd0,                                     /* beq  busy */
489                 0x13, 0xf0, 0x14, 0x0f,         /* tst  r3, #0x14 */
490                 0x01, 0xd1,                                     /* bne  exit */
491                 0x01, 0x3a,                                     /* subs r2, r2, #0x01 */
492                 0xf0, 0xd1,                                     /* bne  write_half_word */
493                 /* exit: */
494                 0x00, 0xbe,                                     /* bkpt #0x00 */
495                 0x00, 0x80, 0x00, 0x40,         /* EM357_FLASH_BASE: .word 0x40008000 */
496         };
497
498         /* flash write code */
499         if (target_alloc_working_area(target, sizeof(em357_flash_write_code),
500                         &em357_info->write_algorithm) != ERROR_OK) {
501                 LOG_WARNING("no working area available, can't do block memory writes");
502                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
503         }
504         ;
505
506         retval = target_write_buffer(target, em357_info->write_algorithm->address,
507                         sizeof(em357_flash_write_code), (uint8_t *)em357_flash_write_code);
508         if (retval != ERROR_OK)
509                 return retval;
510
511         /* memory buffer */
512         while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {
513                 buffer_size /= 2;
514                 if (buffer_size <= 256) {
515                         /* if we already allocated the writing code, but failed to get a
516                          * buffer, free the algorithm */
517                         if (em357_info->write_algorithm)
518                                 target_free_working_area(target, em357_info->write_algorithm);
519
520                         LOG_WARNING(
521                                 "no large enough working area available, can't do block memory writes");
522                         return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
523                 }
524         }
525         ;
526
527         armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
528         armv7m_info.core_mode = ARMV7M_MODE_ANY;
529
530         init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
531         init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
532         init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
533         init_reg_param(&reg_params[3], "r3", 32, PARAM_IN_OUT);
534
535         while (count > 0) {
536                 uint32_t thisrun_count = (count > (buffer_size / 2)) ?
537                         (buffer_size / 2) : count;
538
539                 retval = target_write_buffer(target, source->address, thisrun_count * 2, buffer);
540                 if (retval != ERROR_OK)
541                         break;
542
543                 buf_set_u32(reg_params[0].value, 0, 32, source->address);
544                 buf_set_u32(reg_params[1].value, 0, 32, address);
545                 buf_set_u32(reg_params[2].value, 0, 32, thisrun_count);
546                 buf_set_u32(reg_params[3].value, 0, 32, 0);
547
548                 retval = target_run_algorithm(target, 0, NULL, 4, reg_params,
549                                 em357_info->write_algorithm->address, 0, 10000, &armv7m_info);
550                 if (retval != ERROR_OK) {
551                         LOG_ERROR("error executing em357 flash write algorithm");
552                         break;
553                 }
554
555                 if (buf_get_u32(reg_params[3].value, 0, 32) & FLASH_PGERR) {
556                         LOG_ERROR("flash memory not erased before writing");
557                         /* Clear but report errors */
558                         target_write_u32(target, EM357_FLASH_SR, FLASH_PGERR);
559                         retval = ERROR_FAIL;
560                         break;
561                 }
562
563                 if (buf_get_u32(reg_params[3].value, 0, 32) & FLASH_WRPRTERR) {
564                         LOG_ERROR("flash memory write protected");
565                         /* Clear but report errors */
566                         target_write_u32(target, EM357_FLASH_SR, FLASH_WRPRTERR);
567                         retval = ERROR_FAIL;
568                         break;
569                 }
570
571                 buffer += thisrun_count * 2;
572                 address += thisrun_count * 2;
573                 count -= thisrun_count;
574         }
575
576         target_free_working_area(target, source);
577         target_free_working_area(target, em357_info->write_algorithm);
578
579         destroy_reg_param(&reg_params[0]);
580         destroy_reg_param(&reg_params[1]);
581         destroy_reg_param(&reg_params[2]);
582         destroy_reg_param(&reg_params[3]);
583
584         return retval;
585 }
586
587 static int em357_write(struct flash_bank *bank, uint8_t *buffer,
588         uint32_t offset, uint32_t count)
589 {
590         struct target *target = bank->target;
591         uint32_t words_remaining = (count / 2);
592         uint32_t bytes_remaining = (count & 0x00000001);
593         uint32_t address = bank->base + offset;
594         uint32_t bytes_written = 0;
595         int retval;
596
597         if (bank->target->state != TARGET_HALTED) {
598                 LOG_ERROR("Target not halted");
599                 return ERROR_TARGET_NOT_HALTED;
600         }
601
602         if (offset & 0x1) {
603                 LOG_WARNING("offset 0x%" PRIx32 " breaks required 2-byte alignment", offset);
604                 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
605         }
606
607         /* unlock flash registers */
608         retval = target_write_u32(target, EM357_FLASH_KEYR, KEY1);
609         if (retval != ERROR_OK)
610                 return retval;
611         retval = target_write_u32(target, EM357_FLASH_KEYR, KEY2);
612         if (retval != ERROR_OK)
613                 return retval;
614
615         /* multiple half words (2-byte) to be programmed? */
616         if (words_remaining > 0) {
617                 /* try using a block write */
618                 retval = em357_write_block(bank, buffer, offset, words_remaining);
619                 if (retval != ERROR_OK) {
620                         if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
621                                 /* if block write failed (no sufficient working area),
622                                  * we use normal (slow) single dword accesses */
623                                 LOG_WARNING(
624                                         "couldn't use block writes, falling back to single memory accesses");
625                         }
626                 } else {
627                         buffer += words_remaining * 2;
628                         address += words_remaining * 2;
629                         words_remaining = 0;
630                 }
631         }
632
633         if ((retval != ERROR_OK) && (retval != ERROR_TARGET_RESOURCE_NOT_AVAILABLE))
634                 return retval;
635
636         while (words_remaining > 0) {
637                 uint16_t value;
638                 memcpy(&value, buffer + bytes_written, sizeof(uint16_t));
639
640                 retval = target_write_u32(target, EM357_FLASH_CR, FLASH_PG);
641                 if (retval != ERROR_OK)
642                         return retval;
643                 retval = target_write_u16(target, address, value);
644                 if (retval != ERROR_OK)
645                         return retval;
646
647                 retval = em357_wait_status_busy(bank, 5);
648                 if (retval != ERROR_OK)
649                         return retval;
650
651                 bytes_written += 2;
652                 words_remaining--;
653                 address += 2;
654         }
655
656         if (bytes_remaining) {
657                 uint16_t value = 0xffff;
658                 memcpy(&value, buffer + bytes_written, bytes_remaining);
659
660                 retval = target_write_u32(target, EM357_FLASH_CR, FLASH_PG);
661                 if (retval != ERROR_OK)
662                         return retval;
663                 retval = target_write_u16(target, address, value);
664                 if (retval != ERROR_OK)
665                         return retval;
666
667                 retval = em357_wait_status_busy(bank, 5);
668                 if (retval != ERROR_OK)
669                         return retval;
670         }
671
672         return target_write_u32(target, EM357_FLASH_CR, FLASH_LOCK);
673 }
674
675 static int em357_probe(struct flash_bank *bank)
676 {
677         struct target *target = bank->target;
678         struct em357_flash_bank *em357_info = bank->driver_priv;
679         int i;
680         uint16_t num_pages;
681         int page_size;
682         uint32_t base_address = 0x08000000;
683
684         em357_info->probed = 0;
685
686         /* Enable FPEC CLK */
687         int retval = target_write_u32(target, EM357_FPEC_CLK, 0x00000001);
688         if (retval != ERROR_OK)
689                 return retval;
690
691         page_size = 2048;
692         em357_info->ppage_size = 4;
693         num_pages = 96;
694
695         LOG_INFO("flash size = %dkbytes", num_pages*page_size/1024);
696
697         if (bank->sectors) {
698                 free(bank->sectors);
699                 bank->sectors = NULL;
700         }
701
702         bank->base = base_address;
703         bank->size = (num_pages * page_size);
704         bank->num_sectors = num_pages;
705         bank->sectors = malloc(sizeof(struct flash_sector) * num_pages);
706
707         for (i = 0; i < num_pages; i++) {
708                 bank->sectors[i].offset = i * page_size;
709                 bank->sectors[i].size = page_size;
710                 bank->sectors[i].is_erased = -1;
711                 bank->sectors[i].is_protected = 1;
712         }
713
714         em357_info->probed = 1;
715
716         return ERROR_OK;
717 }
718
719 static int em357_auto_probe(struct flash_bank *bank)
720 {
721         struct em357_flash_bank *em357_info = bank->driver_priv;
722         if (em357_info->probed)
723                 return ERROR_OK;
724         return em357_probe(bank);
725 }
726
727
728 static int get_em357_info(struct flash_bank *bank, char *buf, int buf_size)
729 {
730         snprintf(buf, buf_size, "em357\n");
731         return ERROR_OK;
732 }
733
734 COMMAND_HANDLER(em357_handle_lock_command)
735 {
736         struct target *target = NULL;
737         struct em357_flash_bank *em357_info = NULL;
738
739         if (CMD_ARGC < 1)
740                 return ERROR_COMMAND_SYNTAX_ERROR;
741
742         struct flash_bank *bank;
743         int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
744         if (ERROR_OK != retval)
745                 return retval;
746
747         em357_info = bank->driver_priv;
748
749         target = bank->target;
750
751         if (target->state != TARGET_HALTED) {
752                 LOG_ERROR("Target not halted");
753                 return ERROR_TARGET_NOT_HALTED;
754         }
755
756         if (em357_erase_options(bank) != ERROR_OK) {
757                 command_print(CMD_CTX, "em357 failed to erase options");
758                 return ERROR_OK;
759         }
760
761         /* set readout protection */
762         em357_info->option_bytes.RDP = 0;
763
764         if (em357_write_options(bank) != ERROR_OK) {
765                 command_print(CMD_CTX, "em357 failed to lock device");
766                 return ERROR_OK;
767         }
768
769         command_print(CMD_CTX, "em357 locked");
770
771         return ERROR_OK;
772 }
773
774 COMMAND_HANDLER(em357_handle_unlock_command)
775 {
776         struct target *target = NULL;
777
778         if (CMD_ARGC < 1)
779                 return ERROR_COMMAND_SYNTAX_ERROR;
780
781         struct flash_bank *bank;
782         int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
783         if (ERROR_OK != retval)
784                 return retval;
785
786         target = bank->target;
787
788         if (target->state != TARGET_HALTED) {
789                 LOG_ERROR("Target not halted");
790                 return ERROR_TARGET_NOT_HALTED;
791         }
792
793         if (em357_erase_options(bank) != ERROR_OK) {
794                 command_print(CMD_CTX, "em357 failed to unlock device");
795                 return ERROR_OK;
796         }
797
798         if (em357_write_options(bank) != ERROR_OK) {
799                 command_print(CMD_CTX, "em357 failed to lock device");
800                 return ERROR_OK;
801         }
802
803         command_print(CMD_CTX, "em357 unlocked.\n"
804                 "INFO: a reset or power cycle is required "
805                 "for the new settings to take effect.");
806
807         return ERROR_OK;
808 }
809
810 static int em357_mass_erase(struct flash_bank *bank)
811 {
812         struct target *target = bank->target;
813
814         if (target->state != TARGET_HALTED) {
815                 LOG_ERROR("Target not halted");
816                 return ERROR_TARGET_NOT_HALTED;
817         }
818
819         /* unlock option flash registers */
820         int retval = target_write_u32(target, EM357_FLASH_KEYR, KEY1);
821         if (retval != ERROR_OK)
822                 return retval;
823         retval = target_write_u32(target, EM357_FLASH_KEYR, KEY2);
824         if (retval != ERROR_OK)
825                 return retval;
826
827         /* mass erase flash memory */
828         retval = target_write_u32(target, EM357_FLASH_CR, FLASH_MER);
829         if (retval != ERROR_OK)
830                 return retval;
831         retval = target_write_u32(target, EM357_FLASH_CR, FLASH_MER | FLASH_STRT);
832         if (retval != ERROR_OK)
833                 return retval;
834
835         retval = em357_wait_status_busy(bank, 100);
836         if (retval != ERROR_OK)
837                 return retval;
838
839         retval = target_write_u32(target, EM357_FLASH_CR, FLASH_LOCK);
840         if (retval != ERROR_OK)
841                 return retval;
842
843         return ERROR_OK;
844 }
845
846 COMMAND_HANDLER(em357_handle_mass_erase_command)
847 {
848         int i;
849
850         if (CMD_ARGC < 1)
851                 return ERROR_COMMAND_SYNTAX_ERROR;
852
853         struct flash_bank *bank;
854         int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
855         if (ERROR_OK != retval)
856                 return retval;
857
858         retval = em357_mass_erase(bank);
859         if (retval == ERROR_OK) {
860                 /* set all sectors as erased */
861                 for (i = 0; i < bank->num_sectors; i++)
862                         bank->sectors[i].is_erased = 1;
863
864                 command_print(CMD_CTX, "em357 mass erase complete");
865         } else
866                 command_print(CMD_CTX, "em357 mass erase failed");
867
868         return retval;
869 }
870
871 static const struct command_registration em357_exec_command_handlers[] = {
872         {
873                 .name = "lock",
874                 .usage = "<bank>",
875                 .handler = em357_handle_lock_command,
876                 .mode = COMMAND_EXEC,
877                 .help = "Lock entire flash device.",
878         },
879         {
880                 .name = "unlock",
881                 .usage = "<bank>",
882                 .handler = em357_handle_unlock_command,
883                 .mode = COMMAND_EXEC,
884                 .help = "Unlock entire protected flash device.",
885         },
886         {
887                 .name = "mass_erase",
888                 .usage = "<bank>",
889                 .handler = em357_handle_mass_erase_command,
890                 .mode = COMMAND_EXEC,
891                 .help = "Erase entire flash device.",
892         },
893         COMMAND_REGISTRATION_DONE
894 };
895
896 static const struct command_registration em357_command_handlers[] = {
897         {
898                 .name = "em357",
899                 .mode = COMMAND_ANY,
900                 .help = "em357 flash command group",
901                 .usage = "",
902                 .chain = em357_exec_command_handlers,
903         },
904         COMMAND_REGISTRATION_DONE
905 };
906
907 struct flash_driver em357_flash = {
908         .name = "em357",
909         .commands = em357_command_handlers,
910         .flash_bank_command = em357_flash_bank_command,
911         .erase = em357_erase,
912         .protect = em357_protect,
913         .write = em357_write,
914         .read = default_flash_read,
915         .probe = em357_probe,
916         .auto_probe = em357_auto_probe,
917         .erase_check = default_flash_mem_blank_check,
918         .protect_check = em357_protect_check,
919         .info = get_em357_info,
920 };