John McCarthy <jgmcc@magma.ca> pic32mx flash fixups and speedups
[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 int pic32mx_register_commands(struct command_context_s *cmd_ctx);
70 int pic32mx_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
71 int pic32mx_erase(struct flash_bank_s *bank, int first, int last);
72 int pic32mx_protect(struct flash_bank_s *bank, int set, int first, int last);
73 int pic32mx_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
74 int pic32mx_write_row(struct flash_bank_s *bank, u32 address, u32 srcaddr);
75 int pic32mx_write_word(struct flash_bank_s *bank, u32 address, u32 word);
76 int pic32mx_probe(struct flash_bank_s *bank);
77 int pic32mx_auto_probe(struct flash_bank_s *bank);
78 int pic32mx_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
79 int pic32mx_protect_check(struct flash_bank_s *bank);
80 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 int pic32mx_handle_chip_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
87 int pic32mx_handle_pgm_word_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
88 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 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 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 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 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 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 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 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 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         u16 prot_reg[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
272         int i, reg, bit;
273         int status;
274         u32 protection;
275
276         pic32mx_info = bank->driver_priv;
277
278         if (target->state != TARGET_HALTED)
279         {
280                 LOG_ERROR("Target not halted");
281                 return ERROR_TARGET_NOT_HALTED;
282         }
283
284 #if 0
285         if ((first && (first % pic32mx_info->ppage_size)) || ((last + 1) && (last + 1) % pic32mx_info->ppage_size))
286         {
287                 LOG_WARNING("sector start/end incorrect - stm32 has %dK sector protection", pic32mx_info->ppage_size);
288                 return ERROR_FLASH_SECTOR_INVALID;
289         }
290
291         /* medium density - each bit refers to a 4bank protection
292          * high density - each bit refers to a 2bank protection */
293         target_read_u32(target, PIC32MX_FLASH_WRPR, &protection);
294
295         prot_reg[0] = (u16)protection;
296         prot_reg[1] = (u16)(protection >> 8);
297         prot_reg[2] = (u16)(protection >> 16);
298         prot_reg[3] = (u16)(protection >> 24);
299
300         if (pic32mx_info->ppage_size == 2)
301         {
302                 /* high density flash */
303
304                 /* bit 7 controls sector 62 - 255 protection */
305                 if (last > 61)
306                 {
307                         if (set)
308                                 prot_reg[3] &= ~(1 << 7);
309                         else
310                                 prot_reg[3] |= (1 << 7);
311                 }
312
313                 if (first > 61)
314                         first = 62;
315                 if (last > 61)
316                         last = 61;
317
318                 for (i = first; i <= last; i++)
319                 {
320                         reg = (i / pic32mx_info->ppage_size) / 8;
321                         bit = (i / pic32mx_info->ppage_size) - (reg * 8);
322
323                         if( set )
324                                 prot_reg[reg] &= ~(1 << bit);
325                         else
326                                 prot_reg[reg] |= (1 << bit);
327                 }
328         }
329         else
330         {
331                 /* medium density flash */
332                 for (i = first; i <= last; i++)
333                 {
334                         reg = (i / pic32mx_info->ppage_size) / 8;
335                         bit = (i / pic32mx_info->ppage_size) - (reg * 8);
336
337                         if( set )
338                                 prot_reg[reg] &= ~(1 << bit);
339                         else
340                                 prot_reg[reg] |= (1 << bit);
341                 }
342         }
343
344         if ((status = pic32mx_erase_options(bank)) != ERROR_OK)
345                 return status;
346
347         pic32mx_info->option_bytes.protection[0] = prot_reg[0];
348         pic32mx_info->option_bytes.protection[1] = prot_reg[1];
349         pic32mx_info->option_bytes.protection[2] = prot_reg[2];
350         pic32mx_info->option_bytes.protection[3] = prot_reg[3];
351
352         return pic32mx_write_options(bank);
353 #else
354         return ERROR_OK;
355 #endif
356 }
357
358 int pic32mx_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
359 {
360         target_t *target = bank->target;
361         u32 buffer_size = 512;
362         working_area_t *source;
363         u32 address = bank->base + offset;
364         int retval = ERROR_OK;
365 #if 0
366         pic32mx_flash_bank_t *pic32mx_info = bank->driver_priv;
367         armv7m_algorithm_t armv7m_info;
368
369         u8 pic32mx_flash_write_code[] = {
370                                                                         /* write: */
371                 0xDF, 0xF8, 0x24, 0x40,         /* ldr  r4, PIC32MX_FLASH_CR */
372                 0x09, 0x4D,                                     /* ldr  r5, PIC32MX_FLASH_SR */
373                 0x4F, 0xF0, 0x01, 0x03,         /* mov  r3, #1 */
374                 0x23, 0x60,                                     /* str  r3, [r4, #0] */
375                 0x30, 0xF8, 0x02, 0x3B,         /* ldrh r3, [r0], #2 */
376                 0x21, 0xF8, 0x02, 0x3B,         /* strh r3, [r1], #2 */
377                                                                         /* busy: */
378                 0x2B, 0x68,                                     /* ldr  r3, [r5, #0] */
379                 0x13, 0xF0, 0x01, 0x0F,         /* tst  r3, #0x01 */
380                 0xFB, 0xD0,                                     /* beq  busy */
381                 0x13, 0xF0, 0x14, 0x0F,         /* tst  r3, #0x14 */
382                 0x01, 0xD1,                                     /* bne  exit */
383                 0x01, 0x3A,                                     /* subs r2, r2, #1 */
384                 0xED, 0xD1,                                     /* bne  write */
385                                                                         /* exit: */
386                 0xFE, 0xE7,                                     /* b exit */
387                 0x10, 0x20, 0x02, 0x40,         /* PIC32MX_FLASH_CR:    .word 0x40022010 */
388                 0x0C, 0x20, 0x02, 0x40          /* PIC32MX_FLASH_SR:    .word 0x4002200C */
389         };
390
391         /* flash write code */
392         if (target_alloc_working_area(target, sizeof(pic32mx_flash_write_code), &pic32mx_info->write_algorithm) != ERROR_OK)
393         {
394                 LOG_WARNING("no working area available, can't do block memory writes");
395                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
396         };
397
398         if ((retval=target_write_buffer(target, pic32mx_info->write_algorithm->address, sizeof(pic32mx_flash_write_code), pic32mx_flash_write_code))!=ERROR_OK)
399                 return retval;
400 #endif
401
402         /* memory buffer */
403         if (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
404         {
405 #if 0
406                 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
407                 if (pic32mx_info->write_algorithm)
408                         target_free_working_area(target, pic32mx_info->write_algorithm);
409 #endif
410
411                 LOG_WARNING("no large enough working area available, can't do block memory writes");
412                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
413         }
414
415         while (count >= buffer_size/4)
416         {
417                 u32 status;
418
419                 if ((retval = target_write_buffer(target, source->address, buffer_size, buffer))!=ERROR_OK) {
420                         LOG_ERROR("Failed to write row buffer (%d words) to RAM", buffer_size/4);
421                         break;
422                 }
423
424 #if 0
425                 buf_set_u32(reg_params[0].value, 0, 32, source->address);
426                 buf_set_u32(reg_params[1].value, 0, 32, address);
427                 buf_set_u32(reg_params[2].value, 0, 32, buffer_size/4);
428
429                 if ((retval = target->type->run_algorithm(target, 0, NULL, 4, reg_params, pic32mx_info->write_algorithm->address, \
430                                 pic32mx_info->write_algorithm->address + (sizeof(pic32mx_flash_write_code) - 10), 10000, &armv7m_info)) != ERROR_OK)
431                 {
432                         LOG_ERROR("error executing pic32mx flash write algorithm");
433                         retval = ERROR_FLASH_OPERATION_FAILED;
434                         break;
435                 }
436
437                 if (buf_get_u32(reg_params[3].value, 0, 32) & 0x14)
438                 {
439                         retval = ERROR_FLASH_OPERATION_FAILED;
440                         break;
441                 }
442 #endif
443                 status = pic32mx_write_row(bank, address, source->address);
444                 if( status & NVMCON_NVMERR ) {
445                         LOG_ERROR("Flash write error NVMERR (status=0x%08x)", status);
446                         retval = ERROR_FLASH_OPERATION_FAILED;
447                         break;
448                 }
449                 if( status & NVMCON_LVDERR ) {
450                         LOG_ERROR("Flash write error LVDERR (status=0x%08x)", status);
451                         retval = ERROR_FLASH_OPERATION_FAILED;
452                         break;
453                 }
454
455                 buffer  += buffer_size;
456                 address += buffer_size;
457                 count   -= buffer_size/4;
458         }
459
460         target_free_working_area(target, source);
461
462         while(count > 0)
463         {
464                 u32 status;
465
466                 status = pic32mx_write_word(bank, address, *(u32*)buffer);
467                 if( status & NVMCON_NVMERR ) {
468                         LOG_ERROR("Flash write error NVMERR (status=0x%08x)", status);
469                         retval = ERROR_FLASH_OPERATION_FAILED;
470                         break;
471                 }
472                 if( status & NVMCON_LVDERR ) {
473                         LOG_ERROR("Flash write error LVDERR (status=0x%08x)", status);
474                         retval = ERROR_FLASH_OPERATION_FAILED;
475                         break;
476                 }
477
478                 buffer  += 4;
479                 address += 4;
480                 count--;
481         }
482
483         return retval;
484 }
485
486 int pic32mx_write_word(struct flash_bank_s *bank, u32 address, u32 word)
487 {
488         target_t *target = bank->target;
489
490         if(bank->base >= PIC32MX_KSEG1_PGM_FLASH)
491                 target_write_u32(target, PIC32MX_NVMADDR, KS1Virt2Phys(address));
492         else
493                 target_write_u32(target, PIC32MX_NVMADDR, KS0Virt2Phys(address));
494         target_write_u32(target, PIC32MX_NVMDATA, word);
495
496         return pic32mx_nvm_exec(bank, NVMCON_OP_WORD_PROG, 5);
497 }
498
499 /*
500  * Write a 128 word (512 byte) row to flash address from RAM srcaddr.
501  */
502 int pic32mx_write_row(struct flash_bank_s *bank, u32 address, u32 srcaddr)
503 {
504         target_t *target = bank->target;
505
506         LOG_DEBUG("addr: 0x%08x srcaddr: 0x%08x", address, srcaddr);
507
508         if(address >= PIC32MX_KSEG1_PGM_FLASH)
509                 target_write_u32(target, PIC32MX_NVMADDR,    KS1Virt2Phys(address));
510         else
511                 target_write_u32(target, PIC32MX_NVMADDR,    KS0Virt2Phys(address));
512         if(srcaddr >= PIC32MX_KSEG1_RAM)
513                 target_write_u32(target, PIC32MX_NVMSRCADDR, KS1Virt2Phys(srcaddr));
514         else
515                 target_write_u32(target, PIC32MX_NVMSRCADDR, KS0Virt2Phys(srcaddr));
516
517         return pic32mx_nvm_exec(bank, NVMCON_OP_ROW_PROG, 100);
518 }
519
520 int pic32mx_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
521 {
522         u32 words_remaining = (count / 4);
523         u32 bytes_remaining = (count & 0x00000003);
524         u32 address = bank->base + offset;
525         u32 bytes_written = 0;
526         u32 status;
527         u32 retval;
528
529         if (bank->target->state != TARGET_HALTED)
530         {
531                 LOG_ERROR("Target not halted");
532                 return ERROR_TARGET_NOT_HALTED;
533         }
534
535         if (offset & 0x3)
536         {
537                 LOG_WARNING("offset 0x%x breaks required 4-byte alignment", offset);
538                 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
539         }
540
541         /* multiple words (4-byte) to be programmed? */
542         if (words_remaining > 0)
543         {
544                 /* try using a block write */
545                 if ((retval = pic32mx_write_block(bank, buffer, offset, words_remaining)) != ERROR_OK)
546                 {
547                         if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
548                         {
549                                 /* if block write failed (no sufficient working area),
550                                  * we use normal (slow) single dword accesses */
551                                 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
552                         }
553                         else if (retval == ERROR_FLASH_OPERATION_FAILED)
554                         {
555                                 LOG_ERROR("flash writing failed with error code: 0x%x", retval);
556                                 return ERROR_FLASH_OPERATION_FAILED;
557                         }
558                 }
559                 else
560                 {
561                         buffer += words_remaining * 4;
562                         address += words_remaining * 4;
563                         words_remaining = 0;
564                 }
565         }
566
567         while (words_remaining > 0)
568         {
569                 status = pic32mx_write_word(bank, address, *(u32*)(buffer + bytes_written));
570
571                 if( status & NVMCON_NVMERR )
572                         return ERROR_FLASH_OPERATION_FAILED;
573                 if( status & NVMCON_LVDERR )
574                         return ERROR_FLASH_OPERATION_FAILED;
575
576                 bytes_written += 4;
577                 words_remaining--;
578                 address += 4;
579         }
580
581         if (bytes_remaining)
582         {
583                 u8 last_word[4] = {0xff, 0xff, 0xff, 0xff};
584                 int i = 0;
585
586                 while(bytes_remaining > 0)
587                 {
588                         /* Assumes little endian */
589                         last_word[i++] = *(buffer + bytes_written);
590                         bytes_remaining--;
591                         bytes_written++;
592                 }
593
594                 status = pic32mx_write_word(bank, address, *(u32*)last_word);
595
596                 if( status & NVMCON_NVMERR )
597                         return ERROR_FLASH_OPERATION_FAILED;
598                 if( status & NVMCON_LVDERR )
599                         return ERROR_FLASH_OPERATION_FAILED;
600         }
601
602         return ERROR_OK;
603 }
604
605 int pic32mx_probe(struct flash_bank_s *bank)
606 {
607         target_t *target = bank->target;
608         pic32mx_flash_bank_t *pic32mx_info = bank->driver_priv;
609         mips32_common_t *mips32 = target->arch_info;
610         mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
611         int i;
612         u16 num_pages;
613         u32 device_id;
614         int page_size;
615
616         pic32mx_info->probed = 0;
617
618         device_id = ejtag_info->idcode;
619         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 );
620
621         if(((device_id>>1)&0x7ff) != PIC32MX_MANUF_ID) {
622                 LOG_WARNING( "Cannot identify target as a PIC32MX family." );
623                 return ERROR_FLASH_OPERATION_FAILED;
624         }
625
626         page_size = 4096;
627         if(bank->base == PIC32MX_KSEG1_BOOT_FLASH || bank->base == 1) {
628                 /* 0xBFC00000: Boot flash size fixed at 12k */
629                 num_pages = 12;
630         } else {
631                 /* 0xBD000000: Program flash size varies with device */
632                 for(i=0; pic32mx_devs[i].name != NULL; i++)
633                         if(pic32mx_devs[i].devid == ((device_id >> 12) & 0xff)) {
634                                 num_pages = pic32mx_devs[i].pfm_size;
635                                 break;
636                         }
637                 if(pic32mx_devs[i].name == NULL) {
638                         LOG_WARNING( "Cannot identify target as a PIC32MX family." );
639                         return ERROR_FLASH_OPERATION_FAILED;
640                 }
641         }
642
643 #if 0
644         if (bank->target->state != TARGET_HALTED)
645         {
646                 LOG_ERROR("Target not halted");
647                 return ERROR_TARGET_NOT_HALTED;
648         }
649
650         /* get flash size from target */
651         if (target_read_u16(target, 0x1FFFF7E0, &num_pages) != ERROR_OK)
652         {
653                 /* failed reading flash size, default to max target family */
654                 num_pages = 0xffff;
655         }
656 #endif
657
658         LOG_INFO( "flash size = %dkbytes", num_pages );
659
660         /* calculate numbers of pages */
661         num_pages /= (page_size / 1024);
662
663         if(bank->base == 0) bank->base = PIC32MX_KSEG1_PGM_FLASH;
664         if(bank->base == 1) bank->base = PIC32MX_KSEG1_BOOT_FLASH;
665         bank->size = (num_pages * page_size);
666         bank->num_sectors = num_pages;
667         bank->chip_width = 4;
668         bank->bus_width  = 4;
669         bank->sectors = malloc(sizeof(flash_sector_t) * num_pages);
670
671         for (i = 0; i < num_pages; i++)
672         {
673                 bank->sectors[i].offset = i * page_size;
674                 bank->sectors[i].size = page_size;
675                 bank->sectors[i].is_erased = -1;
676                 bank->sectors[i].is_protected = 1;
677         }
678
679         pic32mx_info->probed = 1;
680
681         return ERROR_OK;
682 }
683
684 int pic32mx_auto_probe(struct flash_bank_s *bank)
685 {
686         pic32mx_flash_bank_t *pic32mx_info = bank->driver_priv;
687         if (pic32mx_info->probed)
688                 return ERROR_OK;
689         return pic32mx_probe(bank);
690 }
691
692 int pic32mx_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
693 {
694         return ERROR_OK;
695 }
696
697 int pic32mx_info(struct flash_bank_s *bank, char *buf, int buf_size)
698 {
699         target_t *target = bank->target;
700         mips32_common_t *mips32 = target->arch_info;
701         mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
702         u32 device_id;
703         int printed, i;
704
705         device_id = ejtag_info->idcode;
706
707         if(((device_id>>1)&0x7ff) != PIC32MX_MANUF_ID) {
708                 snprintf(buf, buf_size, "Cannot identify target as a PIC32MX family (manufacturer 0x%03d != 0x%03d)\n", (device_id>>1)&0x7ff, PIC32MX_MANUF_ID);
709                 return ERROR_FLASH_OPERATION_FAILED;
710         }
711         for(i=0; pic32mx_devs[i].name != NULL; i++)
712                 if(pic32mx_devs[i].devid == ((device_id >> 12) & 0xff)) {
713                         printed = snprintf(buf, buf_size, "PIC32MX%s", pic32mx_devs[i].name);
714                         break;
715                 }
716         if(pic32mx_devs[i].name == NULL) {
717                 snprintf(buf, buf_size, "Cannot identify target as a PIC32MX family\n");
718                 return ERROR_FLASH_OPERATION_FAILED;
719         }
720         buf += printed;
721         buf_size -= printed;
722         printed = snprintf(buf, buf_size, "  Ver: 0x%03x", (device_id>>20)&0xfff);
723
724         return ERROR_OK;
725 }
726
727 #if 0
728 int pic32mx_handle_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
729 {
730         flash_bank_t *bank;
731         target_t *target = NULL;
732         pic32mx_flash_bank_t *pic32mx_info = NULL;
733
734         if (argc < 1)
735         {
736                 command_print(cmd_ctx, "pic32mx lock <bank>");
737                 return ERROR_OK;
738         }
739
740         bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
741         if (!bank)
742         {
743                 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
744                 return ERROR_OK;
745         }
746
747         pic32mx_info = bank->driver_priv;
748
749         target = bank->target;
750
751         if (target->state != TARGET_HALTED)
752         {
753                 LOG_ERROR("Target not halted");
754                 return ERROR_TARGET_NOT_HALTED;
755         }
756
757         if (pic32mx_erase_options(bank) != ERROR_OK)
758         {
759                 command_print(cmd_ctx, "pic32mx failed to erase options");
760                 return ERROR_OK;
761         }
762
763         /* set readout protection */
764         pic32mx_info->option_bytes.RDP = 0;
765
766         if (pic32mx_write_options(bank) != ERROR_OK)
767         {
768                 command_print(cmd_ctx, "pic32mx failed to lock device");
769                 return ERROR_OK;
770         }
771
772         command_print(cmd_ctx, "pic32mx locked");
773
774         return ERROR_OK;
775 }
776
777 int pic32mx_handle_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
778 {
779         flash_bank_t *bank;
780         target_t *target = NULL;
781         pic32mx_flash_bank_t *pic32mx_info = NULL;
782
783         if (argc < 1)
784         {
785                 command_print(cmd_ctx, "pic32mx unlock <bank>");
786                 return ERROR_OK;
787         }
788
789         bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
790         if (!bank)
791         {
792                 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
793                 return ERROR_OK;
794         }
795
796         pic32mx_info = bank->driver_priv;
797
798         target = bank->target;
799
800         if (target->state != TARGET_HALTED)
801         {
802                 LOG_ERROR("Target not halted");
803                 return ERROR_TARGET_NOT_HALTED;
804         }
805
806         if (pic32mx_erase_options(bank) != ERROR_OK)
807         {
808                 command_print(cmd_ctx, "pic32mx failed to unlock device");
809                 return ERROR_OK;
810         }
811
812         if (pic32mx_write_options(bank) != ERROR_OK)
813         {
814                 command_print(cmd_ctx, "pic32mx failed to lock device");
815                 return ERROR_OK;
816         }
817
818         command_print(cmd_ctx, "pic32mx unlocked");
819
820         return ERROR_OK;
821 }
822 #endif
823
824 int pic32mx_chip_erase(struct flash_bank_s *bank)
825 {
826         target_t *target = bank->target;
827         u32 status;
828
829         if (target->state != TARGET_HALTED)
830         {
831                 LOG_ERROR("Target not halted");
832                 return ERROR_TARGET_NOT_HALTED;
833         }
834
835         LOG_INFO("PIC32MX chip erase called");
836
837 #if 0
838         /* unlock option flash registers */
839         target_write_u32(target, PIC32MX_FLASH_KEYR, KEY1);
840         target_write_u32(target, PIC32MX_FLASH_KEYR, KEY2);
841
842         /* chip erase flash memory */
843         target_write_u32(target, PIC32MX_FLASH_CR, FLASH_MER);
844         target_write_u32(target, PIC32MX_FLASH_CR, FLASH_MER|FLASH_STRT);
845
846         status = pic32mx_wait_status_busy(bank, 10);
847
848         target_write_u32(target, PIC32MX_FLASH_CR, FLASH_LOCK);
849
850         if( status & FLASH_WRPRTERR )
851         {
852                 LOG_ERROR("pic32mx device protected");
853                 return ERROR_OK;
854         }
855
856         if( status & FLASH_PGERR )
857         {
858                 LOG_ERROR("pic32mx device programming failed");
859                 return ERROR_OK;
860         }
861 #endif
862
863         return ERROR_OK;
864 }
865
866 int pic32mx_handle_chip_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
867 {
868         flash_bank_t *bank;
869         int i;
870
871 #if 0
872         if (argc != 0)
873         {
874                 command_print(cmd_ctx, "pic32mx chip_erase");
875                 return ERROR_OK;
876         }
877
878         bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
879         if (!bank)
880         {
881                 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
882                 return ERROR_OK;
883         }
884
885         if (pic32mx_chip_erase(bank) == ERROR_OK)
886         {
887                 /* set all sectors as erased */
888                 for (i = 0; i < bank->num_sectors; i++)
889                 {
890                         bank->sectors[i].is_erased = 1;
891                 }
892
893                 command_print(cmd_ctx, "pic32mx chip erase complete");
894         }
895         else
896         {
897                 command_print(cmd_ctx, "pic32mx chip erase failed");
898         }
899 #endif
900
901         return ERROR_OK;
902 }
903
904 int pic32mx_handle_pgm_word_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
905 {
906         flash_bank_t *bank;
907         u32 address, value;
908         int status, res;
909
910         if (argc != 3)
911         {
912                 command_print(cmd_ctx, "pic32mx pgm_word <addr> <value> <bank>");
913                 return ERROR_OK;
914         }
915
916         address = strtoul(args[0], NULL, 0);
917         value   = strtoul(args[1], NULL, 0);
918
919         bank = get_flash_bank_by_num(strtoul(args[2], NULL, 0));
920         if (!bank)
921         {
922                 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[2]);
923                 return ERROR_OK;
924         }
925         if (address < bank->base || address >= (bank->base+bank->size))
926         {
927                 command_print(cmd_ctx, "flash address '%s' is out of bounds", args[0]);
928                 return ERROR_OK;
929         }
930
931         res = ERROR_OK;
932         status = pic32mx_write_word(bank, address, value);
933         if( status & NVMCON_NVMERR )
934                 res = ERROR_FLASH_OPERATION_FAILED;
935         if( status & NVMCON_LVDERR )
936                 res = ERROR_FLASH_OPERATION_FAILED;
937
938         if (res == ERROR_OK)
939                 command_print(cmd_ctx, "pic32mx pgm word complete");
940         else
941                 command_print(cmd_ctx, "pic32mx pgm word failed (status=0x%x)", status);
942
943         return ERROR_OK;
944 }