The following patches was applied:
[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 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 static 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 static 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 static 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 static 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 static 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 #if 0
695 static int pic32mx_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
696 {
697         return ERROR_OK;
698 }
699 #endif
700
701 static int pic32mx_info(struct flash_bank_s *bank, char *buf, int buf_size)
702 {
703         target_t *target = bank->target;
704         mips32_common_t *mips32 = target->arch_info;
705         mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
706         u32 device_id;
707         int printed, i;
708
709         device_id = ejtag_info->idcode;
710
711         if(((device_id>>1)&0x7ff) != PIC32MX_MANUF_ID) {
712                 snprintf(buf, buf_size, "Cannot identify target as a PIC32MX family (manufacturer 0x%03d != 0x%03d)\n", (device_id>>1)&0x7ff, PIC32MX_MANUF_ID);
713                 return ERROR_FLASH_OPERATION_FAILED;
714         }
715         for(i=0; pic32mx_devs[i].name != NULL; i++)
716                 if(pic32mx_devs[i].devid == ((device_id >> 12) & 0xff)) {
717                         printed = snprintf(buf, buf_size, "PIC32MX%s", pic32mx_devs[i].name);
718                         break;
719                 }
720         if(pic32mx_devs[i].name == NULL) {
721                 snprintf(buf, buf_size, "Cannot identify target as a PIC32MX family\n");
722                 return ERROR_FLASH_OPERATION_FAILED;
723         }
724         buf += printed;
725         buf_size -= printed;
726         printed = snprintf(buf, buf_size, "  Ver: 0x%03x", (device_id>>20)&0xfff);
727
728         return ERROR_OK;
729 }
730
731 #if 0
732 int pic32mx_handle_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
733 {
734         flash_bank_t *bank;
735         target_t *target = NULL;
736         pic32mx_flash_bank_t *pic32mx_info = NULL;
737
738         if (argc < 1)
739         {
740                 command_print(cmd_ctx, "pic32mx lock <bank>");
741                 return ERROR_OK;
742         }
743
744         bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
745         if (!bank)
746         {
747                 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
748                 return ERROR_OK;
749         }
750
751         pic32mx_info = bank->driver_priv;
752
753         target = bank->target;
754
755         if (target->state != TARGET_HALTED)
756         {
757                 LOG_ERROR("Target not halted");
758                 return ERROR_TARGET_NOT_HALTED;
759         }
760
761         if (pic32mx_erase_options(bank) != ERROR_OK)
762         {
763                 command_print(cmd_ctx, "pic32mx failed to erase options");
764                 return ERROR_OK;
765         }
766
767         /* set readout protection */
768         pic32mx_info->option_bytes.RDP = 0;
769
770         if (pic32mx_write_options(bank) != ERROR_OK)
771         {
772                 command_print(cmd_ctx, "pic32mx failed to lock device");
773                 return ERROR_OK;
774         }
775
776         command_print(cmd_ctx, "pic32mx locked");
777
778         return ERROR_OK;
779 }
780
781 int pic32mx_handle_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
782 {
783         flash_bank_t *bank;
784         target_t *target = NULL;
785         pic32mx_flash_bank_t *pic32mx_info = NULL;
786
787         if (argc < 1)
788         {
789                 command_print(cmd_ctx, "pic32mx unlock <bank>");
790                 return ERROR_OK;
791         }
792
793         bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
794         if (!bank)
795         {
796                 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
797                 return ERROR_OK;
798         }
799
800         pic32mx_info = bank->driver_priv;
801
802         target = bank->target;
803
804         if (target->state != TARGET_HALTED)
805         {
806                 LOG_ERROR("Target not halted");
807                 return ERROR_TARGET_NOT_HALTED;
808         }
809
810         if (pic32mx_erase_options(bank) != ERROR_OK)
811         {
812                 command_print(cmd_ctx, "pic32mx failed to unlock device");
813                 return ERROR_OK;
814         }
815
816         if (pic32mx_write_options(bank) != ERROR_OK)
817         {
818                 command_print(cmd_ctx, "pic32mx failed to lock device");
819                 return ERROR_OK;
820         }
821
822         command_print(cmd_ctx, "pic32mx unlocked");
823
824         return ERROR_OK;
825 }
826 #endif
827
828 #if 0
829 static int pic32mx_chip_erase(struct flash_bank_s *bank)
830 {
831         target_t *target = bank->target;
832 #if 0
833         u32 status;
834 #endif
835
836         if (target->state != TARGET_HALTED)
837         {
838                 LOG_ERROR("Target not halted");
839                 return ERROR_TARGET_NOT_HALTED;
840         }
841
842         LOG_INFO("PIC32MX chip erase called");
843
844 #if 0
845         /* unlock option flash registers */
846         target_write_u32(target, PIC32MX_FLASH_KEYR, KEY1);
847         target_write_u32(target, PIC32MX_FLASH_KEYR, KEY2);
848
849         /* chip erase flash memory */
850         target_write_u32(target, PIC32MX_FLASH_CR, FLASH_MER);
851         target_write_u32(target, PIC32MX_FLASH_CR, FLASH_MER|FLASH_STRT);
852
853         status = pic32mx_wait_status_busy(bank, 10);
854
855         target_write_u32(target, PIC32MX_FLASH_CR, FLASH_LOCK);
856
857         if( status & FLASH_WRPRTERR )
858         {
859                 LOG_ERROR("pic32mx device protected");
860                 return ERROR_OK;
861         }
862
863         if( status & FLASH_PGERR )
864         {
865                 LOG_ERROR("pic32mx device programming failed");
866                 return ERROR_OK;
867         }
868 #endif
869
870         return ERROR_OK;
871 }
872 #endif
873
874 static int pic32mx_handle_chip_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
875 {
876 #if 0
877         flash_bank_t *bank;
878         int i;
879
880         if (argc != 0)
881         {
882                 command_print(cmd_ctx, "pic32mx chip_erase");
883                 return ERROR_OK;
884         }
885
886         bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
887         if (!bank)
888         {
889                 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
890                 return ERROR_OK;
891         }
892
893         if (pic32mx_chip_erase(bank) == ERROR_OK)
894         {
895                 /* set all sectors as erased */
896                 for (i = 0; i < bank->num_sectors; i++)
897                 {
898                         bank->sectors[i].is_erased = 1;
899                 }
900
901                 command_print(cmd_ctx, "pic32mx chip erase complete");
902         }
903         else
904         {
905                 command_print(cmd_ctx, "pic32mx chip erase failed");
906         }
907 #endif
908
909         return ERROR_OK;
910 }
911
912 static int pic32mx_handle_pgm_word_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
913 {
914         flash_bank_t *bank;
915         u32 address, value;
916         int status, res;
917
918         if (argc != 3)
919         {
920                 command_print(cmd_ctx, "pic32mx pgm_word <addr> <value> <bank>");
921                 return ERROR_OK;
922         }
923
924         address = strtoul(args[0], NULL, 0);
925         value   = strtoul(args[1], NULL, 0);
926
927         bank = get_flash_bank_by_num(strtoul(args[2], NULL, 0));
928         if (!bank)
929         {
930                 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[2]);
931                 return ERROR_OK;
932         }
933         if (address < bank->base || address >= (bank->base+bank->size))
934         {
935                 command_print(cmd_ctx, "flash address '%s' is out of bounds", args[0]);
936                 return ERROR_OK;
937         }
938
939         res = ERROR_OK;
940         status = pic32mx_write_word(bank, address, value);
941         if( status & NVMCON_NVMERR )
942                 res = ERROR_FLASH_OPERATION_FAILED;
943         if( status & NVMCON_LVDERR )
944                 res = ERROR_FLASH_OPERATION_FAILED;
945
946         if (res == ERROR_OK)
947                 command_print(cmd_ctx, "pic32mx pgm word complete");
948         else
949                 command_print(cmd_ctx, "pic32mx pgm word failed (status=0x%x)", status);
950
951         return ERROR_OK;
952 }