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

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)