Fix stm32x and pic32mx flash pointer cast alignment warnings, simplify their last...
[fw/openocd] / src / flash / pic32mx.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) 2008 by John McCarthy                                   *
9  *   jgmcc@magma.ca                                                        *
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 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include "replacements.h"
31
32 #include "pic32mx.h"
33 #include "flash.h"
34 #include "target.h"
35 #include "log.h"
36 #include "mips32.h"
37 #include "algorithm.h"
38 #include "binarybuffer.h"
39
40 #include <stdlib.h>
41 #include <string.h>
42
43 static
44 struct pic32mx_devs_s {
45         u8      devid;
46         char    *name;
47         u32     pfm_size;
48 } pic32mx_devs[] = {
49         { 0x78, "460F512L USB", 512 },
50         { 0x74, "460F256L USB", 256 },
51         { 0x6D, "440F128L USB", 128 },
52         { 0x56, "440F512H USB", 512 },
53         { 0x52, "440F256H USB", 256 },
54         { 0x4D, "440F128H USB", 128 },
55         { 0x42, "420F032H USB",  32 },
56         { 0x38, "360F512L",     512 },
57         { 0x34, "360F256L",     256 },
58         { 0x2D, "340F128L",     128 },
59         { 0x2A, "320F128L",     128 },
60         { 0x16, "340F512H",     512 },
61         { 0x12, "340F256H",     256 },
62         { 0x0D, "340F128H",     128 },
63         { 0x0A, "320F128H",     128 },
64         { 0x06, "320F064H",      64 },
65         { 0x02, "320F032H",      32 },
66         { 0x00, NULL, 0 }
67 };
68
69 static int pic32mx_register_commands(struct command_context_s *cmd_ctx);
70 static int pic32mx_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
71 static int pic32mx_erase(struct flash_bank_s *bank, int first, int last);
72 static int pic32mx_protect(struct flash_bank_s *bank, int set, int first, int last);
73 static int pic32mx_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
74 static int pic32mx_write_row(struct flash_bank_s *bank, u32 address, u32 srcaddr);
75 static int pic32mx_write_word(struct flash_bank_s *bank, u32 address, u32 word);
76 static int pic32mx_probe(struct flash_bank_s *bank);
77 static int pic32mx_auto_probe(struct flash_bank_s *bank);
78 //static int pic32mx_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
79 static int pic32mx_protect_check(struct flash_bank_s *bank);
80 static int pic32mx_info(struct flash_bank_s *bank, char *buf, int buf_size);
81
82 #if 0
83 int pic32mx_handle_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
84 int pic32mx_handle_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
85 #endif
86 static int pic32mx_handle_chip_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
87 static int pic32mx_handle_pgm_word_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
88 //static int pic32mx_chip_erase(struct flash_bank_s *bank);
89
90 flash_driver_t pic32mx_flash =
91 {
92         .name = "pic32mx",
93         .register_commands = pic32mx_register_commands,
94         .flash_bank_command = pic32mx_flash_bank_command,
95         .erase = pic32mx_erase,
96         .protect = pic32mx_protect,
97         .write = pic32mx_write,
98         .probe = pic32mx_probe,
99         .auto_probe = pic32mx_auto_probe,
100         .erase_check = default_flash_mem_blank_check,
101         .protect_check = pic32mx_protect_check,
102         .info = pic32mx_info
103 };
104
105 static int pic32mx_register_commands(struct command_context_s *cmd_ctx)
106 {
107         command_t *pic32mx_cmd = register_command(cmd_ctx, NULL, "pic32mx", NULL, COMMAND_ANY, "pic32mx flash specific commands");
108
109 #if 0
110         register_command(cmd_ctx, pic32mx_cmd, "lock", pic32mx_handle_lock_command, COMMAND_EXEC,
111                                          "lock device");
112         register_command(cmd_ctx, pic32mx_cmd, "unlock", pic32mx_handle_unlock_command, COMMAND_EXEC,
113                                          "unlock protected device");
114 #endif
115         register_command(cmd_ctx, pic32mx_cmd, "chip_erase", pic32mx_handle_chip_erase_command, COMMAND_EXEC,
116                                          "erase device");
117         register_command(cmd_ctx, pic32mx_cmd, "pgm_word", pic32mx_handle_pgm_word_command, COMMAND_EXEC,
118                                          "program a word");
119         return ERROR_OK;
120 }
121
122 /* flash bank pic32mx <base> <size> 0 0 <target#>
123  */
124 static int pic32mx_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
125 {
126         pic32mx_flash_bank_t *pic32mx_info;
127
128         if (argc < 6)
129         {
130                 LOG_WARNING("incomplete flash_bank pic32mx configuration");
131                 return ERROR_FLASH_BANK_INVALID;
132         }
133
134         pic32mx_info = malloc(sizeof(pic32mx_flash_bank_t));
135         bank->driver_priv = pic32mx_info;
136
137         pic32mx_info->write_algorithm = NULL;
138         pic32mx_info->probed = 0;
139
140         return ERROR_OK;
141 }
142
143 static u32 pic32mx_get_flash_status(flash_bank_t *bank)
144 {
145         target_t *target = bank->target;
146         u32 status;
147
148         target_read_u32(target, PIC32MX_NVMCON, &status);
149
150         return status;
151 }
152
153 static u32 pic32mx_wait_status_busy(flash_bank_t *bank, int timeout)
154 {
155         u32 status;
156
157         /* wait for busy to clear */
158         while (((status = pic32mx_get_flash_status(bank)) & NVMCON_NVMWR) && (timeout-- > 0))
159         {
160                 LOG_DEBUG("status: 0x%x", status);
161                 alive_sleep(1);
162         }
163         if(timeout <= 0)
164                 LOG_DEBUG("timeout: status: 0x%x", status);
165
166         return status;
167 }
168
169 static int pic32mx_nvm_exec(struct flash_bank_s *bank, u32 op, u32 timeout)
170 {
171         target_t *target = bank->target;
172         u32 status;
173
174         target_write_u32(target, PIC32MX_NVMCON, NVMCON_NVMWREN|op);
175
176         /* unlock flash registers */
177         target_write_u32(target, PIC32MX_NVMKEY, NVMKEY1);
178         target_write_u32(target, PIC32MX_NVMKEY, NVMKEY2);
179
180         /* start operation */
181         target_write_u32(target, PIC32MX_NVMCONSET, NVMCON_NVMWR);
182
183         status = pic32mx_wait_status_busy(bank, timeout);
184
185         /* lock flash registers */
186         target_write_u32(target, PIC32MX_NVMCONCLR, NVMCON_NVMWREN);
187
188         return status;
189 }
190
191 static int pic32mx_protect_check(struct flash_bank_s *bank)
192 {
193         target_t *target = bank->target;
194
195         u32 devcfg0;
196         int s;
197         int num_pages;
198
199         if (target->state != TARGET_HALTED)
200         {
201                 LOG_ERROR("Target not halted");
202                 return ERROR_TARGET_NOT_HALTED;
203         }
204
205         target_read_u32(target, PIC32MX_DEVCFG0, &devcfg0);
206         if((devcfg0 & (1<<28)) == 0) /* code protect bit */
207                 num_pages = 0xffff;  /* All pages protected */
208         else if(bank->base == PIC32MX_KSEG1_BOOT_FLASH)
209         {
210                 if(devcfg0 & (1<<24))
211                         num_pages = 0;       /* All pages unprotected */
212                 else
213                         num_pages = 0xffff;  /* All pages protected */
214         }
215         else /* pgm flash */
216                 num_pages = (~devcfg0 >> 12) & 0xff;
217         for (s = 0; s < bank->num_sectors && s < num_pages; s++)
218                 bank->sectors[s].is_protected = 1;
219         for (; s < bank->num_sectors; s++)
220                 bank->sectors[s].is_protected = 0;
221
222         return ERROR_OK;
223 }
224
225 static int pic32mx_erase(struct flash_bank_s *bank, int first, int last)
226 {
227         target_t *target = bank->target;
228         int i;
229         u32 status;
230
231         if (bank->target->state != TARGET_HALTED)
232         {
233                 LOG_ERROR("Target not halted");
234                 return ERROR_TARGET_NOT_HALTED;
235         }
236
237         if ((first == 0) && (last == (bank->num_sectors - 1)) && (bank->base == PIC32MX_KSEG0_PGM_FLASH || bank->base == PIC32MX_KSEG1_PGM_FLASH))
238         {
239                 LOG_DEBUG("Erasing entire program flash");
240                 status = pic32mx_nvm_exec(bank, NVMCON_OP_PFM_ERASE, 50);
241                 if( status & NVMCON_NVMERR )
242                         return ERROR_FLASH_OPERATION_FAILED;
243                 if( status & NVMCON_LVDERR )
244                         return ERROR_FLASH_OPERATION_FAILED;
245                 return ERROR_OK;
246         }
247
248         for (i = first; i <= last; i++)
249         {
250                 if(bank->base >= PIC32MX_KSEG1_PGM_FLASH)
251                         target_write_u32(target, PIC32MX_NVMADDR, KS1Virt2Phys(bank->base + bank->sectors[i].offset));
252                 else
253                         target_write_u32(target, PIC32MX_NVMADDR, KS0Virt2Phys(bank->base + bank->sectors[i].offset));
254
255                 status = pic32mx_nvm_exec(bank, NVMCON_OP_PAGE_ERASE, 10);
256
257                 if( status & NVMCON_NVMERR )
258                         return ERROR_FLASH_OPERATION_FAILED;
259                 if( status & NVMCON_LVDERR )
260                         return ERROR_FLASH_OPERATION_FAILED;
261                 bank->sectors[i].is_erased = 1;
262         }
263
264         return ERROR_OK;
265 }
266
267 static int pic32mx_protect(struct flash_bank_s *bank, int set, int first, int last)
268 {
269         pic32mx_flash_bank_t *pic32mx_info = NULL;
270         target_t *target = bank->target;
271 #if 0
272         u16 prot_reg[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
273         int i, reg, bit;
274         int status;
275         u32 protection;
276 #endif
277
278         pic32mx_info = bank->driver_priv;
279
280         if (target->state != TARGET_HALTED)
281         {
282                 LOG_ERROR("Target not halted");
283                 return ERROR_TARGET_NOT_HALTED;
284         }
285
286 #if 0
287         if ((first && (first % pic32mx_info->ppage_size)) || ((last + 1) && (last + 1) % pic32mx_info->ppage_size))
288         {
289                 LOG_WARNING("sector start/end incorrect - stm32 has %dK sector protection", pic32mx_info->ppage_size);
290                 return ERROR_FLASH_SECTOR_INVALID;
291         }
292
293         /* medium density - each bit refers to a 4bank protection
294          * high density - each bit refers to a 2bank protection */
295         target_read_u32(target, PIC32MX_FLASH_WRPR, &protection);
296
297         prot_reg[0] = (u16)protection;
298         prot_reg[1] = (u16)(protection >> 8);
299         prot_reg[2] = (u16)(protection >> 16);
300         prot_reg[3] = (u16)(protection >> 24);
301
302         if (pic32mx_info->ppage_size == 2)
303         {
304                 /* high density flash */
305
306                 /* bit 7 controls sector 62 - 255 protection */
307                 if (last > 61)
308                 {
309                         if (set)
310                                 prot_reg[3] &= ~(1 << 7);
311                         else
312                                 prot_reg[3] |= (1 << 7);
313                 }
314
315                 if (first > 61)
316                         first = 62;
317                 if (last > 61)
318                         last = 61;
319
320                 for (i = first; i <= last; i++)
321                 {
322                         reg = (i / pic32mx_info->ppage_size) / 8;
323                         bit = (i / pic32mx_info->ppage_size) - (reg * 8);
324
325                         if( set )
326                                 prot_reg[reg] &= ~(1 << bit);
327                         else
328                                 prot_reg[reg] |= (1 << bit);
329                 }
330         }
331         else
332         {
333                 /* medium density flash */
334                 for (i = first; i <= last; i++)
335                 {
336                         reg = (i / pic32mx_info->ppage_size) / 8;
337                         bit = (i / pic32mx_info->ppage_size) - (reg * 8);
338
339                         if( set )
340                                 prot_reg[reg] &= ~(1 << bit);
341                         else
342                                 prot_reg[reg] |= (1 << bit);
343                 }
344         }
345
346         if ((status = pic32mx_erase_options(bank)) != ERROR_OK)
347                 return status;
348
349         pic32mx_info->option_bytes.protection[0] = prot_reg[0];
350         pic32mx_info->option_bytes.protection[1] = prot_reg[1];
351         pic32mx_info->option_bytes.protection[2] = prot_reg[2];
352         pic32mx_info->option_bytes.protection[3] = prot_reg[3];
353
354         return pic32mx_write_options(bank);
355 #else
356         return ERROR_OK;
357 #endif
358 }
359
360 static int pic32mx_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
361 {
362         target_t *target = bank->target;
363         u32 buffer_size = 512;
364         working_area_t *source;
365         u32 address = bank->base + offset;
366         int retval = ERROR_OK;
367 #if 0
368         pic32mx_flash_bank_t *pic32mx_info = bank->driver_priv;
369         armv7m_algorithm_t armv7m_info;
370
371         u8 pic32mx_flash_write_code[] = {
372                                                                         /* write: */
373                 0xDF, 0xF8, 0x24, 0x40,         /* ldr  r4, PIC32MX_FLASH_CR */
374                 0x09, 0x4D,                                     /* ldr  r5, PIC32MX_FLASH_SR */
375                 0x4F, 0xF0, 0x01, 0x03,         /* mov  r3, #1 */
376                 0x23, 0x60,                                     /* str  r3, [r4, #0] */
377                 0x30, 0xF8, 0x02, 0x3B,         /* ldrh r3, [r0], #2 */
378                 0x21, 0xF8, 0x02, 0x3B,         /* strh r3, [r1], #2 */
379                                                                         /* busy: */
380                 0x2B, 0x68,                                     /* ldr  r3, [r5, #0] */
381                 0x13, 0xF0, 0x01, 0x0F,         /* tst  r3, #0x01 */
382                 0xFB, 0xD0,                                     /* beq  busy */
383                 0x13, 0xF0, 0x14, 0x0F,         /* tst  r3, #0x14 */
384                 0x01, 0xD1,                                     /* bne  exit */
385                 0x01, 0x3A,                                     /* subs r2, r2, #1 */
386                 0xED, 0xD1,                                     /* bne  write */
387                                                                         /* exit: */
388                 0xFE, 0xE7,                                     /* b exit */
389                 0x10, 0x20, 0x02, 0x40,         /* PIC32MX_FLASH_CR:    .word 0x40022010 */
390                 0x0C, 0x20, 0x02, 0x40          /* PIC32MX_FLASH_SR:    .word 0x4002200C */
391         };
392
393         /* flash write code */
394         if (target_alloc_working_area(target, sizeof(pic32mx_flash_write_code), &pic32mx_info->write_algorithm) != ERROR_OK)
395         {
396                 LOG_WARNING("no working area available, can't do block memory writes");
397                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
398         };
399
400         if ((retval=target_write_buffer(target, pic32mx_info->write_algorithm->address, sizeof(pic32mx_flash_write_code), pic32mx_flash_write_code))!=ERROR_OK)
401                 return retval;
402 #endif
403
404         /* memory buffer */
405         if (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
406         {
407 #if 0
408                 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
409                 if (pic32mx_info->write_algorithm)
410                         target_free_working_area(target, pic32mx_info->write_algorithm);
411 #endif
412
413                 LOG_WARNING("no large enough working area available, can't do block memory writes");
414                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
415         }
416
417         while (count >= buffer_size/4)
418         {
419                 u32 status;
420
421                 if ((retval = target_write_buffer(target, source->address, buffer_size, buffer))!=ERROR_OK) {
422                         LOG_ERROR("Failed to write row buffer (%d words) to RAM", buffer_size/4);
423                         break;
424                 }
425
426 #if 0
427                 buf_set_u32(reg_params[0].value, 0, 32, source->address);
428                 buf_set_u32(reg_params[1].value, 0, 32, address);
429                 buf_set_u32(reg_params[2].value, 0, 32, buffer_size/4);
430
431                 if ((retval = target->type->run_algorithm(target, 0, NULL, 4, reg_params, pic32mx_info->write_algorithm->address, \
432                                 pic32mx_info->write_algorithm->address + (sizeof(pic32mx_flash_write_code) - 10), 10000, &armv7m_info)) != ERROR_OK)
433                 {
434                         LOG_ERROR("error executing pic32mx flash write algorithm");
435                         retval = ERROR_FLASH_OPERATION_FAILED;
436                         break;
437                 }
438
439                 if (buf_get_u32(reg_params[3].value, 0, 32) & 0x14)
440                 {
441                         retval = ERROR_FLASH_OPERATION_FAILED;
442                         break;
443                 }
444 #endif
445                 status = pic32mx_write_row(bank, address, source->address);
446                 if( status & NVMCON_NVMERR ) {
447                         LOG_ERROR("Flash write error NVMERR (status=0x%08x)", status);
448                         retval = ERROR_FLASH_OPERATION_FAILED;
449                         break;
450                 }
451                 if( status & NVMCON_LVDERR ) {
452                         LOG_ERROR("Flash write error LVDERR (status=0x%08x)", status);
453                         retval = ERROR_FLASH_OPERATION_FAILED;
454                         break;
455                 }
456
457                 buffer  += buffer_size;
458                 address += buffer_size;
459                 count   -= buffer_size/4;
460         }
461
462         target_free_working_area(target, source);
463
464         while(count > 0)
465         {
466                 u32 value;
467                 memcpy(&value, buffer, sizeof(u32));
468
469                 u32 status = pic32mx_write_word(bank, address, value);
470                 if( status & NVMCON_NVMERR ) {
471                         LOG_ERROR("Flash write error NVMERR (status=0x%08x)", status);
472                         retval = ERROR_FLASH_OPERATION_FAILED;
473                         break;
474                 }
475                 if( status & NVMCON_LVDERR ) {
476                         LOG_ERROR("Flash write error LVDERR (status=0x%08x)", status);
477                         retval = ERROR_FLASH_OPERATION_FAILED;
478                         break;
479                 }
480
481                 buffer  += 4;
482                 address += 4;
483                 count--;
484         }
485
486         return retval;
487 }
488
489 static int pic32mx_write_word(struct flash_bank_s *bank, u32 address, u32 word)
490 {
491         target_t *target = bank->target;
492
493         if(bank->base >= PIC32MX_KSEG1_PGM_FLASH)
494                 target_write_u32(target, PIC32MX_NVMADDR, KS1Virt2Phys(address));
495         else
496                 target_write_u32(target, PIC32MX_NVMADDR, KS0Virt2Phys(address));
497         target_write_u32(target, PIC32MX_NVMDATA, word);
498
499         return pic32mx_nvm_exec(bank, NVMCON_OP_WORD_PROG, 5);
500 }
501
502 /*
503  * Write a 128 word (512 byte) row to flash address from RAM srcaddr.
504  */
505 static int pic32mx_write_row(struct flash_bank_s *bank, u32 address, u32 srcaddr)
506 {
507         target_t *target = bank->target;
508
509         LOG_DEBUG("addr: 0x%08x srcaddr: 0x%08x", address, srcaddr);
510
511         if(address >= PIC32MX_KSEG1_PGM_FLASH)
512                 target_write_u32(target, PIC32MX_NVMADDR,    KS1Virt2Phys(address));
513         else
514                 target_write_u32(target, PIC32MX_NVMADDR,    KS0Virt2Phys(address));
515         if(srcaddr >= PIC32MX_KSEG1_RAM)
516                 target_write_u32(target, PIC32MX_NVMSRCADDR, KS1Virt2Phys(srcaddr));
517         else
518                 target_write_u32(target, PIC32MX_NVMSRCADDR, KS0Virt2Phys(srcaddr));
519
520         return pic32mx_nvm_exec(bank, NVMCON_OP_ROW_PROG, 100);
521 }
522
523 static int pic32mx_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
524 {
525         u32 words_remaining = (count / 4);
526         u32 bytes_remaining = (count & 0x00000003);
527         u32 address = bank->base + offset;
528         u32 bytes_written = 0;
529         u32 status;
530         int retval;
531
532         if (bank->target->state != TARGET_HALTED)
533         {
534                 LOG_ERROR("Target not halted");
535                 return ERROR_TARGET_NOT_HALTED;
536         }
537
538         if (offset & 0x3)
539         {
540                 LOG_WARNING("offset 0x%x breaks required 4-byte alignment", offset);
541                 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
542         }
543
544         /* multiple words (4-byte) to be programmed? */
545         if (words_remaining > 0)
546         {
547                 /* try using a block write */
548                 if ((retval = pic32mx_write_block(bank, buffer, offset, words_remaining)) != ERROR_OK)
549                 {
550                         if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
551                         {
552                                 /* if block write failed (no sufficient working area),
553                                  * we use normal (slow) single dword accesses */
554                                 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
555                         }
556                         else if (retval == ERROR_FLASH_OPERATION_FAILED)
557                         {
558                                 LOG_ERROR("flash writing failed with error code: 0x%x", retval);
559                                 return ERROR_FLASH_OPERATION_FAILED;
560                         }
561                 }
562                 else
563                 {
564                         buffer += words_remaining * 4;
565                         address += words_remaining * 4;
566                         words_remaining = 0;
567                 }
568         }
569
570         while (words_remaining > 0)
571         {
572                 u32 value;
573                 memcpy(&value, buffer + bytes_written, sizeof(u32));
574
575                 status = pic32mx_write_word(bank, address, value);
576                 if( status & NVMCON_NVMERR )
577                         return ERROR_FLASH_OPERATION_FAILED;
578                 if( status & NVMCON_LVDERR )
579                         return ERROR_FLASH_OPERATION_FAILED;
580
581                 bytes_written += 4;
582                 words_remaining--;
583                 address += 4;
584         }
585
586         if (bytes_remaining)
587         {
588                 u32 value = 0xffffffff;
589                 memcpy(&value, buffer + bytes_written, bytes_remaining);
590
591                 status = pic32mx_write_word(bank, address, value);
592                 if( status & NVMCON_NVMERR )
593                         return ERROR_FLASH_OPERATION_FAILED;
594                 if( status & NVMCON_LVDERR )
595                         return ERROR_FLASH_OPERATION_FAILED;
596         }
597
598         return ERROR_OK;
599 }
600
601 static int pic32mx_probe(struct flash_bank_s *bank)
602 {
603         target_t *target = bank->target;
604         pic32mx_flash_bank_t *pic32mx_info = bank->driver_priv;
605         mips32_common_t *mips32 = target->arch_info;
606         mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
607         int i;
608         u16 num_pages = 0;
609         u32 device_id;
610         int page_size;
611
612         pic32mx_info->probed = 0;
613
614         device_id = ejtag_info->idcode;
615         LOG_INFO( "device id = 0x%08x (manuf 0x%03x dev 0x%02x, ver 0x%03x)", device_id, (device_id>>1)&0x7ff, (device_id>>12)&0xff, (device_id>>20)&0xfff );
616
617         if(((device_id>>1)&0x7ff) != PIC32MX_MANUF_ID) {
618                 LOG_WARNING( "Cannot identify target as a PIC32MX family." );
619                 return ERROR_FLASH_OPERATION_FAILED;
620         }
621
622         page_size = 4096;
623         if(bank->base == PIC32MX_KSEG1_BOOT_FLASH || bank->base == 1) {
624                 /* 0xBFC00000: Boot flash size fixed at 12k */
625                 num_pages = 12;
626         } else {
627                 /* 0xBD000000: Program flash size varies with device */
628                 for(i=0; pic32mx_devs[i].name != NULL; i++)
629                         if(pic32mx_devs[i].devid == ((device_id >> 12) & 0xff)) {
630                                 num_pages = pic32mx_devs[i].pfm_size;
631                                 break;
632                         }
633                 if(pic32mx_devs[i].name == NULL) {
634                         LOG_WARNING( "Cannot identify target as a PIC32MX family." );
635                         return ERROR_FLASH_OPERATION_FAILED;
636                 }
637         }
638
639 #if 0
640         if (bank->target->state != TARGET_HALTED)
641         {
642                 LOG_ERROR("Target not halted");
643                 return ERROR_TARGET_NOT_HALTED;
644         }
645
646         /* get flash size from target */
647         if (target_read_u16(target, 0x1FFFF7E0, &num_pages) != ERROR_OK)
648         {
649                 /* failed reading flash size, default to max target family */
650                 num_pages = 0xffff;
651         }
652 #endif
653
654         LOG_INFO( "flash size = %dkbytes", num_pages );
655
656         /* calculate numbers of pages */
657         num_pages /= (page_size / 1024);
658
659         if(bank->base == 0) bank->base = PIC32MX_KSEG1_PGM_FLASH;
660         if(bank->base == 1) bank->base = PIC32MX_KSEG1_BOOT_FLASH;
661         bank->size = (num_pages * page_size);
662         bank->num_sectors = num_pages;
663         bank->chip_width = 4;
664         bank->bus_width  = 4;
665         bank->sectors = malloc(sizeof(flash_sector_t) * num_pages);
666
667         for (i = 0; i < num_pages; i++)
668         {
669                 bank->sectors[i].offset = i * page_size;
670                 bank->sectors[i].size = page_size;
671                 bank->sectors[i].is_erased = -1;
672                 bank->sectors[i].is_protected = 1;
673         }
674
675         pic32mx_info->probed = 1;
676
677         return ERROR_OK;
678 }
679
680 static int pic32mx_auto_probe(struct flash_bank_s *bank)
681 {
682         pic32mx_flash_bank_t *pic32mx_info = bank->driver_priv;
683         if (pic32mx_info->probed)
684                 return ERROR_OK;
685         return pic32mx_probe(bank);
686 }
687
688 #if 0
689 static int pic32mx_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
690 {
691         return ERROR_OK;
692 }
693 #endif
694
695 static int pic32mx_info(struct flash_bank_s *bank, char *buf, int buf_size)
696 {
697         target_t *target = bank->target;
698         mips32_common_t *mips32 = target->arch_info;
699         mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
700         u32 device_id;
701         int printed = 0, i;
702
703         device_id = ejtag_info->idcode;
704
705         if(((device_id>>1)&0x7ff) != PIC32MX_MANUF_ID) {
706                 snprintf(buf, buf_size, "Cannot identify target as a PIC32MX family (manufacturer 0x%03d != 0x%03d)\n", (device_id>>1)&0x7ff, PIC32MX_MANUF_ID);
707                 return ERROR_FLASH_OPERATION_FAILED;
708         }
709         for(i=0; pic32mx_devs[i].name != NULL; i++)
710                 if(pic32mx_devs[i].devid == ((device_id >> 12) & 0xff)) {
711                         printed = snprintf(buf, buf_size, "PIC32MX%s", pic32mx_devs[i].name);
712                         break;
713                 }
714         if(pic32mx_devs[i].name == NULL) {
715                 snprintf(buf, buf_size, "Cannot identify target as a PIC32MX family\n");
716                 return ERROR_FLASH_OPERATION_FAILED;
717         }
718         buf += printed;
719         buf_size -= printed;
720         printed = snprintf(buf, buf_size, "  Ver: 0x%03x", (device_id>>20)&0xfff);
721
722         return ERROR_OK;
723 }
724
725 #if 0
726 int pic32mx_handle_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
727 {
728         flash_bank_t *bank;
729         target_t *target = NULL;
730         pic32mx_flash_bank_t *pic32mx_info = NULL;
731
732         if (argc < 1)
733         {
734                 command_print(cmd_ctx, "pic32mx lock <bank>");
735                 return ERROR_OK;
736         }
737
738         bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
739         if (!bank)
740         {
741                 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
742                 return ERROR_OK;
743         }
744
745         pic32mx_info = bank->driver_priv;
746
747         target = bank->target;
748
749         if (target->state != TARGET_HALTED)
750         {
751                 LOG_ERROR("Target not halted");
752                 return ERROR_TARGET_NOT_HALTED;
753         }
754
755         if (pic32mx_erase_options(bank) != ERROR_OK)
756         {
757                 command_print(cmd_ctx, "pic32mx failed to erase options");
758                 return ERROR_OK;
759         }
760
761         /* set readout protection */
762         pic32mx_info->option_bytes.RDP = 0;
763
764         if (pic32mx_write_options(bank) != ERROR_OK)
765         {
766                 command_print(cmd_ctx, "pic32mx failed to lock device");
767                 return ERROR_OK;
768         }
769
770         command_print(cmd_ctx, "pic32mx locked");
771
772         return ERROR_OK;
773 }
774
775 int pic32mx_handle_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
776 {
777         flash_bank_t *bank;
778         target_t *target = NULL;
779         pic32mx_flash_bank_t *pic32mx_info = NULL;
780
781         if (argc < 1)
782         {
783                 command_print(cmd_ctx, "pic32mx unlock <bank>");
784                 return ERROR_OK;
785         }
786
787         bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
788         if (!bank)
789         {
790                 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
791                 return ERROR_OK;
792         }
793
794         pic32mx_info = bank->driver_priv;
795
796         target = bank->target;
797
798         if (target->state != TARGET_HALTED)
799         {
800                 LOG_ERROR("Target not halted");
801                 return ERROR_TARGET_NOT_HALTED;
802         }
803
804         if (pic32mx_erase_options(bank) != ERROR_OK)
805         {
806                 command_print(cmd_ctx, "pic32mx failed to unlock device");
807                 return ERROR_OK;
808         }
809
810         if (pic32mx_write_options(bank) != ERROR_OK)
811         {
812                 command_print(cmd_ctx, "pic32mx failed to lock device");
813                 return ERROR_OK;
814         }
815
816         command_print(cmd_ctx, "pic32mx unlocked");
817
818         return ERROR_OK;
819 }
820 #endif
821
822 #if 0
823 static int pic32mx_chip_erase(struct flash_bank_s *bank)
824 {
825         target_t *target = bank->target;
826 #if 0
827         u32 status;
828 #endif
829
830         if (target->state != TARGET_HALTED)
831         {
832                 LOG_ERROR("Target not halted");
833                 return ERROR_TARGET_NOT_HALTED;
834         }
835
836         LOG_INFO("PIC32MX chip erase called");
837
838 #if 0
839         /* unlock option flash registers */
840         target_write_u32(target, PIC32MX_FLASH_KEYR, KEY1);
841         target_write_u32(target, PIC32MX_FLASH_KEYR, KEY2);
842
843         /* chip erase flash memory */
844         target_write_u32(target, PIC32MX_FLASH_CR, FLASH_MER);
845         target_write_u32(target, PIC32MX_FLASH_CR, FLASH_MER|FLASH_STRT);
846
847         status = pic32mx_wait_status_busy(bank, 10);
848
849         target_write_u32(target, PIC32MX_FLASH_CR, FLASH_LOCK);
850
851         if( status & FLASH_WRPRTERR )
852         {
853                 LOG_ERROR("pic32mx device protected");
854                 return ERROR_OK;
855         }
856
857         if( status & FLASH_PGERR )
858         {
859                 LOG_ERROR("pic32mx device programming failed");
860                 return ERROR_OK;
861         }
862 #endif
863
864         return ERROR_OK;
865 }
866 #endif
867
868 static int pic32mx_handle_chip_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
869 {
870 #if 0
871         flash_bank_t *bank;
872         int i;
873
874         if (argc != 0)
875         {
876                 command_print(cmd_ctx, "pic32mx chip_erase");
877                 return ERROR_OK;
878         }
879
880         bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
881         if (!bank)
882         {
883                 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
884                 return ERROR_OK;
885         }
886
887         if (pic32mx_chip_erase(bank) == ERROR_OK)
888         {
889                 /* set all sectors as erased */
890                 for (i = 0; i < bank->num_sectors; i++)
891                 {
892                         bank->sectors[i].is_erased = 1;
893                 }
894
895                 command_print(cmd_ctx, "pic32mx chip erase complete");
896         }
897         else
898         {
899                 command_print(cmd_ctx, "pic32mx chip erase failed");
900         }
901 #endif
902
903         return ERROR_OK;
904 }
905
906 static int pic32mx_handle_pgm_word_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
907 {
908         flash_bank_t *bank;
909         u32 address, value;
910         int status, res;
911
912         if (argc != 3)
913         {
914                 command_print(cmd_ctx, "pic32mx pgm_word <addr> <value> <bank>");
915                 return ERROR_OK;
916         }
917
918         address = strtoul(args[0], NULL, 0);
919         value   = strtoul(args[1], NULL, 0);
920
921         bank = get_flash_bank_by_num(strtoul(args[2], NULL, 0));
922         if (!bank)
923         {
924                 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[2]);
925                 return ERROR_OK;
926         }
927         if (address < bank->base || address >= (bank->base+bank->size))
928         {
929                 command_print(cmd_ctx, "flash address '%s' is out of bounds", args[0]);
930                 return ERROR_OK;
931         }
932
933         res = ERROR_OK;
934         status = pic32mx_write_word(bank, address, value);
935         if( status & NVMCON_NVMERR )
936                 res = ERROR_FLASH_OPERATION_FAILED;
937         if( status & NVMCON_LVDERR )
938                 res = ERROR_FLASH_OPERATION_FAILED;
939
940         if (res == ERROR_OK)
941                 command_print(cmd_ctx, "pic32mx pgm word complete");
942         else
943                 command_print(cmd_ctx, "pic32mx pgm word failed (status=0x%x)", status);
944
945         return ERROR_OK;
946 }