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