OpenOCD
pic32mx.c
Go to the documentation of this file.
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 
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 {
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 {
196 
197  if (CMD_ARGC < 6)
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 
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 
240 
241  /* unlock flash registers */
244 
245  /* start operation */
247 
249 
250  /* lock flash registers */
252 
253  return status;
254 }
255 
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");
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");
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");
329  if (status & NVMCON_NVMERR)
331  if (status & NVMCON_LVDERR)
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 
340 
341  if (status & NVMCON_NVMERR)
343  if (status & NVMCON_LVDERR)
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");
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 */
449  &write_algorithm) != ERROR_OK) {
450  LOG_WARNING("no working area available, can't do block memory writes");
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)];
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");
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");
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);
557  break;
558  }
559 
560  if (status & NVMCON_LVDERR) {
561  LOG_ERROR("Flash write error LVDERR (status = 0x%08" PRIx32 ")", status);
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 
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 
592 
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");
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);
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);
647  }
648 
649  if (status & NVMCON_LVDERR) {
650  LOG_ERROR("Flash write error LVDERR (status = 0x%08" PRIx32 ")", status);
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);
668  }
669 
670  if (status & NVMCON_LVDERR) {
671  LOG_ERROR("Flash write error LVDERR (status = 0x%08" PRIx32 ")", status);
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.");
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) {
803  "Cannot identify target as a PIC32MX family (manufacturer 0x%03x != 0x%03x)\n",
804  (unsigned)((device_id >> 1) & 0x7ff),
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)
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)
851  if (status & NVMCON_LVDERR)
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)
871 
872  struct flash_bank *bank;
873  int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
874  if (retval != ERROR_OK)
875  return retval;
876 
877  target = bank->target;
878  mips_m4k = target_to_m4k(target);
879  ejtag_info = &mips_m4k->mips32.ejtag_info;
880 
881  /* we have to use the MTAP to perform a full erase */
882  mips_ejtag_set_instr(ejtag_info, MTAP_SW_MTAP);
883  mips_ejtag_set_instr(ejtag_info, MTAP_COMMAND);
884 
885  /* first check status of device */
886  uint8_t mchip_cmd = MCHP_STATUS;
887  mips_ejtag_drscan_8(ejtag_info, &mchip_cmd);
888  if (mchip_cmd & (1 << 7)) {
889  /* device is not locked */
890  command_print(CMD, "pic32mx is already unlocked, erasing anyway");
891  }
892 
893  /* unlock/erase device */
895  jtag_add_sleep(200);
896 
897  mips_ejtag_drscan_8_out(ejtag_info, MCHP_ERASE);
898 
899  do {
900  mchip_cmd = MCHP_STATUS;
901  mips_ejtag_drscan_8(ejtag_info, &mchip_cmd);
902  if (timeout-- == 0) {
903  LOG_DEBUG("timeout waiting for unlock: 0x%" PRIx8 "", mchip_cmd);
904  break;
905  }
906  alive_sleep(1);
907  } while ((mchip_cmd & (1 << 2)) || (!(mchip_cmd & (1 << 3))));
908 
910 
911  /* select ejtag tap */
912  mips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP);
913 
914  command_print(CMD, "pic32mx unlocked.\n"
915  "INFO: a reset or power cycle is required "
916  "for the new settings to take effect.");
917 
918  return ERROR_OK;
919 }
920 
921 static const struct command_registration pic32mx_exec_command_handlers[] = {
922  {
923  .name = "pgm_word",
924  .usage = "<addr> <value> <bank>",
925  .handler = pic32mx_handle_pgm_word_command,
926  .mode = COMMAND_EXEC,
927  .help = "program a word",
928  },
929  {
930  .name = "unlock",
931  .handler = pic32mx_handle_unlock_command,
932  .mode = COMMAND_EXEC,
933  .usage = "bank_id",
934  .help = "Unlock/Erase entire device.",
935  },
937 };
938 
939 static const struct command_registration pic32mx_command_handlers[] = {
940  {
941  .name = "pic32mx",
942  .mode = COMMAND_ANY,
943  .help = "pic32mx flash command group",
944  .usage = "",
946  },
948 };
949 
950 const struct flash_driver pic32mx_flash = {
951  .name = "pic32mx",
952  .commands = pic32mx_command_handlers,
953  .flash_bank_command = pic32mx_flash_bank_command,
954  .erase = pic32mx_erase,
955  .protect = pic32mx_protect,
956  .write = pic32mx_write,
957  .read = default_flash_read,
958  .probe = pic32mx_probe,
959  .auto_probe = pic32mx_auto_probe,
960  .erase_check = default_flash_blank_check,
961  .protect_check = pic32mx_protect_check,
962  .info = pic32mx_info,
963  .free_driver_priv = default_flash_free_driver_priv,
964 };
void init_reg_param(struct reg_param *param, char *reg_name, uint32_t size, enum param_direction direction)
Definition: algorithm.c:29
void destroy_reg_param(struct reg_param *param)
Definition: algorithm.c:37
@ PARAM_OUT
Definition: algorithm.h:16
@ PARAM_IN_OUT
Definition: algorithm.h:17
const char * name
Definition: armv4_5.c:76
static uint32_t buf_get_u32(const uint8_t *_buffer, unsigned int first, unsigned int num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 32-bit word.
Definition: binarybuffer.h:104
static void buf_set_u32(uint8_t *_buffer, unsigned int first, unsigned int num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
Definition: binarybuffer.h:34
void command_print_sameline(struct command_invocation *cmd, const char *format,...)
Definition: command.c:420
void command_print(struct command_invocation *cmd, const char *format,...)
Definition: command.c:443
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
Definition: command.h:141
#define CALL_COMMAND_HANDLER(name, extra ...)
Use this to macro to call a command helper (or a nested handler).
Definition: command.h:118
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:156
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:402
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:151
#define COMMAND_PARSE_NUMBER(type, in, out)
parses the string in into out as a type, or prints a command error and passes the error code to the c...
Definition: command.h:442
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:253
@ COMMAND_ANY
Definition: command.h:42
@ COMMAND_EXEC
Definition: command.h:40
uint8_t bank
Definition: esirisc.c:135
#define ERROR_FLASH_OPERATION_FAILED
Definition: flash/common.h:30
#define ERROR_FLASH_DST_BREAKS_ALIGNMENT
Definition: flash/common.h:32
int default_flash_blank_check(struct flash_bank *bank)
Provides default erased-bank check handling.
int default_flash_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
Provides default read implementation for flash memory.
void default_flash_free_driver_priv(struct flash_bank *bank)
Deallocates bank->driver_priv.
void jtag_add_sleep(uint32_t us)
Definition: jtag/core.c:876
The JTAG interface can be implemented with a software or hardware fifo.
uint64_t op
Definition: lakemont.c:68
void alive_sleep(uint64_t ms)
Definition: log.c:456
#define LOG_WARNING(expr ...)
Definition: log.h:129
#define ERROR_FAIL
Definition: log.h:170
#define LOG_ERROR(expr ...)
Definition: log.h:132
#define LOG_INFO(expr ...)
Definition: log.h:126
#define LOG_DEBUG(expr ...)
Definition: log.h:109
#define ERROR_OK
Definition: log.h:164
#define MIPS32_COMMON_MAGIC
Definition: mips32.h:21
@ MIPS32_ISA_MIPS32
Definition: mips32.h:250
int mips_ejtag_drscan_8(struct mips_ejtag *ejtag_info, uint8_t *data)
Definition: mips_ejtag.c:150
void mips_ejtag_set_instr(struct mips_ejtag *ejtag_info, uint32_t new_instr)
Definition: mips_ejtag.c:22
void mips_ejtag_drscan_8_out(struct mips_ejtag *ejtag_info, uint8_t data)
Definition: mips_ejtag.c:171
#define MTAP_SW_ETAP
Definition: mips_ejtag.h:37
#define MCHP_STATUS
Definition: mips_ejtag.h:44
#define MCHP_DE_ASSERT_RST
Definition: mips_ejtag.h:42
#define MTAP_COMMAND
Definition: mips_ejtag.h:38
#define MCHP_ASERT_RST
Definition: mips_ejtag.h:41
#define MCHP_ERASE
Definition: mips_ejtag.h:43
#define MTAP_SW_MTAP
Definition: mips_ejtag.h:36
static struct mips_m4k_common * target_to_m4k(struct target *target)
Definition: mips_m4k.h:29
static uint32_t pic32mx_wait_status_busy(struct flash_bank *bank, int timeout)
Definition: pic32mx.c:219
static const struct command_registration pic32mx_command_handlers[]
Definition: pic32mx.c:939
#define NVMCON_OP_PFM_ERASE
Definition: pic32mx.c:64
#define PIC32MX_NVMCONSET
Definition: pic32mx.c:57
static int pic32mx_write_block(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
Definition: pic32mx.c:432
#define PIC32MX_BMXPFMSZ
Definition: pic32mx.c:49
#define NVMCON_OP_PAGE_ERASE
Definition: pic32mx.c:65
#define NVMCON_NVMWREN
Definition: pic32mx.c:60
static int pic32mx_write_word(struct flash_bank *bank, uint32_t address, uint32_t word)
Definition: pic32mx.c:586
FLASH_BANK_COMMAND_HANDLER(pic32mx_flash_bank_command)
Definition: pic32mx.c:193
#define PIC32MX_BMXBOOTSZ
Definition: pic32mx.c:50
const struct flash_driver pic32mx_flash
Definition: pic32mx.c:950
#define NVMKEY1
Definition: pic32mx.c:80
#define MX_17X_27X
Definition: pic32mx.c:84
static uint32_t pic32mx_get_flash_status(struct flash_bank *bank)
Definition: pic32mx.c:209
#define PIC32MX_NVMADDR
Definition: pic32mx.c:71
#define PIC32MX_NVMKEY
Definition: pic32mx.c:70
static int pic32mx_nvm_exec(struct flash_bank *bank, uint32_t op, uint32_t timeout)
Definition: pic32mx.c:234
#define NVMCON_OP_WORD_PROG
Definition: pic32mx.c:67
#define PIC32MX_NVMCONCLR
Definition: pic32mx.c:56
#define MX_1XX_2XX
Definition: pic32mx.c:83
#define virt2phys(v)
Definition: pic32mx.c:38
static const struct command_registration pic32mx_exec_command_handlers[]
Definition: pic32mx.c:921
#define PIC32MX_PHYS_PGM_FLASH
Definition: pic32mx.c:29
static int pic32mx_protect_check(struct flash_bank *bank)
Definition: pic32mx.c:256
static int pic32mx_probe(struct flash_bank *bank)
Definition: pic32mx.c:679
#define NVMCON_NVMWR
Definition: pic32mx.c:59
#define PIC32MX_PHYS_BOOT_FLASH
Definition: pic32mx.c:31
#define PIC32MX_DEVCFG0
Definition: pic32mx.c:43
#define NVMKEY2
Definition: pic32mx.c:81
static int pic32mx_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
Definition: pic32mx.c:312
static int pic32mx_protect(struct flash_bank *bank, int set, unsigned int first, unsigned int last)
Definition: pic32mx.c:350
static uint32_t pic32mx_flash_write_code[]
Definition: pic32mx.c:365
#define PIC32MX_DEVCFG0_1XX_2XX
Definition: pic32mx.c:42
COMMAND_HANDLER(pic32mx_handle_pgm_word_command)
Definition: pic32mx.c:826
#define PIC32MX_MANUF_ID
Definition: pic32mx.c:24
#define PIC32MX_NVMCON
Definition: pic32mx.c:55
#define PIC32MX_NVMDATA
Definition: pic32mx.c:75
static int pic32mx_auto_probe(struct flash_bank *bank)
Definition: pic32mx.c:784
#define NVMCON_NVMERR
Definition: pic32mx.c:61
static int pic32mx_info(struct flash_bank *bank, struct command_invocation *cmd)
Definition: pic32mx.c:792
static int pic32mx_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
Definition: pic32mx.c:596
#define NVMCON_LVDERR
Definition: pic32mx.c:62
struct rtt_source source
Definition: rtt/rtt.c:23
When run_command is called, a new instance will be created on the stack, filled with the proper value...
Definition: command.h:76
const char * name
Definition: command.h:235
Provides details of a flash bank, available either on-chip or through a major interface.
Definition: nor/core.h:75
target_addr_t base
The base address of this bank.
Definition: nor/core.h:84
Provides the implementation-independent structure that defines all of the callbacks required by OpenO...
Definition: nor/driver.h:39
const char * name
Gives a human-readable name of this flash driver, This field is used to select and initialize the dri...
Definition: nor/driver.h:44
Describes the geometry and status of a single flash sector within a flash bank.
Definition: nor/core.h:28
enum mips32_isa_mode isa_mode
Definition: mips32.h:457
unsigned int common_magic
Definition: mips32.h:456
struct mips_ejtag ejtag_info
Definition: mips32.h:396
uint32_t idcode
Definition: mips_ejtag.h:208
struct mips32_common mips32
Definition: mips_m4k.h:23
const char * name
Definition: pic32mx.c:97
uint32_t devid
Definition: pic32mx.c:96
Definition: target.h:116
enum target_state state
Definition: target.h:157
void * arch_info
Definition: target.h:164
Definition: psoc6.c:83
target_addr_t address
Definition: target.h:86
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
Definition: target.c:2342
int target_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_param, target_addr_t entry_point, target_addr_t exit_point, unsigned int timeout_ms, void *arch_info)
Downloads a target-specific native code algorithm to the target, and executes it.
Definition: target.c:773
int target_alloc_working_area(struct target *target, uint32_t size, struct working_area **area)
Definition: target.c:2060
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
Definition: target.c:2641
int target_free_working_area(struct target *target, struct working_area *area)
Free a working area.
Definition: target.c:2118
int target_alloc_working_area_try(struct target *target, uint32_t size, struct working_area **area)
Definition: target.c:1966
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
Definition: target.c:2550
void target_buffer_set_u32_array(struct target *target, uint8_t *buffer, uint32_t count, const uint32_t *srcbuf)
Definition: target.c:417
#define ERROR_TARGET_NOT_HALTED
Definition: target.h:790
@ TARGET_HALTED
Definition: target.h:56
#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE
Definition: target.h:794
#define TARGET_ADDR_FMT
Definition: types.h:342
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.
Definition: types.h:57
#define NULL
Definition: usb.h:16
uint8_t status[4]
Definition: vdebug.c:17
uint8_t cmd
Definition: vdebug.c:1
uint8_t offset[4]
Definition: vdebug.c:9
uint8_t count[4]
Definition: vdebug.c:22