Fix serious bug in LPC2xxx/LPC17xx flash algorithm.
[fw/openocd] / src / flash / nor / lpc2000.c
1 /***************************************************************************
2  *   Copyright (C) 2005 by Dominic Rath                                    *
3  *   Dominic.Rath@gmx.de                                                   *
4  *                                                                         *
5  *   LPC1700 support Copyright (C) 2009 by Audrius Urmanavicius            *
6  *   didele.deze@gmail.com                                                 *
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
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include "imp.h"
29 #include <helper/binarybuffer.h>
30 #include <target/algorithm.h>
31 #include <target/arm_opcodes.h>
32 #include <target/armv7m.h>
33
34 /**
35  * @file
36  * flash programming support for NXP LPC17xx and LPC2xxx devices.
37  *
38  * @todo Provide a way to update CCLK after declaring the flash bank. The value which is correct after chip reset will
39  * rarely still work right after the clocks switch to use the PLL (e.g. 4MHz --> 100 MHz).
40  */
41 /*
42  * currently supported devices:
43  * variant 1 (lpc2000_v1):
44  * - 2104 | 5 | 6
45  * - 2114 | 9
46  * - 2124 | 9
47  * - 2194
48  * - 2212 | 4
49  * - 2292 | 4
50  *
51  * variant 2 (lpc2000_v2):
52  * - 213x
53  * - 214x
54  * - 2101 | 2 | 3
55  * - 2364 | 6 | 8
56  * - 2378
57  *
58  * lpc1700:
59  * - 175x
60  * - 176x (tested with LPC1768)
61  */
62
63 typedef enum {
64         lpc2000_v1,
65         lpc2000_v2,
66         lpc1700
67 } lpc2000_variant;
68
69 struct lpc2000_flash_bank {
70         lpc2000_variant variant;
71         uint32_t cclk;
72         int cmd51_dst_boundary;
73         int cmd51_can_256b;
74         int cmd51_can_8192b;
75         int calc_checksum;
76         uint32_t cmd51_max_buffer;
77         int checksum_vector;
78 };
79
80 enum lpc2000_status_codes {
81         LPC2000_CMD_SUCCESS = 0,
82         LPC2000_INVALID_COMMAND = 1,
83         LPC2000_SRC_ADDR_ERROR = 2,
84         LPC2000_DST_ADDR_ERROR = 3,
85         LPC2000_SRC_ADDR_NOT_MAPPED = 4,
86         LPC2000_DST_ADDR_NOT_MAPPED = 5,
87         LPC2000_COUNT_ERROR = 6,
88         LPC2000_INVALID_SECTOR = 7,
89         LPC2000_SECTOR_NOT_BLANK = 8,
90         LPC2000_SECTOR_NOT_PREPARED = 9,
91         LPC2000_COMPARE_ERROR = 10,
92         LPC2000_BUSY = 11,
93         LPC2000_PARAM_ERROR = 12,
94         LPC2000_ADDR_ERROR = 13,
95         LPC2000_ADDR_NOT_MAPPED = 14,
96         LPC2000_CMD_NOT_LOCKED = 15,
97         LPC2000_INVALID_CODE = 16,
98         LPC2000_INVALID_BAUD_RATE = 17,
99         LPC2000_INVALID_STOP_BIT = 18,
100         LPC2000_CRP_ENABLED = 19
101 };
102
103 static int lpc2000_build_sector_list(struct flash_bank *bank)
104 {
105         struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
106         uint32_t offset = 0;
107
108         /* default to a 4096 write buffer */
109         lpc2000_info->cmd51_max_buffer = 4096;
110
111         if (lpc2000_info->variant == lpc2000_v1) {
112                 /* variant 1 has different layout for 128kb and 256kb flashes */
113                 if (bank->size == 128 * 1024) {
114                         bank->num_sectors = 16;
115                         bank->sectors = malloc(sizeof(struct flash_sector) * 16);
116                         for (int i = 0; i < 16; i++) {
117                                 bank->sectors[i].offset = offset;
118                                 bank->sectors[i].size = 8 * 1024;
119                                 offset += bank->sectors[i].size;
120                                 bank->sectors[i].is_erased = -1;
121                                 bank->sectors[i].is_protected = 1;
122                         }
123                 } else if (bank->size == 256 * 1024) {
124                         bank->num_sectors = 18;
125                         bank->sectors = malloc(sizeof(struct flash_sector) * 18);
126
127                         for (int i = 0; i < 8; i++) {
128                                 bank->sectors[i].offset = offset;
129                                 bank->sectors[i].size = 8 * 1024;
130                                 offset += bank->sectors[i].size;
131                                 bank->sectors[i].is_erased = -1;
132                                 bank->sectors[i].is_protected = 1;
133                         }
134                         for (int i = 8; i < 10; i++) {
135                                 bank->sectors[i].offset = offset;
136                                 bank->sectors[i].size = 64 * 1024;
137                                 offset += bank->sectors[i].size;
138                                 bank->sectors[i].is_erased = -1;
139                                 bank->sectors[i].is_protected = 1;
140                         }
141                         for (int i = 10; i < 18; i++) {
142                                 bank->sectors[i].offset = offset;
143                                 bank->sectors[i].size = 8 * 1024;
144                                 offset += bank->sectors[i].size;
145                                 bank->sectors[i].is_erased = -1;
146                                 bank->sectors[i].is_protected = 1;
147                         }
148                 } else {
149                         LOG_ERROR("BUG: unknown bank->size encountered");
150                         exit(-1);
151                 }
152         } else if (lpc2000_info->variant == lpc2000_v2) {
153                 /* variant 2 has a uniform layout, only number of sectors differs */
154                 switch (bank->size) {
155                         case 4 * 1024:
156                                 lpc2000_info->cmd51_max_buffer = 1024;
157                                 bank->num_sectors = 1;
158                                 break;
159                         case 8 * 1024:
160                                 lpc2000_info->cmd51_max_buffer = 1024;
161                                 bank->num_sectors = 2;
162                                 break;
163                         case 16 * 1024:
164                                 bank->num_sectors = 4;
165                                 break;
166                         case 32 * 1024:
167                                 bank->num_sectors = 8;
168                                 break;
169                         case 64 * 1024:
170                                 bank->num_sectors = 9;
171                                 break;
172                         case 128 * 1024:
173                                 bank->num_sectors = 11;
174                                 break;
175                         case 256 * 1024:
176                                 bank->num_sectors = 15;
177                                 break;
178                         case 500 * 1024:
179                                 bank->num_sectors = 27;
180                                 break;
181                         case 512 * 1024:
182                         case 504 * 1024:
183                                 bank->num_sectors = 28;
184                                 break;
185                         default:
186                                 LOG_ERROR("BUG: unknown bank->size encountered");
187                                 exit(-1);
188                                 break;
189                 }
190
191                 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
192
193                 for (int i = 0; i < bank->num_sectors; i++) {
194                         if (i < 8) {
195                                 bank->sectors[i].offset = offset;
196                                 bank->sectors[i].size = 4 * 1024;
197                                 offset += bank->sectors[i].size;
198                                 bank->sectors[i].is_erased = -1;
199                                 bank->sectors[i].is_protected = 1;
200                         } else if (i < 22) {
201                                 bank->sectors[i].offset = offset;
202                                 bank->sectors[i].size = 32 * 1024;
203                                 offset += bank->sectors[i].size;
204                                 bank->sectors[i].is_erased = -1;
205                                 bank->sectors[i].is_protected = 1;
206                         } else if (i < 28) {
207                                 bank->sectors[i].offset = offset;
208                                 bank->sectors[i].size = 4 * 1024;
209                                 offset += bank->sectors[i].size;
210                                 bank->sectors[i].is_erased = -1;
211                                 bank->sectors[i].is_protected = 1;
212                         }
213                 }
214         } else if (lpc2000_info->variant == lpc1700) {
215                 switch (bank->size) {
216                         case 32 * 1024:
217                                 bank->num_sectors = 8;
218                                 break;
219                         case 64 * 1024:
220                                 bank->num_sectors = 16;
221                                 break;
222                         case 128 * 1024:
223                                 bank->num_sectors = 18;
224                         break;
225                         case 256 * 1024:
226                                 bank->num_sectors = 22;
227                                 break;
228                         case 512 * 1024:
229                                 bank->num_sectors = 30;
230                                 break;
231                         default:
232                                 LOG_ERROR("BUG: unknown bank->size encountered");
233                                 exit(-1);
234                 }
235
236                 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
237
238                 for (int i = 0; i < bank->num_sectors; i++) {
239                         bank->sectors[i].offset = offset;
240                         /* sectors 0-15 are 4kB-sized, 16 and above are 32kB-sized for LPC17xx devices */
241                         bank->sectors[i].size = (i < 16) ? 4 * 1024 : 32 * 1024;
242                         offset += bank->sectors[i].size;
243                         bank->sectors[i].is_erased = -1;
244                         bank->sectors[i].is_protected = 1;
245                 }
246         } else {
247                 LOG_ERROR("BUG: unknown lpc2000_info->variant encountered");
248                 exit(-1);
249         }
250
251         return ERROR_OK;
252 }
253
254 /* this function allocates and initializes working area used for IAP algorithm
255  * uses 180 bytes working area
256  * 0x0 to 0x7: jump gate (BX to thumb state, b -2 to wait)
257  * 0x8 to 0x1f: command parameter table (1+5 words)
258  * 0x20 to 0x33: command result table (1+4 words)
259  * 0x34 to 0xb3: stack (only 128b needed)
260  */
261
262 static int lpc2000_iap_working_area_init(struct flash_bank *bank, struct working_area **iap_working_area)
263 {
264         struct target *target = bank->target;
265
266         if (target_alloc_working_area(target, 180, iap_working_area) != ERROR_OK) {
267                 LOG_ERROR("no working area specified, can't write LPC2000 internal flash");
268                 return ERROR_FLASH_OPERATION_FAILED;
269         }
270
271         struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
272         uint8_t jump_gate[8];
273
274         /* write IAP code to working area */
275         switch (lpc2000_info->variant) {
276                 case lpc1700:
277                         target_buffer_set_u32(target, jump_gate, ARMV4_5_T_BX(12));
278                         target_buffer_set_u32(target, jump_gate + 4, ARMV5_T_BKPT(0));
279                         break;
280                 case lpc2000_v1:
281                 case lpc2000_v2:
282                         target_buffer_set_u32(target, jump_gate, ARMV4_5_BX(12));
283                         target_buffer_set_u32(target, jump_gate + 4, ARMV4_5_B(0xfffffe, 0));
284                         break;
285                 default:
286                         LOG_ERROR("BUG: unknown lpc2000_info->variant encountered");
287                         exit(-1);
288         }
289
290         int retval = target_write_memory(target, (*iap_working_area)->address, 4, 2, jump_gate);
291         if (retval != ERROR_OK)
292                 LOG_ERROR("Write memory at address 0x%8.8" PRIx32 " failed (check work_area definition)",
293                                 (*iap_working_area)->address);
294
295         return retval;
296 }
297
298 /* call LPC1700/LPC2000 IAP function */
299
300 static int lpc2000_iap_call(struct flash_bank *bank, struct working_area *iap_working_area, int code,
301                 uint32_t param_table[5], uint32_t result_table[4])
302 {
303         struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
304
305         struct arm_algorithm arm_algo;  /* for LPC2000 */
306         struct armv7m_algorithm armv7m_info;    /* for LPC1700 */
307         uint32_t iap_entry_point = 0;   /* to make compiler happier */
308
309         switch (lpc2000_info->variant) {
310                 case lpc1700:
311                         armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
312                         armv7m_info.core_mode = ARMV7M_MODE_ANY;
313                         iap_entry_point = 0x1fff1ff1;
314                         break;
315                 case lpc2000_v1:
316                 case lpc2000_v2:
317                         arm_algo.common_magic = ARM_COMMON_MAGIC;
318                         arm_algo.core_mode = ARM_MODE_SVC;
319                         arm_algo.core_state = ARM_STATE_ARM;
320                         iap_entry_point = 0x7ffffff1;
321                         break;
322                 default:
323                         LOG_ERROR("BUG: unknown lpc2000->variant encountered");
324                         exit(-1);
325         }
326
327         struct target *target = bank->target;
328         struct mem_param mem_params[2];
329
330         /* command parameter table */
331         init_mem_param(&mem_params[0], iap_working_area->address + 8, 6 * 4, PARAM_OUT);
332         target_buffer_set_u32(target, mem_params[0].value, code);
333         target_buffer_set_u32(target, mem_params[0].value + 0x04, param_table[0]);
334         target_buffer_set_u32(target, mem_params[0].value + 0x08, param_table[1]);
335         target_buffer_set_u32(target, mem_params[0].value + 0x0c, param_table[2]);
336         target_buffer_set_u32(target, mem_params[0].value + 0x10, param_table[3]);
337         target_buffer_set_u32(target, mem_params[0].value + 0x14, param_table[4]);
338
339         struct reg_param reg_params[5];
340
341         init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
342         buf_set_u32(reg_params[0].value, 0, 32, iap_working_area->address + 0x08);
343
344         /* command result table */
345         init_mem_param(&mem_params[1], iap_working_area->address + 0x20, 5 * 4, PARAM_IN);
346
347         init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
348         buf_set_u32(reg_params[1].value, 0, 32, iap_working_area->address + 0x20);
349
350         /* IAP entry point */
351         init_reg_param(&reg_params[2], "r12", 32, PARAM_OUT);
352         buf_set_u32(reg_params[2].value, 0, 32, iap_entry_point);
353
354         switch (lpc2000_info->variant) {
355                 case lpc1700:
356                         /* IAP stack */
357                         init_reg_param(&reg_params[3], "sp", 32, PARAM_OUT);
358                         buf_set_u32(reg_params[3].value, 0, 32, iap_working_area->address + 0xb4);
359
360                         /* return address */
361                         init_reg_param(&reg_params[4], "lr", 32, PARAM_OUT);
362                         buf_set_u32(reg_params[4].value, 0, 32, (iap_working_area->address + 0x04) | 1);
363                         /* bit0 of LR = 1 to return in Thumb mode */
364
365                         target_run_algorithm(target, 2, mem_params, 5, reg_params, iap_working_area->address, 0, 10000,
366                                         &armv7m_info);
367                         break;
368                 case lpc2000_v1:
369                 case lpc2000_v2:
370                         /* IAP stack */
371                         init_reg_param(&reg_params[3], "sp_svc", 32, PARAM_OUT);
372                         buf_set_u32(reg_params[3].value, 0, 32, iap_working_area->address + 0xb4);
373
374                         /* return address */
375                         init_reg_param(&reg_params[4], "lr_svc", 32, PARAM_OUT);
376                         buf_set_u32(reg_params[4].value, 0, 32, iap_working_area->address + 0x04);
377
378                         target_run_algorithm(target, 2, mem_params, 5, reg_params, iap_working_area->address,
379                                         iap_working_area->address + 0x4, 10000, &arm_algo);
380                         break;
381                 default:
382                         LOG_ERROR("BUG: unknown lpc2000->variant encountered");
383                         exit(-1);
384         }
385
386         int status_code = target_buffer_get_u32(target, mem_params[1].value);
387         result_table[0] = target_buffer_get_u32(target, mem_params[1].value + 0x04);
388         result_table[1] = target_buffer_get_u32(target, mem_params[1].value + 0x08);
389         result_table[2] = target_buffer_get_u32(target, mem_params[1].value + 0x0c);
390         result_table[3] = target_buffer_get_u32(target, mem_params[1].value + 0x10);
391
392         LOG_DEBUG("IAP command = %i (0x%8.8" PRIx32 ", 0x%8.8" PRIx32 ", 0x%8.8" PRIx32 ", 0x%8.8" PRIx32 ", 0x%8.8" PRIx32
393                         ") completed with result = %8.8" PRIx32,
394                         code, param_table[0], param_table[1], param_table[2], param_table[3], param_table[4], status_code);
395
396         destroy_mem_param(&mem_params[0]);
397         destroy_mem_param(&mem_params[1]);
398
399         destroy_reg_param(&reg_params[0]);
400         destroy_reg_param(&reg_params[1]);
401         destroy_reg_param(&reg_params[2]);
402         destroy_reg_param(&reg_params[3]);
403         destroy_reg_param(&reg_params[4]);
404
405         return status_code;
406 }
407
408 static int lpc2000_iap_blank_check(struct flash_bank *bank, int first, int last)
409 {
410         if ((first < 0) || (last >= bank->num_sectors))
411                 return ERROR_FLASH_SECTOR_INVALID;
412
413         uint32_t param_table[5] = {0};
414         uint32_t result_table[4];
415         struct working_area *iap_working_area;
416
417         int retval = lpc2000_iap_working_area_init(bank, &iap_working_area);
418
419         if (retval != ERROR_OK)
420                 return retval;
421
422         for (int i = first; i <= last && retval == ERROR_OK; i++) {
423                 /* check single sector */
424                 param_table[0] = param_table[1] = i;
425                 int status_code = lpc2000_iap_call(bank, iap_working_area, 53, param_table, result_table);
426
427                 switch (status_code) {
428                         case ERROR_FLASH_OPERATION_FAILED:
429                                 retval = ERROR_FLASH_OPERATION_FAILED;
430                                 break;
431                         case LPC2000_CMD_SUCCESS:
432                                 bank->sectors[i].is_erased = 1;
433                                 break;
434                         case LPC2000_SECTOR_NOT_BLANK:
435                                 bank->sectors[i].is_erased = 0;
436                                 break;
437                         case LPC2000_INVALID_SECTOR:
438                                 bank->sectors[i].is_erased = 0;
439                                 break;
440                         case LPC2000_BUSY:
441                                 retval = ERROR_FLASH_BUSY;
442                                 break;
443                         default:
444                                 LOG_ERROR("BUG: unknown LPC2000 status code %i", status_code);
445                                 exit(-1);
446                 }
447         }
448
449         struct target *target = bank->target;
450         target_free_working_area(target, iap_working_area);
451
452         return retval;
453 }
454
455 /*
456  * flash bank lpc2000 <base> <size> 0 0 <target#> <lpc_variant> <cclk> [calc_checksum]
457  */
458 FLASH_BANK_COMMAND_HANDLER(lpc2000_flash_bank_command)
459 {
460         if (CMD_ARGC < 8)
461                 return ERROR_COMMAND_SYNTAX_ERROR;
462
463         struct lpc2000_flash_bank *lpc2000_info = malloc(sizeof(struct lpc2000_flash_bank));
464         bank->driver_priv = lpc2000_info;
465
466         if (strcmp(CMD_ARGV[6], "lpc2000_v1") == 0) {
467                 lpc2000_info->variant = lpc2000_v1;
468                 lpc2000_info->cmd51_dst_boundary = 512;
469                 lpc2000_info->cmd51_can_256b = 0;
470                 lpc2000_info->cmd51_can_8192b = 1;
471                 lpc2000_info->checksum_vector = 5;
472         } else if (strcmp(CMD_ARGV[6], "lpc2000_v2") == 0) {
473                 lpc2000_info->variant = lpc2000_v2;
474                 lpc2000_info->cmd51_dst_boundary = 256;
475                 lpc2000_info->cmd51_can_256b = 1;
476                 lpc2000_info->cmd51_can_8192b = 0;
477                 lpc2000_info->checksum_vector = 5;
478         } else if (strcmp(CMD_ARGV[6], "lpc1700") == 0) {
479                 lpc2000_info->variant = lpc1700;
480                 lpc2000_info->cmd51_dst_boundary = 256;
481                 lpc2000_info->cmd51_can_256b = 1;
482                 lpc2000_info->cmd51_can_8192b = 0;
483                 lpc2000_info->checksum_vector = 7;
484         } else {
485                 LOG_ERROR("unknown LPC2000 variant: %s", CMD_ARGV[6]);
486                 free(lpc2000_info);
487                 return ERROR_FLASH_BANK_INVALID;
488         }
489
490         COMMAND_PARSE_NUMBER(u32, CMD_ARGV[7], lpc2000_info->cclk);
491         lpc2000_info->calc_checksum = 0;
492         lpc2000_build_sector_list(bank);
493
494         if (CMD_ARGC >= 9) {
495                 if (strcmp(CMD_ARGV[8], "calc_checksum") == 0)
496                         lpc2000_info->calc_checksum = 1;
497         }
498
499         return ERROR_OK;
500 }
501
502 static int lpc2000_erase(struct flash_bank *bank, int first, int last)
503 {
504         if (bank->target->state != TARGET_HALTED) {
505                 LOG_ERROR("Target not halted");
506                 return ERROR_TARGET_NOT_HALTED;
507         }
508
509         struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
510         uint32_t param_table[5] = {0};
511
512         param_table[0] = first;
513         param_table[1] = last;
514         param_table[2] = lpc2000_info->cclk;
515
516         uint32_t result_table[4];
517         struct working_area *iap_working_area;
518
519         int retval = lpc2000_iap_working_area_init(bank, &iap_working_area);
520
521         if (retval != ERROR_OK)
522                 return retval;
523
524         /* Prepare sectors */
525         int status_code = lpc2000_iap_call(bank, iap_working_area, 50, param_table, result_table);
526         switch (status_code) {
527                 case ERROR_FLASH_OPERATION_FAILED:
528                         retval = ERROR_FLASH_OPERATION_FAILED;
529                         break;
530                 case LPC2000_CMD_SUCCESS:
531                         break;
532                 case LPC2000_INVALID_SECTOR:
533                         retval = ERROR_FLASH_SECTOR_INVALID;
534                         break;
535                 default:
536                         LOG_WARNING("lpc2000 prepare sectors returned %i", status_code);
537                         retval = ERROR_FLASH_OPERATION_FAILED;
538                         break;
539         }
540
541         if (retval == ERROR_OK) {
542                 /* Erase sectors */
543                 status_code = lpc2000_iap_call(bank, iap_working_area, 52, param_table, result_table);
544                 switch (status_code) {
545                         case ERROR_FLASH_OPERATION_FAILED:
546                                 retval = ERROR_FLASH_OPERATION_FAILED;
547                                 break;
548                         case LPC2000_CMD_SUCCESS:
549                                 break;
550                         case LPC2000_INVALID_SECTOR:
551                                 retval = ERROR_FLASH_SECTOR_INVALID;
552                                 break;
553                         default:
554                                 LOG_WARNING("lpc2000 erase sectors returned %i", status_code);
555                                 retval = ERROR_FLASH_OPERATION_FAILED;
556                                 break;
557                 }
558         }
559
560         struct target *target = bank->target;
561         target_free_working_area(target, iap_working_area);
562
563         return retval;
564 }
565
566 static int lpc2000_protect(struct flash_bank *bank, int set, int first, int last)
567 {
568         /* can't protect/unprotect on the lpc2000 */
569         return ERROR_OK;
570 }
571
572 static int lpc2000_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
573 {
574         struct target *target = bank->target;
575
576         if (bank->target->state != TARGET_HALTED) {
577                 LOG_ERROR("Target not halted");
578                 return ERROR_TARGET_NOT_HALTED;
579         }
580
581         if (offset + count > bank->size)
582                 return ERROR_FLASH_DST_OUT_OF_BANK;
583
584         struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
585
586         uint32_t dst_min_alignment = lpc2000_info->cmd51_dst_boundary;
587
588         if (offset % dst_min_alignment) {
589                 LOG_WARNING("offset 0x%" PRIx32 " breaks required alignment 0x%" PRIx32, offset, dst_min_alignment);
590                 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
591         }
592
593         int first_sector = 0;
594         int last_sector = 0;
595
596         for (int i = 0; i < bank->num_sectors; i++) {
597                 if (offset >= bank->sectors[i].offset)
598                         first_sector = i;
599                 if (offset + DIV_ROUND_UP(count, dst_min_alignment) * dst_min_alignment > bank->sectors[i].offset)
600                         last_sector = i;
601         }
602
603         LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
604
605         /* check if exception vectors should be flashed */
606         if ((offset == 0) && (count >= 0x20) && lpc2000_info->calc_checksum) {
607                 uint32_t checksum = 0;
608                 for (int i = 0; i < 8; i++) {
609                         LOG_DEBUG("Vector 0x%2.2x: 0x%8.8" PRIx32, i * 4, buf_get_u32(buffer + (i * 4), 0, 32));
610                         if (i != lpc2000_info->checksum_vector)
611                                 checksum += buf_get_u32(buffer + (i * 4), 0, 32);
612                 }
613                 checksum = 0 - checksum;
614                 LOG_DEBUG("checksum: 0x%8.8" PRIx32, checksum);
615
616                 uint32_t original_value = buf_get_u32(buffer + (lpc2000_info->checksum_vector * 4), 0, 32);
617                 if (original_value != checksum) {
618                         LOG_WARNING("Verification will fail since checksum in image (0x%8.8" PRIx32 ") to be written to flash is "
619                                         "different from calculated vector checksum (0x%8.8" PRIx32 ").", original_value, checksum);
620                         LOG_WARNING("To remove this warning modify build tools on developer PC to inject correct LPC vector "
621                                         "checksum.");
622                 }
623
624                 buf_set_u32(buffer + (lpc2000_info->checksum_vector * 4), 0, 32, checksum);
625         }
626
627         struct working_area *iap_working_area;
628
629         int retval = lpc2000_iap_working_area_init(bank, &iap_working_area);
630
631         if (retval != ERROR_OK)
632                 return retval;
633
634         struct working_area *download_area;
635
636         /* allocate a working area */
637         if (target_alloc_working_area(target, lpc2000_info->cmd51_max_buffer, &download_area) != ERROR_OK) {
638                 LOG_ERROR("no working area specified, can't write LPC2000 internal flash");
639                 target_free_working_area(target, iap_working_area);
640                 return ERROR_FLASH_OPERATION_FAILED;
641         }
642
643         uint32_t bytes_remaining = count;
644         uint32_t bytes_written = 0;
645         uint32_t param_table[5] = {0};
646         uint32_t result_table[4];
647
648         while (bytes_remaining > 0) {
649                 uint32_t thisrun_bytes;
650                 if (bytes_remaining >= lpc2000_info->cmd51_max_buffer)
651                         thisrun_bytes = lpc2000_info->cmd51_max_buffer;
652                 else if (bytes_remaining >= 1024)
653                         thisrun_bytes = 1024;
654                 else if ((bytes_remaining >= 512) || (!lpc2000_info->cmd51_can_256b))
655                         thisrun_bytes = 512;
656                 else
657                         thisrun_bytes = 256;
658
659                 /* Prepare sectors */
660                 param_table[0] = first_sector;
661                 param_table[1] = last_sector;
662                 int status_code = lpc2000_iap_call(bank, iap_working_area, 50, param_table, result_table);
663                 switch (status_code) {
664                         case ERROR_FLASH_OPERATION_FAILED:
665                                 retval = ERROR_FLASH_OPERATION_FAILED;
666                                 break;
667                         case LPC2000_CMD_SUCCESS:
668                                 break;
669                         case LPC2000_INVALID_SECTOR:
670                                 retval = ERROR_FLASH_SECTOR_INVALID;
671                                 break;
672                         default:
673                                 LOG_WARNING("lpc2000 prepare sectors returned %i", status_code);
674                                 retval = ERROR_FLASH_OPERATION_FAILED;
675                                 break;
676                 }
677
678                 /* Exit if error occured */
679                 if (retval != ERROR_OK)
680                         break;
681
682                 if (bytes_remaining >= thisrun_bytes) {
683                         retval = target_write_buffer(bank->target, download_area->address, thisrun_bytes, buffer + bytes_written);
684                         if (retval != ERROR_OK) {
685                                 retval = ERROR_FLASH_OPERATION_FAILED;
686                                 break;
687                         }
688                 } else {
689                         uint8_t *last_buffer = malloc(thisrun_bytes);
690                         memcpy(last_buffer, buffer + bytes_written, bytes_remaining);
691                         memset(last_buffer + bytes_remaining, 0xff, thisrun_bytes - bytes_remaining);
692                         target_write_buffer(bank->target, download_area->address, thisrun_bytes, last_buffer);
693                         free(last_buffer);
694                 }
695
696                 LOG_DEBUG("writing 0x%" PRIx32 " bytes to address 0x%" PRIx32, thisrun_bytes,
697                                 bank->base + offset + bytes_written);
698
699                 /* Write data */
700                 param_table[0] = bank->base + offset + bytes_written;
701                 param_table[1] = download_area->address;
702                 param_table[2] = thisrun_bytes;
703                 param_table[3] = lpc2000_info->cclk;
704                 status_code = lpc2000_iap_call(bank, iap_working_area, 51, param_table, result_table);
705                 switch (status_code) {
706                         case ERROR_FLASH_OPERATION_FAILED:
707                                 retval = ERROR_FLASH_OPERATION_FAILED;
708                                 break;
709                         case LPC2000_CMD_SUCCESS:
710                                 break;
711                         case LPC2000_INVALID_SECTOR:
712                                 retval = ERROR_FLASH_SECTOR_INVALID;
713                                 break;
714                         default:
715                                 LOG_WARNING("lpc2000 returned %i", status_code);
716                                 retval = ERROR_FLASH_OPERATION_FAILED;
717                                 break;
718                 }
719
720                 /* Exit if error occured */
721                 if (retval != ERROR_OK)
722                         break;
723
724                 if (bytes_remaining > thisrun_bytes)
725                         bytes_remaining -= thisrun_bytes;
726                 else
727                         bytes_remaining = 0;
728                 bytes_written += thisrun_bytes;
729         }
730
731         target_free_working_area(target, iap_working_area);
732         target_free_working_area(target, download_area);
733
734         return retval;
735 }
736
737 static int lpc2000_probe(struct flash_bank *bank)
738 {
739         /* we can't probe on an lpc2000 if this is an lpc2xxx, it has the configured flash */
740         return ERROR_OK;
741 }
742
743 static int lpc2000_erase_check(struct flash_bank *bank)
744 {
745         if (bank->target->state != TARGET_HALTED) {
746                 LOG_ERROR("Target not halted");
747                 return ERROR_TARGET_NOT_HALTED;
748         }
749
750         return lpc2000_iap_blank_check(bank, 0, bank->num_sectors - 1);
751 }
752
753 static int lpc2000_protect_check(struct flash_bank *bank)
754 {
755         /* sectors are always protected */
756         return ERROR_OK;
757 }
758
759 static int get_lpc2000_info(struct flash_bank *bank, char *buf, int buf_size)
760 {
761         struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
762
763         snprintf(buf, buf_size, "lpc2000 flash driver variant: %i, clk: %" PRIi32 "kHz", lpc2000_info->variant,
764                         lpc2000_info->cclk);
765
766         return ERROR_OK;
767 }
768
769 COMMAND_HANDLER(lpc2000_handle_part_id_command)
770 {
771         if (CMD_ARGC < 1)
772                 return ERROR_COMMAND_SYNTAX_ERROR;
773
774         struct flash_bank *bank;
775         int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
776         if (ERROR_OK != retval)
777                 return retval;
778
779         if (bank->target->state != TARGET_HALTED) {
780                 LOG_ERROR("Target not halted");
781                 return ERROR_TARGET_NOT_HALTED;
782         }
783
784         uint32_t param_table[5] = {0};
785         uint32_t result_table[4];
786         struct working_area *iap_working_area;
787
788         retval = lpc2000_iap_working_area_init(bank, &iap_working_area);
789
790         if (retval != ERROR_OK)
791                 return retval;
792
793         int status_code = lpc2000_iap_call(bank, iap_working_area, 54, param_table, result_table);
794         if (status_code != 0x0) {
795                 if (status_code == ERROR_FLASH_OPERATION_FAILED) {
796                         command_print(CMD_CTX, "no sufficient working area specified, can't access LPC2000 IAP interface");
797                 } else
798                         command_print(CMD_CTX, "lpc2000 IAP returned status code %i", status_code);
799         } else
800                 command_print(CMD_CTX, "lpc2000 part id: 0x%8.8" PRIx32, result_table[0]);
801
802         return retval;
803 }
804
805 static const struct command_registration lpc2000_exec_command_handlers[] = {
806         {
807                 .name = "part_id",
808                 .handler = lpc2000_handle_part_id_command,
809                 .mode = COMMAND_EXEC,
810                 .help = "print part id of lpc2000 flash bank <num>",
811                 .usage = "<bank>",
812         },
813         COMMAND_REGISTRATION_DONE
814 };
815 static const struct command_registration lpc2000_command_handlers[] = {
816         {
817                 .name = "lpc2000",
818                 .mode = COMMAND_ANY,
819                 .help = "lpc2000 flash command group",
820                 .usage = "",
821                 .chain = lpc2000_exec_command_handlers,
822         },
823         COMMAND_REGISTRATION_DONE
824 };
825
826 struct flash_driver lpc2000_flash = {
827         .name = "lpc2000",
828         .commands = lpc2000_command_handlers,
829         .flash_bank_command = lpc2000_flash_bank_command,
830         .erase = lpc2000_erase,
831         .protect = lpc2000_protect,
832         .write = lpc2000_write,
833         .read = default_flash_read,
834         .probe = lpc2000_probe,
835         .auto_probe = lpc2000_probe,
836         .erase_check = lpc2000_erase_check,
837         .protect_check = lpc2000_protect_check,
838         .info = get_lpc2000_info,
839 };