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

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)