Holger Schurig <hs4233@mail.mn-solutions.de> fix warnings
[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 #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 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 status;
467
468                 status = pic32mx_write_word(bank, address, *(u32*)buffer);
469                 if( status & NVMCON_NVMERR ) {
470                         LOG_ERROR("Flash write error NVMERR (status=0x%08x)", status);
471                         retval = ERROR_FLASH_OPERATION_FAILED;
472                         break;
473                 }
474                 if( status & NVMCON_LVDERR ) {
475                         LOG_ERROR("Flash write error LVDERR (status=0x%08x)", status);
476                         retval = ERROR_FLASH_OPERATION_FAILED;
477                         break;
478                 }
479
480                 buffer  += 4;
481                 address += 4;
482                 count--;
483         }
484
485         return retval;
486 }
487
488 int pic32mx_write_word(struct flash_bank_s *bank, u32 address, u32 word)
489 {
490         target_t *target = bank->target;
491
492         if(bank->base >= PIC32MX_KSEG1_PGM_FLASH)
493                 target_write_u32(target, PIC32MX_NVMADDR, KS1Virt2Phys(address));
494         else
495                 target_write_u32(target, PIC32MX_NVMADDR, KS0Virt2Phys(address));
496         target_write_u32(target, PIC32MX_NVMDATA, word);
497
498         return pic32mx_nvm_exec(bank, NVMCON_OP_WORD_PROG, 5);
499 }
500
501 /*
502  * Write a 128 word (512 byte) row to flash address from RAM srcaddr.
503  */
504 int pic32mx_write_row(struct flash_bank_s *bank, u32 address, u32 srcaddr)
505 {
506         target_t *target = bank->target;
507
508         LOG_DEBUG("addr: 0x%08x srcaddr: 0x%08x", address, srcaddr);
509
510         if(address >= PIC32MX_KSEG1_PGM_FLASH)
511                 target_write_u32(target, PIC32MX_NVMADDR,    KS1Virt2Phys(address));
512         else
513                 target_write_u32(target, PIC32MX_NVMADDR,    KS0Virt2Phys(address));
514         if(srcaddr >= PIC32MX_KSEG1_RAM)
515                 target_write_u32(target, PIC32MX_NVMSRCADDR, KS1Virt2Phys(srcaddr));
516         else
517                 target_write_u32(target, PIC32MX_NVMSRCADDR, KS0Virt2Phys(srcaddr));
518
519         return pic32mx_nvm_exec(bank, NVMCON_OP_ROW_PROG, 100);
520 }
521
522 int pic32mx_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
523 {
524         u32 words_remaining = (count / 4);
525         u32 bytes_remaining = (count & 0x00000003);
526         u32 address = bank->base + offset;
527         u32 bytes_written = 0;
528         u32 status;
529         u32 retval;
530
531         if (bank->target->state != TARGET_HALTED)
532         {
533                 LOG_ERROR("Target not halted");
534                 return ERROR_TARGET_NOT_HALTED;
535         }
536
537         if (offset & 0x3)
538         {
539                 LOG_WARNING("offset 0x%x breaks required 4-byte alignment", offset);
540                 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
541         }
542
543         /* multiple words (4-byte) to be programmed? */
544         if (words_remaining > 0)
545         {
546                 /* try using a block write */
547                 if ((retval = pic32mx_write_block(bank, buffer, offset, words_remaining)) != ERROR_OK)
548                 {
549                         if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
550                         {
551                                 /* if block write failed (no sufficient working area),
552                                  * we use normal (slow) single dword accesses */
553                                 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
554                         }
555                         else if (retval == ERROR_FLASH_OPERATION_FAILED)
556                         {
557                                 LOG_ERROR("flash writing failed with error code: 0x%x", retval);
558                                 return ERROR_FLASH_OPERATION_FAILED;
559                         }
560                 }
561                 else
562                 {
563                         buffer += words_remaining * 4;
564                         address += words_remaining * 4;
565                         words_remaining = 0;
566                 }
567         }
568
569         while (words_remaining > 0)
570         {
571                 status = pic32mx_write_word(bank, address, *(u32*)(buffer + bytes_written));
572
573                 if( status & NVMCON_NVMERR )
574                         return ERROR_FLASH_OPERATION_FAILED;
575                 if( status & NVMCON_LVDERR )
576                         return ERROR_FLASH_OPERATION_FAILED;
577
578                 bytes_written += 4;
579                 words_remaining--;
580                 address += 4;
581         }
582
583         if (bytes_remaining)
584         {
585                 u8 last_word[4] = {0xff, 0xff, 0xff, 0xff};
586                 int i = 0;
587
588                 while(bytes_remaining > 0)
589                 {
590                         /* Assumes little endian */
591                         last_word[i++] = *(buffer + bytes_written);
592                         bytes_remaining--;
593                         bytes_written++;
594                 }
595
596                 status = pic32mx_write_word(bank, address, *(u32*)last_word);
597
598                 if( status & NVMCON_NVMERR )
599                         return ERROR_FLASH_OPERATION_FAILED;
600                 if( status & NVMCON_LVDERR )
601                         return ERROR_FLASH_OPERATION_FAILED;
602         }
603
604         return ERROR_OK;
605 }
606
607 int pic32mx_probe(struct flash_bank_s *bank)
608 {
609         target_t *target = bank->target;
610         pic32mx_flash_bank_t *pic32mx_info = bank->driver_priv;
611         mips32_common_t *mips32 = target->arch_info;
612         mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
613         int i;
614         u16 num_pages;
615         u32 device_id;
616         int page_size;
617
618         pic32mx_info->probed = 0;
619
620         device_id = ejtag_info->idcode;
621         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 );
622
623         if(((device_id>>1)&0x7ff) != PIC32MX_MANUF_ID) {
624                 LOG_WARNING( "Cannot identify target as a PIC32MX family." );
625                 return ERROR_FLASH_OPERATION_FAILED;
626         }
627
628         page_size = 4096;
629         if(bank->base == PIC32MX_KSEG1_BOOT_FLASH || bank->base == 1) {
630                 /* 0xBFC00000: Boot flash size fixed at 12k */
631                 num_pages = 12;
632         } else {
633                 /* 0xBD000000: Program flash size varies with device */
634                 for(i=0; pic32mx_devs[i].name != NULL; i++)
635                         if(pic32mx_devs[i].devid == ((device_id >> 12) & 0xff)) {
636                                 num_pages = pic32mx_devs[i].pfm_size;
637                                 break;
638                         }
639                 if(pic32mx_devs[i].name == NULL) {
640                         LOG_WARNING( "Cannot identify target as a PIC32MX family." );
641                         return ERROR_FLASH_OPERATION_FAILED;
642                 }
643         }
644
645 #if 0
646         if (bank->target->state != TARGET_HALTED)
647         {
648                 LOG_ERROR("Target not halted");
649                 return ERROR_TARGET_NOT_HALTED;
650         }
651
652         /* get flash size from target */
653         if (target_read_u16(target, 0x1FFFF7E0, &num_pages) != ERROR_OK)
654         {
655                 /* failed reading flash size, default to max target family */
656                 num_pages = 0xffff;
657         }
658 #endif
659
660         LOG_INFO( "flash size = %dkbytes", num_pages );
661
662         /* calculate numbers of pages */
663         num_pages /= (page_size / 1024);
664
665         if(bank->base == 0) bank->base = PIC32MX_KSEG1_PGM_FLASH;
666         if(bank->base == 1) bank->base = PIC32MX_KSEG1_BOOT_FLASH;
667         bank->size = (num_pages * page_size);
668         bank->num_sectors = num_pages;
669         bank->chip_width = 4;
670         bank->bus_width  = 4;
671         bank->sectors = malloc(sizeof(flash_sector_t) * num_pages);
672
673         for (i = 0; i < num_pages; i++)
674         {
675                 bank->sectors[i].offset = i * page_size;
676                 bank->sectors[i].size = page_size;
677                 bank->sectors[i].is_erased = -1;
678                 bank->sectors[i].is_protected = 1;
679         }
680
681         pic32mx_info->probed = 1;
682
683         return ERROR_OK;
684 }
685
686 int pic32mx_auto_probe(struct flash_bank_s *bank)
687 {
688         pic32mx_flash_bank_t *pic32mx_info = bank->driver_priv;
689         if (pic32mx_info->probed)
690                 return ERROR_OK;
691         return pic32mx_probe(bank);
692 }
693
694 int pic32mx_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
695 {
696         return ERROR_OK;
697 }
698
699 int pic32mx_info(struct flash_bank_s *bank, char *buf, int buf_size)
700 {
701         target_t *target = bank->target;
702         mips32_common_t *mips32 = target->arch_info;
703         mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
704         u32 device_id;
705         int printed, i;
706
707         device_id = ejtag_info->idcode;
708
709         if(((device_id>>1)&0x7ff) != PIC32MX_MANUF_ID) {
710                 snprintf(buf, buf_size, "Cannot identify target as a PIC32MX family (manufacturer 0x%03d != 0x%03d)\n", (device_id>>1)&0x7ff, PIC32MX_MANUF_ID);
711                 return ERROR_FLASH_OPERATION_FAILED;
712         }
713         for(i=0; pic32mx_devs[i].name != NULL; i++)
714                 if(pic32mx_devs[i].devid == ((device_id >> 12) & 0xff)) {
715                         printed = snprintf(buf, buf_size, "PIC32MX%s", pic32mx_devs[i].name);
716                         break;
717                 }
718         if(pic32mx_devs[i].name == NULL) {
719                 snprintf(buf, buf_size, "Cannot identify target as a PIC32MX family\n");
720                 return ERROR_FLASH_OPERATION_FAILED;
721         }
722         buf += printed;
723         buf_size -= printed;
724         printed = snprintf(buf, buf_size, "  Ver: 0x%03x", (device_id>>20)&0xfff);
725
726         return ERROR_OK;
727 }
728
729 #if 0
730 int pic32mx_handle_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
731 {
732         flash_bank_t *bank;
733         target_t *target = NULL;
734         pic32mx_flash_bank_t *pic32mx_info = NULL;
735
736         if (argc < 1)
737         {
738                 command_print(cmd_ctx, "pic32mx lock <bank>");
739                 return ERROR_OK;
740         }
741
742         bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
743         if (!bank)
744         {
745                 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
746                 return ERROR_OK;
747         }
748
749         pic32mx_info = bank->driver_priv;
750
751         target = bank->target;
752
753         if (target->state != TARGET_HALTED)
754         {
755                 LOG_ERROR("Target not halted");
756                 return ERROR_TARGET_NOT_HALTED;
757         }
758
759         if (pic32mx_erase_options(bank) != ERROR_OK)
760         {
761                 command_print(cmd_ctx, "pic32mx failed to erase options");
762                 return ERROR_OK;
763         }
764
765         /* set readout protection */
766         pic32mx_info->option_bytes.RDP = 0;
767
768         if (pic32mx_write_options(bank) != ERROR_OK)
769         {
770                 command_print(cmd_ctx, "pic32mx failed to lock device");
771                 return ERROR_OK;
772         }
773
774         command_print(cmd_ctx, "pic32mx locked");
775
776         return ERROR_OK;
777 }
778
779 int pic32mx_handle_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
780 {
781         flash_bank_t *bank;
782         target_t *target = NULL;
783         pic32mx_flash_bank_t *pic32mx_info = NULL;
784
785         if (argc < 1)
786         {
787                 command_print(cmd_ctx, "pic32mx unlock <bank>");
788                 return ERROR_OK;
789         }
790
791         bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
792         if (!bank)
793         {
794                 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
795                 return ERROR_OK;
796         }
797
798         pic32mx_info = bank->driver_priv;
799
800         target = bank->target;
801
802         if (target->state != TARGET_HALTED)
803         {
804                 LOG_ERROR("Target not halted");
805                 return ERROR_TARGET_NOT_HALTED;
806         }
807
808         if (pic32mx_erase_options(bank) != ERROR_OK)
809         {
810                 command_print(cmd_ctx, "pic32mx failed to unlock device");
811                 return ERROR_OK;
812         }
813
814         if (pic32mx_write_options(bank) != ERROR_OK)
815         {
816                 command_print(cmd_ctx, "pic32mx failed to lock device");
817                 return ERROR_OK;
818         }
819
820         command_print(cmd_ctx, "pic32mx unlocked");
821
822         return ERROR_OK;
823 }
824 #endif
825
826 int pic32mx_chip_erase(struct flash_bank_s *bank)
827 {
828         target_t *target = bank->target;
829 #if 0
830         u32 status;
831 #endif
832
833         if (target->state != TARGET_HALTED)
834         {
835                 LOG_ERROR("Target not halted");
836                 return ERROR_TARGET_NOT_HALTED;
837         }
838
839         LOG_INFO("PIC32MX chip erase called");
840
841 #if 0
842         /* unlock option flash registers */
843         target_write_u32(target, PIC32MX_FLASH_KEYR, KEY1);
844         target_write_u32(target, PIC32MX_FLASH_KEYR, KEY2);
845
846         /* chip erase flash memory */
847         target_write_u32(target, PIC32MX_FLASH_CR, FLASH_MER);
848         target_write_u32(target, PIC32MX_FLASH_CR, FLASH_MER|FLASH_STRT);
849
850         status = pic32mx_wait_status_busy(bank, 10);
851
852         target_write_u32(target, PIC32MX_FLASH_CR, FLASH_LOCK);
853
854         if( status & FLASH_WRPRTERR )
855         {
856                 LOG_ERROR("pic32mx device protected");
857                 return ERROR_OK;
858         }
859
860         if( status & FLASH_PGERR )
861         {
862                 LOG_ERROR("pic32mx device programming failed");
863                 return ERROR_OK;
864         }
865 #endif
866
867         return ERROR_OK;
868 }
869
870 int pic32mx_handle_chip_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
871 {
872 #if 0
873         flash_bank_t *bank;
874         int i;
875
876         if (argc != 0)
877         {
878                 command_print(cmd_ctx, "pic32mx chip_erase");
879                 return ERROR_OK;
880         }
881
882         bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
883         if (!bank)
884         {
885                 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
886                 return ERROR_OK;
887         }
888
889         if (pic32mx_chip_erase(bank) == ERROR_OK)
890         {
891                 /* set all sectors as erased */
892                 for (i = 0; i < bank->num_sectors; i++)
893                 {
894                         bank->sectors[i].is_erased = 1;
895                 }
896
897                 command_print(cmd_ctx, "pic32mx chip erase complete");
898         }
899         else
900         {
901                 command_print(cmd_ctx, "pic32mx chip erase failed");
902         }
903 #endif
904
905         return ERROR_OK;
906 }
907
908 int pic32mx_handle_pgm_word_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
909 {
910         flash_bank_t *bank;
911         u32 address, value;
912         int status, res;
913
914         if (argc != 3)
915         {
916                 command_print(cmd_ctx, "pic32mx pgm_word <addr> <value> <bank>");
917                 return ERROR_OK;
918         }
919
920         address = strtoul(args[0], NULL, 0);
921         value   = strtoul(args[1], NULL, 0);
922
923         bank = get_flash_bank_by_num(strtoul(args[2], NULL, 0));
924         if (!bank)
925         {
926                 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[2]);
927                 return ERROR_OK;
928         }
929         if (address < bank->base || address >= (bank->base+bank->size))
930         {
931                 command_print(cmd_ctx, "flash address '%s' is out of bounds", args[0]);
932                 return ERROR_OK;
933         }
934
935         res = ERROR_OK;
936         status = pic32mx_write_word(bank, address, value);
937         if( status & NVMCON_NVMERR )
938                 res = ERROR_FLASH_OPERATION_FAILED;
939         if( status & NVMCON_LVDERR )
940                 res = ERROR_FLASH_OPERATION_FAILED;
941
942         if (res == ERROR_OK)
943                 command_print(cmd_ctx, "pic32mx pgm word complete");
944         else
945                 command_print(cmd_ctx, "pic32mx pgm word failed (status=0x%x)", status);
946
947         return ERROR_OK;
948 }