ce5bffb56fc4db3793530b8a870e3fb823f6615c
[openocd.git] / src / flash / nor / 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 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
25 ***************************************************************************/
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include <jtag/jtag.h>
32 #include "imp.h"
33 #include <target/algorithm.h>
34 #include <target/mips32.h>
35 #include <target/mips_m4k.h>
36
37 #define PIC32MX_MANUF_ID 0x029
38
39 /* pic32mx memory locations */
40
41 #define PIC32MX_PHYS_RAM 0x00000000
42 #define PIC32MX_PHYS_PGM_FLASH 0x1D000000
43 #define PIC32MX_PHYS_PERIPHERALS 0x1F800000
44 #define PIC32MX_PHYS_BOOT_FLASH 0x1FC00000
45
46 /*
47 * Translate Virtual and Physical addresses.
48 * Note: These macros only work for KSEG0/KSEG1 addresses.
49 */
50
51 #define Virt2Phys(v) ((v) & 0x1FFFFFFF)
52
53 /* pic32mx configuration register locations */
54
55 #define PIC32MX_DEVCFG0_1_2 0xBFC00BFC
56 #define PIC32MX_DEVCFG0 0xBFC02FFC
57 #define PIC32MX_DEVCFG1 0xBFC02FF8
58 #define PIC32MX_DEVCFG2 0xBFC02FF4
59 #define PIC32MX_DEVCFG3 0xBFC02FF0
60 #define PIC32MX_DEVID 0xBF80F220
61
62 #define PIC32MX_BMXPFMSZ 0xBF882060
63 #define PIC32MX_BMXBOOTSZ 0xBF882070
64 #define PIC32MX_BMXDRMSZ 0xBF882040
65
66 /* pic32mx flash controller register locations */
67
68 #define PIC32MX_NVMCON 0xBF80F400
69 #define PIC32MX_NVMCONCLR 0xBF80F404
70 #define PIC32MX_NVMCONSET 0xBF80F408
71 #define PIC32MX_NVMCONINV 0xBF80F40C
72 #define NVMCON_NVMWR (1 << 15)
73 #define NVMCON_NVMWREN (1 << 14)
74 #define NVMCON_NVMERR (1 << 13)
75 #define NVMCON_LVDERR (1 << 12)
76 #define NVMCON_LVDSTAT (1 << 11)
77 #define NVMCON_OP_PFM_ERASE 0x5
78 #define NVMCON_OP_PAGE_ERASE 0x4
79 #define NVMCON_OP_ROW_PROG 0x3
80 #define NVMCON_OP_WORD_PROG 0x1
81 #define NVMCON_OP_NOP 0x0
82
83 #define PIC32MX_NVMKEY 0xBF80F410
84 #define PIC32MX_NVMADDR 0xBF80F420
85 #define PIC32MX_NVMADDRCLR 0xBF80F424
86 #define PIC32MX_NVMADDRSET 0xBF80F428
87 #define PIC32MX_NVMADDRINV 0xBF80F42C
88 #define PIC32MX_NVMDATA 0xBF80F430
89 #define PIC32MX_NVMSRCADDR 0xBF80F440
90
91 /* flash unlock keys */
92
93 #define NVMKEY1 0xAA996655
94 #define NVMKEY2 0x556699AA
95
96 #define MX_1_2 1 /* PIC32mx1xx/2xx */
97
98 struct pic32mx_flash_bank {
99 int probed;
100 int dev_type; /* Default 0. 1 for Pic32MX1XX/2XX variant */
101 };
102
103 /*
104 * DEVID values as per PIC32MX Flash Programming Specification Rev J
105 */
106
107 static const struct pic32mx_devs_s {
108 uint32_t devid;
109 const char *name;
110 } pic32mx_devs[] = {
111 {0x04A07053, "110F016B"},
112 {0x04A09053, "110F016C"},
113 {0x04A0B053, "110F016D"},
114 {0x04A06053, "120F032B"},
115 {0x04A08053, "120F032C"},
116 {0x04A0A053, "120F032D"},
117 {0x04D07053, "130F064B"},
118 {0x04D09053, "130F064C"},
119 {0x04D0B053, "130F064D"},
120 {0x04D06053, "150F128B"},
121 {0x04D08053, "150F128C"},
122 {0x04D0A053, "150F128D"},
123 {0x04A01053, "210F016B"},
124 {0x04A03053, "210F016C"},
125 {0x04A05053, "210F016D"},
126 {0x04A00053, "220F032B"},
127 {0x04A02053, "220F032C"},
128 {0x04A04053, "220F032D"},
129 {0x04D01053, "230F064B"},
130 {0x04D03053, "230F064C"},
131 {0x04D05053, "230F064D"},
132 {0x04D00053, "250F128B"},
133 {0x04D02053, "250F128C"},
134 {0x04D04053, "250F128D"},
135 {0x00938053, "360F512L"},
136 {0x00934053, "360F256L"},
137 {0x0092D053, "340F128L"},
138 {0x0092A053, "320F128L"},
139 {0x00916053, "340F512H"},
140 {0x00912053, "340F256H"},
141 {0x0090D053, "340F128H"},
142 {0x0090A053, "320F128H"},
143 {0x00906053, "320F064H"},
144 {0x00902053, "320F032H"},
145 {0x00978053, "460F512L"},
146 {0x00974053, "460F256L"},
147 {0x0096D053, "440F128L"},
148 {0x00952053, "440F256H"},
149 {0x00956053, "440F512H"},
150 {0x0094D053, "440F128H"},
151 {0x00942053, "420F032H"},
152 {0x04307053, "795F512L"},
153 {0x0430E053, "795F512H"},
154 {0x04306053, "775F512L"},
155 {0x0430D053, "775F512H"},
156 {0x04312053, "775F256L"},
157 {0x04303053, "775F256H"},
158 {0x04417053, "764F128L"},
159 {0x0440B053, "764F128H"},
160 {0x04341053, "695F512L"},
161 {0x04325053, "695F512H"},
162 {0x04311053, "675F512L"},
163 {0x0430C053, "675F512H"},
164 {0x04305053, "675F256L"},
165 {0x0430B053, "675F256H"},
166 {0x04413053, "664F128L"},
167 {0x04407053, "664F128H"},
168 {0x04411053, "664F064L"},
169 {0x04405053, "664F064H"},
170 {0x0430F053, "575F512L"},
171 {0x04309053, "575F512H"},
172 {0x04333053, "575F256L"},
173 {0x04317053, "575F256H"},
174 {0x0440F053, "564F128L"},
175 {0x04403053, "564F128H"},
176 {0x0440D053, "564F064L"},
177 {0x04401053, "564F064H"},
178 {0x04400053, "534F064H"},
179 {0x0440C053, "534F064L"},
180 {0x00000000, NULL}
181 };
182
183 /* flash bank pic32mx <base> <size> 0 0 <target#>
184 */
185 FLASH_BANK_COMMAND_HANDLER(pic32mx_flash_bank_command)
186 {
187 struct pic32mx_flash_bank *pic32mx_info;
188
189 if (CMD_ARGC < 6)
190 return ERROR_COMMAND_SYNTAX_ERROR;
191
192 pic32mx_info = malloc(sizeof(struct pic32mx_flash_bank));
193 bank->driver_priv = pic32mx_info;
194
195 pic32mx_info->probed = 0;
196 pic32mx_info->dev_type = 0;
197
198 return ERROR_OK;
199 }
200
201 static uint32_t pic32mx_get_flash_status(struct flash_bank *bank)
202 {
203 struct target *target = bank->target;
204 uint32_t status;
205
206 target_read_u32(target, PIC32MX_NVMCON, &status);
207
208 return status;
209 }
210
211 static uint32_t pic32mx_wait_status_busy(struct flash_bank *bank, int timeout)
212 {
213 uint32_t status;
214
215 /* wait for busy to clear */
216 while (((status = pic32mx_get_flash_status(bank)) & NVMCON_NVMWR) && (timeout-- > 0)) {
217 LOG_DEBUG("status: 0x%" PRIx32, status);
218 alive_sleep(1);
219 }
220 if (timeout <= 0)
221 LOG_DEBUG("timeout: status: 0x%" PRIx32, status);
222
223 return status;
224 }
225
226 static int pic32mx_nvm_exec(struct flash_bank *bank, uint32_t op, uint32_t timeout)
227 {
228 struct target *target = bank->target;
229 uint32_t status;
230
231 target_write_u32(target, PIC32MX_NVMCON, NVMCON_NVMWREN | op);
232
233 /* unlock flash registers */
234 target_write_u32(target, PIC32MX_NVMKEY, NVMKEY1);
235 target_write_u32(target, PIC32MX_NVMKEY, NVMKEY2);
236
237 /* start operation */
238 target_write_u32(target, PIC32MX_NVMCONSET, NVMCON_NVMWR);
239
240 status = pic32mx_wait_status_busy(bank, timeout);
241
242 /* lock flash registers */
243 target_write_u32(target, PIC32MX_NVMCONCLR, NVMCON_NVMWREN);
244
245 return status;
246 }
247
248 static int pic32mx_protect_check(struct flash_bank *bank)
249 {
250 struct target *target = bank->target;
251 struct pic32mx_flash_bank *pic32mx_info = bank->driver_priv;
252
253 uint32_t config0_address;
254 uint32_t devcfg0;
255 int s;
256 int num_pages;
257
258 if (target->state != TARGET_HALTED) {
259 LOG_ERROR("Target not halted");
260 return ERROR_TARGET_NOT_HALTED;
261 }
262
263 if (pic32mx_info->dev_type == MX_1_2)
264 config0_address = PIC32MX_DEVCFG0_1_2;
265 else
266 config0_address = PIC32MX_DEVCFG0;
267
268 target_read_u32(target, config0_address, &devcfg0);
269
270 if ((devcfg0 & (1 << 28)) == 0) /* code protect bit */
271 num_pages = 0xffff; /* All pages protected */
272 else if (Virt2Phys(bank->base) == PIC32MX_PHYS_BOOT_FLASH) {
273 if (devcfg0 & (1 << 24))
274 num_pages = 0; /* All pages unprotected */
275 else
276 num_pages = 0xffff; /* All pages protected */
277 } else {
278 /* pgm flash */
279 if (pic32mx_info->dev_type == MX_1_2)
280 num_pages = (~devcfg0 >> 10) & 0x3f;
281 else
282 num_pages = (~devcfg0 >> 12) & 0xff;
283 }
284
285 for (s = 0; s < bank->num_sectors && s < num_pages; s++)
286 bank->sectors[s].is_protected = 1;
287 for (; s < bank->num_sectors; s++)
288 bank->sectors[s].is_protected = 0;
289
290 return ERROR_OK;
291 }
292
293 static int pic32mx_erase(struct flash_bank *bank, int first, int last)
294 {
295 struct target *target = bank->target;
296 int i;
297 uint32_t status;
298
299 if (bank->target->state != TARGET_HALTED) {
300 LOG_ERROR("Target not halted");
301 return ERROR_TARGET_NOT_HALTED;
302 }
303
304 if ((first == 0) && (last == (bank->num_sectors - 1))
305 && (Virt2Phys(bank->base) == PIC32MX_PHYS_PGM_FLASH)) {
306 /* this will only erase the Program Flash (PFM), not the Boot Flash (BFM)
307 * we need to use the MTAP to perform a full erase */
308 LOG_DEBUG("Erasing entire program flash");
309 status = pic32mx_nvm_exec(bank, NVMCON_OP_PFM_ERASE, 50);
310 if (status & NVMCON_NVMERR)
311 return ERROR_FLASH_OPERATION_FAILED;
312 if (status & NVMCON_LVDERR)
313 return ERROR_FLASH_OPERATION_FAILED;
314 return ERROR_OK;
315 }
316
317 for (i = first; i <= last; i++) {
318 target_write_u32(target, PIC32MX_NVMADDR, Virt2Phys(bank->base + bank->sectors[i].offset));
319
320 status = pic32mx_nvm_exec(bank, NVMCON_OP_PAGE_ERASE, 10);
321
322 if (status & NVMCON_NVMERR)
323 return ERROR_FLASH_OPERATION_FAILED;
324 if (status & NVMCON_LVDERR)
325 return ERROR_FLASH_OPERATION_FAILED;
326 bank->sectors[i].is_erased = 1;
327 }
328
329 return ERROR_OK;
330 }
331
332 static int pic32mx_protect(struct flash_bank *bank, int set, int first, int last)
333 {
334 struct target *target = bank->target;
335
336 if (target->state != TARGET_HALTED) {
337 LOG_ERROR("Target not halted");
338 return ERROR_TARGET_NOT_HALTED;
339 }
340
341 return ERROR_OK;
342 }
343
344 /* see contib/loaders/flash/pic32mx.s for src */
345
346 static uint32_t pic32mx_flash_write_code[] = {
347 /* write: */
348 0x3C08AA99, /* lui $t0, 0xaa99 */
349 0x35086655, /* ori $t0, 0x6655 */
350 0x3C095566, /* lui $t1, 0x5566 */
351 0x352999AA, /* ori $t1, 0x99aa */
352 0x3C0ABF80, /* lui $t2, 0xbf80 */
353 0x354AF400, /* ori $t2, 0xf400 */
354 0x340B4003, /* ori $t3, $zero, 0x4003 */
355 0x340C8000, /* ori $t4, $zero, 0x8000 */
356 /* write_row: */
357 0x2CD30080, /* sltiu $s3, $a2, 128 */
358 0x16600008, /* bne $s3, $zero, write_word */
359 0x340D4000, /* ori $t5, $zero, 0x4000 */
360 0xAD450020, /* sw $a1, 32($t2) */
361 0xAD440040, /* sw $a0, 64($t2) */
362 0x04110016, /* bal progflash */
363 0x24840200, /* addiu $a0, $a0, 512 */
364 0x24A50200, /* addiu $a1, $a1, 512 */
365 0x1000FFF7, /* beq $zero, $zero, write_row */
366 0x24C6FF80, /* addiu $a2, $a2, -128 */
367 /* write_word: */
368 0x3C15A000, /* lui $s5, 0xa000 */
369 0x36B50000, /* ori $s5, $s5, 0x0 */
370 0x00952025, /* or $a0, $a0, $s5 */
371 0x10000008, /* beq $zero, $zero, next_word */
372 0x340B4001, /* ori $t3, $zero, 0x4001 */
373 /* prog_word: */
374 0x8C940000, /* lw $s4, 0($a0) */
375 0xAD540030, /* sw $s4, 48($t2) */
376 0xAD450020, /* sw $a1, 32($t2) */
377 0x04110009, /* bal progflash */
378 0x24840004, /* addiu $a0, $a0, 4 */
379 0x24A50004, /* addiu $a1, $a1, 4 */
380 0x24C6FFFF, /* addiu $a2, $a2, -1 */
381 /* next_word: */
382 0x14C0FFF8, /* bne $a2, $zero, prog_word */
383 0x00000000, /* nop */
384 /* done: */
385 0x10000002, /* beq $zero, $zero, exit */
386 0x24040000, /* addiu $a0, $zero, 0 */
387 /* error: */
388 0x26240000, /* addiu $a0, $s1, 0 */
389 /* exit: */
390 0x7000003F, /* sdbbp */
391 /* progflash: */
392 0xAD4B0000, /* sw $t3, 0($t2) */
393 0xAD480010, /* sw $t0, 16($t2) */
394 0xAD490010, /* sw $t1, 16($t2) */
395 0xAD4C0008, /* sw $t4, 8($t2) */
396 /* waitflash: */
397 0x8D500000, /* lw $s0, 0($t2) */
398 0x020C8024, /* and $s0, $s0, $t4 */
399 0x1600FFFD, /* bne $s0, $zero, waitflash */
400 0x00000000, /* nop */
401 0x00000000, /* nop */
402 0x00000000, /* nop */
403 0x00000000, /* nop */
404 0x00000000, /* nop */
405 0x8D510000, /* lw $s1, 0($t2) */
406 0x30113000, /* andi $s1, $zero, 0x3000 */
407 0x1620FFEF, /* bne $s1, $zero, error */
408 0xAD4D0004, /* sw $t5, 4($t2) */
409 0x03E00008, /* jr $ra */
410 0x00000000 /* nop */
411 };
412
413 static int pic32mx_write_block(struct flash_bank *bank, const uint8_t *buffer,
414 uint32_t offset, uint32_t count)
415 {
416 struct target *target = bank->target;
417 uint32_t buffer_size = 16384;
418 struct working_area *write_algorithm;
419 struct working_area *source;
420 uint32_t address = bank->base + offset;
421 struct reg_param reg_params[3];
422 uint32_t row_size;
423 int retval = ERROR_OK;
424
425 struct pic32mx_flash_bank *pic32mx_info = bank->driver_priv;
426 struct mips32_algorithm mips32_info;
427
428 /* flash write code */
429 if (target_alloc_working_area(target, sizeof(pic32mx_flash_write_code),
430 &write_algorithm) != ERROR_OK) {
431 LOG_WARNING("no working area available, can't do block memory writes");
432 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
433 }
434
435 /* Change values for counters and row size, depending on variant */
436 if (pic32mx_info->dev_type == MX_1_2) {
437 /* 128 byte row */
438 pic32mx_flash_write_code[8] = 0x2CD30020;
439 pic32mx_flash_write_code[14] = 0x24840080;
440 pic32mx_flash_write_code[15] = 0x24A50080;
441 pic32mx_flash_write_code[17] = 0x24C6FFE0;
442 row_size = 128;
443 } else {
444 /* 512 byte row */
445 pic32mx_flash_write_code[8] = 0x2CD30080;
446 pic32mx_flash_write_code[14] = 0x24840200;
447 pic32mx_flash_write_code[15] = 0x24A50200;
448 pic32mx_flash_write_code[17] = 0x24C6FF80;
449 row_size = 512;
450 }
451
452 uint8_t code[sizeof(pic32mx_flash_write_code)];
453 target_buffer_set_u32_array(target, code, ARRAY_SIZE(pic32mx_flash_write_code),
454 pic32mx_flash_write_code);
455 retval = target_write_buffer(target, write_algorithm->address, sizeof(code), code);
456 if (retval != ERROR_OK)
457 return retval;
458
459 /* memory buffer */
460 while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {
461 buffer_size /= 2;
462 if (buffer_size <= 256) {
463 /* we already allocated the writing code, but failed to get a
464 * buffer, free the algorithm */
465 target_free_working_area(target, write_algorithm);
466
467 LOG_WARNING("no large enough working area available, can't do block memory writes");
468 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
469 }
470 }
471
472 mips32_info.common_magic = MIPS32_COMMON_MAGIC;
473 mips32_info.isa_mode = MIPS32_ISA_MIPS32;
474
475 init_reg_param(&reg_params[0], "r4", 32, PARAM_IN_OUT);
476 init_reg_param(&reg_params[1], "r5", 32, PARAM_OUT);
477 init_reg_param(&reg_params[2], "r6", 32, PARAM_OUT);
478
479 int row_offset = offset % row_size;
480 uint8_t *new_buffer = NULL;
481 if (row_offset && (count >= (row_size / 4))) {
482 new_buffer = malloc(buffer_size);
483 if (new_buffer == NULL) {
484 LOG_ERROR("Out of memory");
485 return ERROR_FAIL;
486 }
487 memset(new_buffer, 0xff, row_offset);
488 address -= row_offset;
489 } else
490 row_offset = 0;
491
492 while (count > 0) {
493 uint32_t status;
494 uint32_t thisrun_count;
495
496 if (row_offset) {
497 thisrun_count = (count > ((buffer_size - row_offset) / 4)) ?
498 ((buffer_size - row_offset) / 4) : count;
499
500 memcpy(new_buffer + row_offset, buffer, thisrun_count * 4);
501
502 retval = target_write_buffer(target, source->address,
503 row_offset + thisrun_count * 4, new_buffer);
504 if (retval != ERROR_OK)
505 break;
506 } else {
507 thisrun_count = (count > (buffer_size / 4)) ?
508 (buffer_size / 4) : count;
509
510 retval = target_write_buffer(target, source->address,
511 thisrun_count * 4, buffer);
512 if (retval != ERROR_OK)
513 break;
514 }
515
516 buf_set_u32(reg_params[0].value, 0, 32, Virt2Phys(source->address));
517 buf_set_u32(reg_params[1].value, 0, 32, Virt2Phys(address));
518 buf_set_u32(reg_params[2].value, 0, 32, thisrun_count + row_offset / 4);
519
520 retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
521 write_algorithm->address,
522 0, 10000, &mips32_info);
523 if (retval != ERROR_OK) {
524 LOG_ERROR("error executing pic32mx flash write algorithm");
525 retval = ERROR_FLASH_OPERATION_FAILED;
526 break;
527 }
528
529 status = buf_get_u32(reg_params[0].value, 0, 32);
530
531 if (status & NVMCON_NVMERR) {
532 LOG_ERROR("Flash write error NVMERR (status = 0x%08" PRIx32 ")", status);
533 retval = ERROR_FLASH_OPERATION_FAILED;
534 break;
535 }
536
537 if (status & NVMCON_LVDERR) {
538 LOG_ERROR("Flash write error LVDERR (status = 0x%08" PRIx32 ")", status);
539 retval = ERROR_FLASH_OPERATION_FAILED;
540 break;
541 }
542
543 buffer += thisrun_count * 4;
544 address += thisrun_count * 4;
545 count -= thisrun_count;
546 if (row_offset) {
547 address += row_offset;
548 row_offset = 0;
549 }
550 }
551
552 target_free_working_area(target, source);
553 target_free_working_area(target, write_algorithm);
554
555 destroy_reg_param(&reg_params[0]);
556 destroy_reg_param(&reg_params[1]);
557 destroy_reg_param(&reg_params[2]);
558
559 if (new_buffer != NULL)
560 free(new_buffer);
561 return retval;
562 }
563
564 static int pic32mx_write_word(struct flash_bank *bank, uint32_t address, uint32_t word)
565 {
566 struct target *target = bank->target;
567
568 target_write_u32(target, PIC32MX_NVMADDR, Virt2Phys(address));
569 target_write_u32(target, PIC32MX_NVMDATA, word);
570
571 return pic32mx_nvm_exec(bank, NVMCON_OP_WORD_PROG, 5);
572 }
573
574 static int pic32mx_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
575 {
576 uint32_t words_remaining = (count / 4);
577 uint32_t bytes_remaining = (count & 0x00000003);
578 uint32_t address = bank->base + offset;
579 uint32_t bytes_written = 0;
580 uint32_t status;
581 int retval;
582
583 if (bank->target->state != TARGET_HALTED) {
584 LOG_ERROR("Target not halted");
585 return ERROR_TARGET_NOT_HALTED;
586 }
587
588 LOG_DEBUG("writing to flash at address 0x%08" PRIx32 " at offset 0x%8.8" PRIx32
589 " count: 0x%8.8" PRIx32 "", bank->base, offset, count);
590
591 if (offset & 0x3) {
592 LOG_WARNING("offset 0x%" PRIx32 "breaks required 4-byte alignment", offset);
593 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
594 }
595
596 /* multiple words (4-byte) to be programmed? */
597 if (words_remaining > 0) {
598 /* try using a block write */
599 retval = pic32mx_write_block(bank, buffer, offset, words_remaining);
600 if (retval != ERROR_OK) {
601 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
602 /* if block write failed (no sufficient working area),
603 * we use normal (slow) single dword accesses */
604 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
605 } else if (retval == ERROR_FLASH_OPERATION_FAILED) {
606 LOG_ERROR("flash writing failed");
607 return retval;
608 }
609 } else {
610 buffer += words_remaining * 4;
611 address += words_remaining * 4;
612 words_remaining = 0;
613 }
614 }
615
616 while (words_remaining > 0) {
617 uint32_t value;
618 memcpy(&value, buffer + bytes_written, sizeof(uint32_t));
619
620 status = pic32mx_write_word(bank, address, value);
621
622 if (status & NVMCON_NVMERR) {
623 LOG_ERROR("Flash write error NVMERR (status = 0x%08" PRIx32 ")", status);
624 return ERROR_FLASH_OPERATION_FAILED;
625 }
626
627 if (status & NVMCON_LVDERR) {
628 LOG_ERROR("Flash write error LVDERR (status = 0x%08" PRIx32 ")", status);
629 return ERROR_FLASH_OPERATION_FAILED;
630 }
631
632 bytes_written += 4;
633 words_remaining--;
634 address += 4;
635 }
636
637 if (bytes_remaining) {
638 uint32_t value = 0xffffffff;
639 memcpy(&value, buffer + bytes_written, bytes_remaining);
640
641 status = pic32mx_write_word(bank, address, value);
642
643 if (status & NVMCON_NVMERR) {
644 LOG_ERROR("Flash write error NVMERR (status = 0x%08" PRIx32 ")", status);
645 return ERROR_FLASH_OPERATION_FAILED;
646 }
647
648 if (status & NVMCON_LVDERR) {
649 LOG_ERROR("Flash write error LVDERR (status = 0x%08" PRIx32 ")", status);
650 return ERROR_FLASH_OPERATION_FAILED;
651 }
652 }
653
654 return ERROR_OK;
655 }
656
657 static int pic32mx_probe(struct flash_bank *bank)
658 {
659 struct target *target = bank->target;
660 struct pic32mx_flash_bank *pic32mx_info = bank->driver_priv;
661 struct mips32_common *mips32 = target->arch_info;
662 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
663 int i;
664 uint32_t num_pages = 0;
665 uint32_t device_id;
666 int page_size;
667
668 pic32mx_info->probed = 0;
669
670 device_id = ejtag_info->idcode;
671 LOG_INFO("device id = 0x%08" PRIx32 " (manuf 0x%03x dev 0x%04x, ver 0x%02x)",
672 device_id,
673 (unsigned)((device_id >> 1) & 0x7ff),
674 (unsigned)((device_id >> 12) & 0xffff),
675 (unsigned)((device_id >> 28) & 0xf));
676
677 if (((device_id >> 1) & 0x7ff) != PIC32MX_MANUF_ID) {
678 LOG_WARNING("Cannot identify target as a PIC32MX family.");
679 return ERROR_FLASH_OPERATION_FAILED;
680 }
681
682 /* Check for PIC32mx1xx/2xx */
683 for (i = 0; pic32mx_devs[i].name != NULL; i++) {
684 if (pic32mx_devs[i].devid == (device_id & 0x0fffffff)) {
685 if ((*(pic32mx_devs[i].name) == '1') || (*(pic32mx_devs[i].name) == '2'))
686 pic32mx_info->dev_type = MX_1_2;
687 break;
688 }
689 }
690
691 if (pic32mx_info->dev_type == MX_1_2)
692 page_size = 1024;
693 else
694 page_size = 4096;
695
696
697 if (Virt2Phys(bank->base) == PIC32MX_PHYS_BOOT_FLASH) {
698 /* 0x1FC00000: Boot flash size */
699 #if 0
700 /* for some reason this register returns 8k for the boot bank size
701 * this does not match the docs, so for now set the boot bank at a
702 * fixed 12k */
703 if (target_read_u32(target, PIC32MX_BMXBOOTSZ, &num_pages) != ERROR_OK) {
704 LOG_WARNING("PIC32MX flash size failed, probe inaccurate - assuming 12k flash");
705 num_pages = (12 * 1024);
706 }
707 #else
708 /* fixed 12k boot bank - see comments above */
709 if (pic32mx_info->dev_type == MX_1_2)
710 num_pages = (3 * 1024);
711 else
712 num_pages = (12 * 1024);
713 #endif
714 } else {
715 /* read the flash size from the device */
716 if (target_read_u32(target, PIC32MX_BMXPFMSZ, &num_pages) != ERROR_OK) {
717 if (pic32mx_info->dev_type == MX_1_2) {
718 LOG_WARNING("PIC32MX flash size failed, probe inaccurate - assuming 32k flash");
719 num_pages = (32 * 1024);
720 } else {
721 LOG_WARNING("PIC32MX flash size failed, probe inaccurate - assuming 512k flash");
722 num_pages = (512 * 1024);
723 }
724 }
725 }
726
727 LOG_INFO("flash size = %" PRId32 "kbytes", num_pages / 1024);
728
729 if (bank->sectors) {
730 free(bank->sectors);
731 bank->sectors = NULL;
732 }
733
734 /* calculate numbers of pages */
735 num_pages /= page_size;
736 bank->size = (num_pages * page_size);
737 bank->num_sectors = num_pages;
738 bank->sectors = malloc(sizeof(struct flash_sector) * num_pages);
739
740 for (i = 0; i < (int)num_pages; i++) {
741 bank->sectors[i].offset = i * page_size;
742 bank->sectors[i].size = page_size;
743 bank->sectors[i].is_erased = -1;
744 bank->sectors[i].is_protected = 1;
745 }
746
747 pic32mx_info->probed = 1;
748
749 return ERROR_OK;
750 }
751
752 static int pic32mx_auto_probe(struct flash_bank *bank)
753 {
754 struct pic32mx_flash_bank *pic32mx_info = bank->driver_priv;
755 if (pic32mx_info->probed)
756 return ERROR_OK;
757 return pic32mx_probe(bank);
758 }
759
760 static int pic32mx_info(struct flash_bank *bank, char *buf, int buf_size)
761 {
762 struct target *target = bank->target;
763 struct mips32_common *mips32 = target->arch_info;
764 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
765 uint32_t device_id;
766 int printed = 0, i;
767
768 device_id = ejtag_info->idcode;
769
770 if (((device_id >> 1) & 0x7ff) != PIC32MX_MANUF_ID) {
771 snprintf(buf, buf_size,
772 "Cannot identify target as a PIC32MX family (manufacturer 0x%03d != 0x%03d)\n",
773 (unsigned)((device_id >> 1) & 0x7ff),
774 PIC32MX_MANUF_ID);
775 return ERROR_FLASH_OPERATION_FAILED;
776 }
777
778 for (i = 0; pic32mx_devs[i].name != NULL; i++) {
779 if (pic32mx_devs[i].devid == (device_id & 0x0fffffff)) {
780 printed = snprintf(buf, buf_size, "PIC32MX%s", pic32mx_devs[i].name);
781 break;
782 }
783 }
784
785 if (pic32mx_devs[i].name == NULL)
786 printed = snprintf(buf, buf_size, "Unknown");
787
788 buf += printed;
789 buf_size -= printed;
790 snprintf(buf, buf_size, " Ver: 0x%02x",
791 (unsigned)((device_id >> 28) & 0xf));
792
793 return ERROR_OK;
794 }
795
796 COMMAND_HANDLER(pic32mx_handle_pgm_word_command)
797 {
798 uint32_t address, value;
799 int status, res;
800
801 if (CMD_ARGC != 3)
802 return ERROR_COMMAND_SYNTAX_ERROR;
803
804 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
805 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
806
807 struct flash_bank *bank;
808 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 2, &bank);
809 if (ERROR_OK != retval)
810 return retval;
811
812 if (address < bank->base || address >= (bank->base + bank->size)) {
813 command_print(CMD_CTX, "flash address '%s' is out of bounds", CMD_ARGV[0]);
814 return ERROR_OK;
815 }
816
817 res = ERROR_OK;
818 status = pic32mx_write_word(bank, address, value);
819 if (status & NVMCON_NVMERR)
820 res = ERROR_FLASH_OPERATION_FAILED;
821 if (status & NVMCON_LVDERR)
822 res = ERROR_FLASH_OPERATION_FAILED;
823
824 if (res == ERROR_OK)
825 command_print(CMD_CTX, "pic32mx pgm word complete");
826 else
827 command_print(CMD_CTX, "pic32mx pgm word failed (status = 0x%x)", status);
828
829 return ERROR_OK;
830 }
831
832 COMMAND_HANDLER(pic32mx_handle_unlock_command)
833 {
834 uint32_t mchip_cmd;
835 struct target *target = NULL;
836 struct mips_m4k_common *mips_m4k;
837 struct mips_ejtag *ejtag_info;
838 int timeout = 10;
839
840 if (CMD_ARGC < 1) {
841 command_print(CMD_CTX, "pic32mx unlock <bank>");
842 return ERROR_COMMAND_SYNTAX_ERROR;
843 }
844
845 struct flash_bank *bank;
846 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
847 if (ERROR_OK != retval)
848 return retval;
849
850 target = bank->target;
851 mips_m4k = target_to_m4k(target);
852 ejtag_info = &mips_m4k->mips32.ejtag_info;
853
854 /* we have to use the MTAP to perform a full erase */
855 mips_ejtag_set_instr(ejtag_info, MTAP_SW_MTAP);
856 mips_ejtag_set_instr(ejtag_info, MTAP_COMMAND);
857
858 /* first check status of device */
859 mchip_cmd = MCHP_STATUS;
860 mips_ejtag_drscan_8(ejtag_info, &mchip_cmd);
861 if (mchip_cmd & (1 << 7)) {
862 /* device is not locked */
863 command_print(CMD_CTX, "pic32mx is already unlocked, erasing anyway");
864 }
865
866 /* unlock/erase device */
867 mips_ejtag_drscan_8_out(ejtag_info, MCHP_ASERT_RST);
868 jtag_add_sleep(200);
869
870 mips_ejtag_drscan_8_out(ejtag_info, MCHP_ERASE);
871
872 do {
873 mchip_cmd = MCHP_STATUS;
874 mips_ejtag_drscan_8(ejtag_info, &mchip_cmd);
875 if (timeout-- == 0) {
876 LOG_DEBUG("timeout waiting for unlock: 0x%" PRIx32 "", mchip_cmd);
877 break;
878 }
879 alive_sleep(1);
880 } while ((mchip_cmd & (1 << 2)) || (!(mchip_cmd & (1 << 3))));
881
882 mips_ejtag_drscan_8_out(ejtag_info, MCHP_DE_ASSERT_RST);
883
884 /* select ejtag tap */
885 mips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP);
886
887 command_print(CMD_CTX, "pic32mx unlocked.\n"
888 "INFO: a reset or power cycle is required "
889 "for the new settings to take effect.");
890
891 return ERROR_OK;
892 }
893
894 static const struct command_registration pic32mx_exec_command_handlers[] = {
895 {
896 .name = "pgm_word",
897 .usage = "<addr> <value> <bank>",
898 .handler = pic32mx_handle_pgm_word_command,
899 .mode = COMMAND_EXEC,
900 .help = "program a word",
901 },
902 {
903 .name = "unlock",
904 .handler = pic32mx_handle_unlock_command,
905 .mode = COMMAND_EXEC,
906 .usage = "[bank_id]",
907 .help = "Unlock/Erase entire device.",
908 },
909 COMMAND_REGISTRATION_DONE
910 };
911
912 static const struct command_registration pic32mx_command_handlers[] = {
913 {
914 .name = "pic32mx",
915 .mode = COMMAND_ANY,
916 .help = "pic32mx flash command group",
917 .usage = "",
918 .chain = pic32mx_exec_command_handlers,
919 },
920 COMMAND_REGISTRATION_DONE
921 };
922
923 struct flash_driver pic32mx_flash = {
924 .name = "pic32mx",
925 .commands = pic32mx_command_handlers,
926 .flash_bank_command = pic32mx_flash_bank_command,
927 .erase = pic32mx_erase,
928 .protect = pic32mx_protect,
929 .write = pic32mx_write,
930 .read = default_flash_read,
931 .probe = pic32mx_probe,
932 .auto_probe = pic32mx_auto_probe,
933 .erase_check = default_flash_blank_check,
934 .protect_check = pic32mx_protect_check,
935 .info = pic32mx_info,
936 };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)