OpenOCD
atsamv.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-Source-Code)
2 
3 /*
4  * Copyright (C) 2009 by Duane Ellis <openocd@duaneellis.com>
5  *
6  * at91sam3s* support
7  * Copyright (C) 2010 by Olaf Lüke <olaf@uni-paderborn.de>
8  *
9  * at91sam3x* & at91sam4 support
10  * Copyright (C) 2011 by Olivier Schonken and Jim Norris
11  *
12  * atsamv, atsams, and atsame support
13  * Copyright (C) 2015 Morgan Quigley
14  *
15  * atsamv extension of user signature area
16  * Copyright (C) 2024-2025 Elektroline Inc.
17  *
18  * Some of the lower level code was based on code supplied by
19  * ATMEL under BSD-Source-Code License and this copyright.
20  * ATMEL Microcontroller Software Support
21  * Copyright (c) 2009, Atmel Corporation. All rights reserved.
22  */
23 
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27 
28 #include "imp.h"
29 #include <helper/time_support.h>
30 #include <helper/bits.h>
31 
32 #define REG_NAME_WIDTH (12)
33 
34 #define SAMV_EFC_FCMD_GETD (0x0) /* (EFC) Get Flash Descriptor */
35 #define SAMV_EFC_FCMD_WP (0x1) /* (EFC) Write Page */
36 #define SAMV_EFC_FCMD_WPL (0x2) /* (EFC) Write Page and Lock */
37 #define SAMV_EFC_FCMD_EWP (0x3) /* (EFC) Erase Page and Write Page */
38 #define SAMV_EFC_FCMD_EWPL (0x4) /* (EFC) Erase Page, Write Page then Lock*/
39 #define SAMV_EFC_FCMD_EA (0x5) /* (EFC) Erase All */
40 #define SAMV_EFC_FCMD_EPA (0x7) /* (EFC) Erase pages */
41 #define SAMV_EFC_FCMD_SLB (0x8) /* (EFC) Set Lock Bit */
42 #define SAMV_EFC_FCMD_CLB (0x9) /* (EFC) Clear Lock Bit */
43 #define SAMV_EFC_FCMD_GLB (0xA) /* (EFC) Get Lock Bit */
44 #define SAMV_EFC_FCMD_SFB (0xB) /* (EFC) Set Fuse Bit */
45 #define SAMV_EFC_FCMD_CFB (0xC) /* (EFC) Clear Fuse Bit */
46 #define SAMV_EFC_FCMD_GFB (0xD) /* (EFC) Get Fuse Bit */
47 #define SAMV_EFC_FCMD_WUS (0x12) /* (EFC) Write User Signature */
48 #define SAMV_EFC_FCMD_EUS (0x13) /* (EFC) Erase User Signature */
49 #define SAMV_EFC_FCMD_STUS (0x14) /* (EFC) Start Read User Signature */
50 #define SAMV_EFC_FCMD_SPUS (0x15) /* (EFC) Stop Read User Signature */
51 
52 #define SAMV_EFC_FMR_SCOD BIT(16) /* Sequantial Code Optimalization Disable */
53 
54 #define SAMV_EFC_FSR_FRDY_SET 1
55 #define SAMV_EFC_FRS_FRDY_CLR 0
56 
57 #define OFFSET_EFC_FMR 0
58 #define OFFSET_EFC_FCR 4
59 #define OFFSET_EFC_FSR 8
60 #define OFFSET_EFC_FRR 12
61 
62 #define TIMEOUT_MS_FRS_CHANGE 10 /* Timeout for FRS ready bit change */
63 #define TIMEOUT_MS_CMD_DEFAULT 50 /* Default timeout for command */
64 #define TIMEOUT_MS_CMD_ERASE 24000 /* Timeout for erase commands */
65 
66 #define SAMV_CHIPID_CIDR (0x400E0940)
67 #define SAMV_NUM_GPNVM_BITS 9
68 #define SAMV_CONTROLLER_ADDR (0x400e0c00)
69 #define SAMV_SECTOR_SIZE 16384
70 #define SAMV_PAGE_SIZE 512
71 #define SAMV_FLASH_BASE 0x00400000
72 /* This is a workaround. Flash Signature area is actually located at the
73  * beginning of the flash memory at the address range overlapping the
74  * first page of program flash. Since OpenOCD does not support write to
75  * a bank outside of address range, we use address above maximum 32-bit
76  * address space.
77  */
78 #define SAMV_FLASH_SIGNATURE_BASE 0x100000000
79 #define SAMV_FLASH_SIGNATURE_SIZE SAMV_PAGE_SIZE
80 
82  bool probed;
83  unsigned int size_bytes;
84  unsigned int gpnvm[SAMV_NUM_GPNVM_BITS];
85 };
86 
87 
88 /* The actual sector size of the SAMV7 flash memory is 128K bytes.
89  * 16 sectors for a 2048KB device. The lock regions are 16KB per lock
90  * region, with a 2048KB device having 128 lock regions.
91  * For the best results, num_sectors is thus set to the number of lock
92  * regions, and the sector_size set to the lock region size. Page
93  * erases are used to erase 16KB sections when programming */
94 
95 static int samv_efc_get_status(struct target *target, uint32_t *v)
96 {
98  return r;
99 }
100 
101 static int samv_efc_wait_status(struct target *target, uint8_t desired,
102  int64_t timeout, uint32_t *status)
103 {
104  uint32_t v;
105  int64_t ms_now, ms_end;
106  int r;
107 
108  if (status)
109  *status = 0;
110 
111  ms_end = timeout + timeval_ms();
112 
113  do {
114  r = samv_efc_get_status(target, &v);
115  if (r != ERROR_OK)
116  return r;
117 
118  if (status)
119  *status = v;
120  ms_now = timeval_ms();
121  if (ms_now > ms_end) {
122  /* error */
123  LOG_ERROR("Command timeout");
124  return ERROR_FLASH_BUSY;
125  }
126  } while ((v & 1) != desired);
127 
128  return ERROR_OK;
129 }
130 
131 static int samv_efc_get_result(struct target *target, uint32_t *v)
132 {
133  uint32_t rv;
135  if (v)
136  *v = rv;
137  return r;
138 }
139 
140 static inline int samv_efc_get_mode(struct target *target, uint32_t *v)
141 {
143 }
144 
145 static inline int samv_efc_set_mode(struct target *target, uint32_t v)
146 {
148 }
149 
151  uint8_t command, unsigned int argument)
152 {
153  uint32_t v;
154 
155  v = (0x5A << 24) | (argument << 8) | command;
156  LOG_DEBUG("starting flash command: 0x%08x", (unsigned int)(v));
158  if (r != ERROR_OK)
159  LOG_DEBUG("write failed");
160  return r;
161 }
162 
164  uint8_t command, unsigned int argument, uint32_t *status)
165 {
166  int r;
167  uint32_t v;
168  int64_t timeout;
169 
170  if (status)
171  *status = 0;
172 
173  r = samv_efc_get_status(target, &v);
174  if (r != ERROR_OK)
175  return r;
176  if ((v & 1) != 0x1)
177  return ERROR_FAIL;
178  r = samv_efc_start_command(target, command, argument);
179  if (r != ERROR_OK)
180  return r;
181 
185  else
187 
189  if (r != ERROR_OK)
190  return r;
191 
192  /* if requested, copy the flash controller error bits back to the caller */
193  if (status)
194  *status = (v & 0x6);
195  return ERROR_OK;
196 }
197 
198 static int samv_efc_read_sequence(struct target *target, uint8_t start_cmd,
199  uint8_t stop_cmd, uint8_t *buf, size_t read_size)
200 {
201  uint32_t v;
202  uint32_t addr = SAMV_FLASH_BASE;
203  int r;
204 
206  v |= SAMV_EFC_FMR_SCOD;
208 
209  r = samv_efc_start_command(target, start_cmd, 0);
210  if (r != ERROR_OK) {
211  samv_efc_start_command(target, stop_cmd, 0);
212  goto rs_finish;
213  }
214 
217  if (r != ERROR_OK)
218  goto rs_finish;
219 
220  r = target_read_memory(target, addr, sizeof(uint32_t),
221  read_size / sizeof(uint32_t), buf);
222  if (r != ERROR_OK) {
223  LOG_ERROR("flash program failed to read page @ 0x%" PRIx32 "", addr);
224  goto rs_finish;
225  }
226 
227  r = samv_efc_start_command(target, stop_cmd, 0);
228  if (r != ERROR_OK)
229  goto rs_finish;
230 
233  if (r != ERROR_OK)
234  goto rs_finish;
235 
236 rs_finish:
237  v &= ~SAMV_EFC_FMR_SCOD;
239 
240  return r;
241 }
242 
243 static int samv_erase_pages(struct target *target,
244  int first_page, int num_pages, uint32_t *status)
245 {
246  uint8_t erase_pages;
247  switch (num_pages) {
248  case 4:
249  erase_pages = 0x00;
250  break;
251  case 8:
252  erase_pages = 0x01;
253  break;
254  case 16:
255  erase_pages = 0x02;
256  break;
257  case 32:
258  erase_pages = 0x03;
259  break;
260  default:
261  erase_pages = 0x00;
262  break;
263  }
264 
265  /* SAMV_EFC_FCMD_EPA
266  * According to the datasheet FARG[15:2] defines the page from which
267  * the erase will start.This page must be modulo 4, 8, 16 or 32
268  * according to the number of pages to erase. FARG[1:0] defines the
269  * number of pages to be erased. Previously (firstpage << 2) was used
270  * to conform to this, seems it should not be shifted...
271  */
273  first_page | erase_pages, status);
274 }
275 
276 static int samv_get_gpnvm(struct target *target, unsigned int gpnvm, unsigned int *out)
277 {
278  uint32_t v;
279  int r;
280 
281  if (gpnvm >= SAMV_NUM_GPNVM_BITS) {
282  LOG_ERROR("invalid gpnvm %d, max: %d", gpnvm, SAMV_NUM_GPNVM_BITS);
283  return ERROR_FAIL;
284  }
285 
287  if (r != ERROR_OK) {
288  LOG_ERROR("samv_get_gpnvm failed");
289  return r;
290  }
291 
292  r = samv_efc_get_result(target, &v);
293 
294  if (out)
295  *out = (v >> gpnvm) & 1;
296 
297  return r;
298 }
299 
300 static int samv_clear_gpnvm(struct target *target, unsigned int gpnvm)
301 {
302  int r;
303  unsigned int v;
304 
305  if (gpnvm >= SAMV_NUM_GPNVM_BITS) {
306  LOG_ERROR("invalid gpnvm %d, max: %d", gpnvm, SAMV_NUM_GPNVM_BITS);
307  return ERROR_FAIL;
308  }
309  r = samv_get_gpnvm(target, gpnvm, &v);
310  if (r != ERROR_OK) {
311  LOG_DEBUG("get gpnvm failed: %d", r);
312  return r;
313  }
315  LOG_DEBUG("clear gpnvm result: %d", r);
316  return r;
317 }
318 
319 static int samv_set_gpnvm(struct target *target, unsigned int gpnvm)
320 {
321  int r;
322  unsigned int v;
323  if (gpnvm >= SAMV_NUM_GPNVM_BITS) {
324  LOG_ERROR("invalid gpnvm %d, max: %d", gpnvm, SAMV_NUM_GPNVM_BITS);
325  return ERROR_FAIL;
326  }
327 
328  r = samv_get_gpnvm(target, gpnvm, &v);
329  if (r != ERROR_OK)
330  return r;
331  if (v) {
332  r = ERROR_OK; /* the gpnvm bit is already set */
333  } else {
334  /* we need to set it */
336  }
337  return r;
338 }
339 
341 {
342  int r;
343 
345  if (r != ERROR_OK)
346  LOG_ERROR("error performing user signature write");
347 
348  return r;
349 }
350 
351 static int samv_flash_unlock(struct target *target,
352  unsigned int start_sector, unsigned int end_sector)
353 {
354  int r;
355  uint32_t status;
356  uint32_t pg;
357  uint32_t pages_per_sector;
358 
359  /* todo: look into this... i think this should be done on lock regions */
360  pages_per_sector = SAMV_SECTOR_SIZE / SAMV_PAGE_SIZE;
361  while (start_sector <= end_sector) {
362  pg = start_sector * pages_per_sector;
364  if (r != ERROR_OK)
365  return r;
366  start_sector++;
367  }
368  return ERROR_OK;
369 }
370 
371 static int samv_flash_lock(struct target *target,
372  unsigned int start_sector, unsigned int end_sector)
373 {
374  uint32_t status;
375  uint32_t pg;
376  uint32_t pages_per_sector;
377  int r;
378 
379  /* todo: look into this... i think this should be done on lock regions */
380  pages_per_sector = SAMV_SECTOR_SIZE / SAMV_PAGE_SIZE;
381  while (start_sector <= end_sector) {
382  pg = start_sector * pages_per_sector;
384  if (r != ERROR_OK)
385  return r;
386  start_sector++;
387  }
388  return ERROR_OK;
389 }
390 
391 static int samv_protect_check(struct flash_bank *bank)
392 {
393  int r;
394  uint32_t v[4] = {0};
395 
397  if (r == ERROR_OK) {
398  samv_efc_get_result(bank->target, &v[0]);
399  samv_efc_get_result(bank->target, &v[1]);
400  samv_efc_get_result(bank->target, &v[2]);
401  r = samv_efc_get_result(bank->target, &v[3]);
402  }
403  if (r != ERROR_OK)
404  return r;
405 
406  for (unsigned int x = 0; x < bank->num_sectors; x++)
407  bank->sectors[x].is_protected = (!!(v[x >> 5] & (1 << (x % 32))));
408  return ERROR_OK;
409 }
410 
411 FLASH_BANK_COMMAND_HANDLER(samv_flash_bank_command)
412 {
413  struct samv_flash_bank *samv_info;
414  samv_info = calloc(1, sizeof(struct samv_flash_bank));
415  bank->driver_priv = samv_info;
416  return ERROR_OK;
417 }
418 
419 static int samv_get_device_id(struct flash_bank *bank, uint32_t *device_id)
420 {
421  return target_read_u32(bank->target, SAMV_CHIPID_CIDR, device_id);
422 }
423 
424 static int samv_probe(struct flash_bank *bank)
425 {
426  if (bank->base == SAMV_FLASH_SIGNATURE_BASE) {
428  bank->num_sectors = 1;
429  bank->sectors = calloc(bank->num_sectors, sizeof(struct flash_sector));
430  bank->sectors[0].size = SAMV_FLASH_SIGNATURE_SIZE;
431  return ERROR_OK;
432  }
433 
434  uint32_t device_id;
435  int r = samv_get_device_id(bank, &device_id);
436  if (r != ERROR_OK)
437  return r;
438  LOG_INFO("device id = 0x%08" PRIx32, device_id);
439 
440  uint8_t eproc = (device_id >> 5) & 0x7;
441  if (eproc != 0) {
442  LOG_ERROR("unexpected eproc code: %d was expecting 0 (Cortex-M7)", eproc);
443  return ERROR_FAIL;
444  }
445 
446  uint8_t nvm_size_code = (device_id >> 8) & 0xf;
447  switch (nvm_size_code) {
448  case 10:
449  bank->size = 512 * 1024;
450  break;
451  case 12:
452  bank->size = 1024 * 1024;
453  break;
454  case 14:
455  bank->size = 2048 * 1024;
456  break;
457  default:
458  LOG_ERROR("unrecognized flash size code: %d", nvm_size_code);
459  return ERROR_FAIL;
460  }
461 
462  struct samv_flash_bank *samv_info = bank->driver_priv;
463  samv_info->size_bytes = bank->size;
464  samv_info->probed = true;
465 
466  bank->base = SAMV_FLASH_BASE;
467  bank->num_sectors = bank->size / SAMV_SECTOR_SIZE;
468  bank->sectors = calloc(bank->num_sectors, sizeof(struct flash_sector));
469  for (unsigned int s = 0; s < bank->num_sectors; s++) {
470  bank->sectors[s].size = SAMV_SECTOR_SIZE;
471  bank->sectors[s].offset = s * SAMV_SECTOR_SIZE;
472  bank->sectors[s].is_erased = -1;
473  bank->sectors[s].is_protected = -1;
474  }
475 
477  if (r != ERROR_OK)
478  return r;
479 
480  return ERROR_OK;
481 }
482 
483 static int samv_auto_probe(struct flash_bank *bank)
484 {
485  struct samv_flash_bank *samv_info = bank->driver_priv;
486  if (samv_info->probed)
487  return ERROR_OK;
488  return samv_probe(bank);
489 }
490 
491 static int samv_erase(struct flash_bank *bank, unsigned int first,
492  unsigned int last)
493 {
494  const int page_count = 32; /* 32 pages equals 16 KB lock region */
495 
496  if (bank->target->state != TARGET_HALTED) {
497  LOG_ERROR("Target not halted");
499  }
500 
501  int r = samv_auto_probe(bank);
502  if (r != ERROR_OK)
503  return r;
504 
505  if (bank->base == SAMV_FLASH_SIGNATURE_BASE)
506  return samv_erase_user_signature(bank->target);
507 
508  /* easy case: we've been requested to erase the entire flash */
509  if ((first == 0) && ((last + 1) == bank->num_sectors))
510  return samv_efc_perform_command(bank->target, SAMV_EFC_FCMD_EA, 0, NULL);
511 
512  LOG_DEBUG("erasing lock regions %u-%u...", first, last);
513 
514  for (unsigned int i = first; i <= last; i++) {
515  uint32_t status;
516  r = samv_erase_pages(bank->target, (i * page_count), page_count, &status);
517  LOG_DEBUG("erasing lock region %u", i);
518  if (r != ERROR_OK)
519  LOG_ERROR("error performing erase page @ lock region number %u", i);
520  if (status & (1 << 2)) {
521  LOG_ERROR("lock region %u is locked", i);
522  return ERROR_FAIL;
523  }
524  if (status & (1 << 1)) {
525  LOG_ERROR("flash command error @lock region %u", i);
526  return ERROR_FAIL;
527  }
528  }
529  return ERROR_OK;
530 }
531 
532 static int samv_protect(struct flash_bank *bank, int set, unsigned int first,
533  unsigned int last)
534 {
535  if (bank->target->state != TARGET_HALTED) {
536  LOG_ERROR("Target not halted");
538  }
539 
540  int r;
541  if (set)
542  r = samv_flash_lock(bank->target, first, last);
543  else
544  r = samv_flash_unlock(bank->target, first, last);
545 
546  return r;
547 }
548 
550  unsigned int page_num, uint8_t *buf)
551 {
552  uint32_t addr = SAMV_FLASH_BASE + page_num * SAMV_PAGE_SIZE;
553  int r = target_read_memory(target, addr, 4, SAMV_PAGE_SIZE / 4, buf);
554  if (r != ERROR_OK)
555  LOG_ERROR("flash program failed to read page @ 0x%08" PRIx32 "",
556  addr);
557  return r;
558 }
559 
560 static int samv_read_user_signature(struct target *target, uint8_t *buf)
561 {
564 }
565 
566 static int samv_page_read(struct target *target,
567  target_addr_t base, unsigned int page_num, uint8_t *buf)
568 {
569  int r;
570  if (base == SAMV_FLASH_SIGNATURE_BASE)
572  else
573  r = samv_read_standard_page(target, page_num, buf);
574 
575  return r;
576 }
577 
579  unsigned int pagenum, const uint8_t *buf)
580 {
581  const uint32_t addr = SAMV_FLASH_BASE;
582  int r;
583 
584  r = target_write_memory(target, addr, sizeof(uint32_t),
585  SAMV_PAGE_SIZE / sizeof(uint32_t), buf);
586  if (r != ERROR_OK) {
587  LOG_ERROR("failed to buffer page at 0x%08" PRIx32 "", addr);
588  return r;
589  }
590 
592  if (r != ERROR_OK)
593  LOG_ERROR("error performing user signature write");
594 
595  return r;
596 }
597 
599  unsigned int pagenum, const uint8_t *buf)
600 {
601  uint32_t status;
602  const uint32_t addr = SAMV_FLASH_BASE + pagenum * SAMV_PAGE_SIZE;
603  int r;
604 
605  LOG_DEBUG("write page %u at address 0x%08" PRIx32 "", pagenum, addr);
606  r = target_write_memory(target, addr, 4, SAMV_PAGE_SIZE / 4, buf);
607  if (r != ERROR_OK) {
608  LOG_ERROR("failed to buffer page at 0x%08" PRIx32 "", addr);
609  return r;
610  }
611 
613  if (r != ERROR_OK)
614  LOG_ERROR("error performing write page at 0x%08" PRIx32 "", addr);
615  if (status & (1 << 2)) {
616  LOG_ERROR("page at 0x%08" PRIx32 " is locked", addr);
617  return ERROR_FAIL;
618  }
619  if (status & (1 << 1)) {
620  LOG_ERROR("flash command error at 0x%08" PRIx32 "", addr);
621  return ERROR_FAIL;
622  }
623  return ERROR_OK;
624 }
625 
626 static int samv_page_write(struct target *target,
627  target_addr_t base, unsigned int pagenum, const uint8_t *buf)
628 {
629  int r;
630  if (base == SAMV_FLASH_SIGNATURE_BASE)
631  r = samv_write_user_signature(target, pagenum, buf);
632  else
633  r = samv_write_standard_page(target, pagenum, buf);
634 
635  return r;
636 }
637 
638 static int samv_read(struct flash_bank *bank, uint8_t *buffer,
639  uint32_t offset, uint32_t count)
640 {
641  int r;
642  uint8_t pagebuffer[SAMV_PAGE_SIZE] = {0};
643  struct target *target = bank->target;
644 
645  LOG_DEBUG("offset=0x%08" PRIx32 " count=0x%08" PRIx32 "", offset, count);
646 
647  if (target->state != TARGET_HALTED) {
648  LOG_ERROR("Target not halted");
650  }
651 
652  if (offset + count > bank->size) {
653  LOG_WARNING("Reads past end of flash. Extra data discarded.");
654  count = bank->size - offset;
655  }
656 
657  LOG_DEBUG("offset: 0x%08" PRIx32 ", count: 0x%08" PRIx32 "", offset, count);
658 
659  if (bank->base == SAMV_FLASH_SIGNATURE_BASE) {
660  r = samv_read_user_signature(target, pagebuffer);
661  if (r != ERROR_OK)
662  return r;
663  memcpy(buffer, pagebuffer + offset, count);
664  } else {
666  if (r != ERROR_OK)
667  return r;
668  }
669 
670  return ERROR_OK;
671 }
672 
673 static int samv_write(struct flash_bank *bank, const uint8_t *buffer,
674  uint32_t offset, uint32_t count)
675 {
676  if (bank->target->state != TARGET_HALTED) {
677  LOG_ERROR("target not halted");
679  }
680 
681  if (count == 0)
682  return ERROR_OK;
683 
684  if ((offset + count) > bank->size) {
685  LOG_ERROR("flash write error - past end of bank");
686  LOG_ERROR(" offset: 0x%08" PRIx32 ", count 0x%08" PRIx32 ", bank end: 0x%08" PRIx32 "",
687  offset,
688  count,
689  bank->size);
690  return ERROR_FAIL;
691  }
692 
693  uint8_t pagebuffer[SAMV_PAGE_SIZE] = {0};
694  uint32_t page_cur = offset / SAMV_PAGE_SIZE;
695  uint32_t page_end = (offset + count - 1) / SAMV_PAGE_SIZE;
696 
697  LOG_DEBUG("offset: 0x%08" PRIx32 ", count: 0x%08" PRIx32 "", offset, count);
698  LOG_DEBUG("page start: %" PRIu32 ", page end: %" PRIu32 "", page_cur, page_end);
699 
700  /* Special case: all one page */
701  /* Otherwise: */
702  /* (1) non-aligned start */
703  /* (2) body pages */
704  /* (3) non-aligned end. */
705 
706  int r;
707  uint32_t page_offset;
708 
709  /* handle special case - all one page. */
710  if (page_cur == page_end) {
711  LOG_DEBUG("special case, all in one page");
712  r = samv_page_read(bank->target, bank->base, page_cur, pagebuffer);
713  if (r != ERROR_OK)
714  return r;
715 
716  page_offset = offset & (SAMV_PAGE_SIZE - 1);
717  memcpy(pagebuffer + page_offset, buffer, count);
718 
719  r = samv_page_write(bank->target, bank->base, page_cur, pagebuffer);
720  if (r != ERROR_OK)
721  return r;
722  return ERROR_OK;
723  }
724 
725  /* step 1) handle the non-aligned starting address */
726  page_offset = offset & (SAMV_PAGE_SIZE - 1);
727  if (page_offset) {
728  LOG_DEBUG("non-aligned start");
729  /* read the partial page */
730  r = samv_page_read(bank->target, bank->base, page_cur, pagebuffer);
731  if (r != ERROR_OK)
732  return r;
733 
734  /* over-write with new data */
735  uint32_t n = SAMV_PAGE_SIZE - page_offset;
736  memcpy(pagebuffer + page_offset, buffer, n);
737 
738  r = samv_page_write(bank->target, bank->base, page_cur, pagebuffer);
739  if (r != ERROR_OK)
740  return r;
741 
742  count -= n;
743  offset += n;
744  buffer += n;
745  page_cur++;
746  }
747 
748  /* By checking that offset is correct here, we also fix a clang warning */
749  assert(offset % SAMV_PAGE_SIZE == 0);
750 
751  /* step 2) handle the full pages */
752  LOG_DEBUG("full page loop: cur=%" PRIu32 ", end=%" PRIu32 ", count = 0x%08" PRIx32 "",
753  page_cur, page_end, count);
754 
755  while ((page_cur < page_end) && (count >= SAMV_PAGE_SIZE)) {
756  r = samv_page_write(bank->target, bank->base, page_cur, buffer);
757  if (r != ERROR_OK)
758  return r;
761  page_cur += 1;
762  }
763 
764  /* step 3) write final page, if it's partial (otherwise it's already done) */
765  if (count) {
766  LOG_DEBUG("final partial page, count = 0x%08" PRIx32 "", count);
767  /* we have a partial page */
768  r = samv_page_read(bank->target, bank->base, page_cur, pagebuffer);
769  if (r != ERROR_OK)
770  return r;
771  memcpy(pagebuffer, buffer, count); /* data goes at start of page */
772  r = samv_page_write(bank->target, bank->base, page_cur, pagebuffer);
773  if (r != ERROR_OK)
774  return r;
775  }
776  return ERROR_OK;
777 }
778 
779 static int samv_get_info(struct flash_bank *bank, struct command_invocation *cmd)
780 {
781  struct samv_flash_bank *samv_info = bank->driver_priv;
782  if (!samv_info->probed) {
783  int r = samv_probe(bank);
784  if (r != ERROR_OK)
785  return r;
786  }
787  command_print_sameline(cmd, "Cortex-M7 detected with %" PRIu32 " kB flash\n",
788  bank->size / 1024);
789  return ERROR_OK;
790 }
791 
792 COMMAND_HANDLER(samv_handle_gpnvm_command)
793 {
795  if (!bank)
796  return ERROR_FAIL;
797  struct samv_flash_bank *samv_info = bank->driver_priv;
798  struct target *target = bank->target;
799 
800  if (target->state != TARGET_HALTED) {
801  LOG_ERROR("target not halted");
803  }
804 
805  int r;
806  if (!samv_info->probed) {
807  r = samv_auto_probe(bank);
808  if (r != ERROR_OK)
809  return r;
810  }
811 
812  int who = 0;
813 
814  switch (CMD_ARGC) {
815  case 0:
816  goto showall;
817  case 1:
818  who = -1;
819  break;
820  case 2:
821  if (!strcmp(CMD_ARGV[0], "show") && !strcmp(CMD_ARGV[1], "all")) {
822  who = -1;
823  } else {
824  uint32_t v32;
825  COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], v32);
826  who = v32;
827  }
828  break;
829  default:
831  }
832 
833  unsigned int v = 0;
834  if (!strcmp("show", CMD_ARGV[0])) {
835  if (who == -1) {
836 showall:
837  r = ERROR_OK;
838  for (int x = 0; x < SAMV_NUM_GPNVM_BITS; x++) {
839  r = samv_get_gpnvm(target, x, &v);
840  if (r != ERROR_OK)
841  break;
842  command_print(CMD, "samv-gpnvm%u: %u", x, v);
843  }
844  return r;
845  }
846  if ((who >= 0) && (((unsigned)who) < SAMV_NUM_GPNVM_BITS)) {
847  r = samv_get_gpnvm(target, who, &v);
848  if (r != ERROR_OK)
849  return r;
850 
851  command_print(CMD, "samv-gpnvm%u: %u", who, v);
852  return r;
853  } else {
854  command_print(CMD, "invalid gpnvm: %u", who);
856  }
857  }
858 
859  if (who == -1) {
860  command_print(CMD, "missing gpnvm number");
862  }
863 
864  if (!strcmp("set", CMD_ARGV[0]))
865  r = samv_set_gpnvm(target, who);
866  else if (!strcmp("clr", CMD_ARGV[0]) || !strcmp("clear", CMD_ARGV[0]))
867  r = samv_clear_gpnvm(target, who);
868  else {
869  command_print(CMD, "unknown command: %s", CMD_ARGV[0]);
871  }
872  return r;
873 }
874 
875 static const struct command_registration atsamv_exec_command_handlers[] = {
876  {
877  .name = "gpnvm",
878  .handler = samv_handle_gpnvm_command,
879  .mode = COMMAND_EXEC,
880  .usage = "[('clr'|'set'|'show') bitnum]",
881  .help = "Without arguments, shows all bits in the gpnvm "
882  "register. Otherwise, clears, sets, or shows one "
883  "General Purpose Non-Volatile Memory (gpnvm) bit.",
884  },
886 };
887 
888 static const struct command_registration atsamv_command_handlers[] = {
889  {
890  .name = "atsamv",
891  .mode = COMMAND_ANY,
892  .help = "atsamv flash command group",
893  .usage = "",
895  },
897 };
898 
899 const struct flash_driver atsamv_flash = {
900  .name = "atsamv",
901  .commands = atsamv_command_handlers,
902  .flash_bank_command = samv_flash_bank_command,
903  .erase = samv_erase,
904  .protect = samv_protect,
905  .write = samv_write,
906  .read = samv_read,
907  .probe = samv_probe,
908  .auto_probe = samv_auto_probe,
909  .erase_check = default_flash_blank_check,
910  .protect_check = samv_protect_check,
911  .info = samv_get_info,
912  .free_driver_priv = default_flash_free_driver_priv,
913 };
static const char * eproc[8]
Definition: at91sam7.c:100
static int samv_efc_read_sequence(struct target *target, uint8_t start_cmd, uint8_t stop_cmd, uint8_t *buf, size_t read_size)
Definition: atsamv.c:198
static int samv_get_gpnvm(struct target *target, unsigned int gpnvm, unsigned int *out)
Definition: atsamv.c:276
#define SAMV_EFC_FCMD_STUS
Definition: atsamv.c:49
#define SAMV_EFC_FMR_SCOD
Definition: atsamv.c:52
static int samv_efc_get_result(struct target *target, uint32_t *v)
Definition: atsamv.c:131
#define TIMEOUT_MS_CMD_DEFAULT
Definition: atsamv.c:63
static int samv_protect_check(struct flash_bank *bank)
Definition: atsamv.c:391
#define SAMV_FLASH_BASE
Definition: atsamv.c:71
FLASH_BANK_COMMAND_HANDLER(samv_flash_bank_command)
Definition: atsamv.c:411
static int samv_flash_unlock(struct target *target, unsigned int start_sector, unsigned int end_sector)
Definition: atsamv.c:351
static int samv_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
Definition: atsamv.c:638
#define SAMV_EFC_FCMD_EPA
Definition: atsamv.c:40
#define SAMV_EFC_FCMD_SPUS
Definition: atsamv.c:50
static int samv_read_standard_page(struct target *target, unsigned int page_num, uint8_t *buf)
Definition: atsamv.c:549
#define SAMV_SECTOR_SIZE
Definition: atsamv.c:69
#define SAMV_CHIPID_CIDR
Definition: atsamv.c:66
#define SAMV_EFC_FCMD_EA
Definition: atsamv.c:39
static int samv_auto_probe(struct flash_bank *bank)
Definition: atsamv.c:483
#define SAMV_EFC_FCMD_CFB
Definition: atsamv.c:45
#define OFFSET_EFC_FRR
Definition: atsamv.c:60
static int samv_efc_get_mode(struct target *target, uint32_t *v)
Definition: atsamv.c:140
const struct flash_driver atsamv_flash
Definition: atsamv.c:899
#define TIMEOUT_MS_CMD_ERASE
Definition: atsamv.c:64
COMMAND_HANDLER(samv_handle_gpnvm_command)
Definition: atsamv.c:792
#define SAMV_EFC_FCMD_SLB
Definition: atsamv.c:41
#define SAMV_EFC_FCMD_SFB
Definition: atsamv.c:44
#define SAMV_EFC_FCMD_WP
Definition: atsamv.c:35
#define SAMV_PAGE_SIZE
Definition: atsamv.c:70
#define SAMV_EFC_FCMD_GFB
Definition: atsamv.c:46
#define SAMV_FLASH_SIGNATURE_BASE
Definition: atsamv.c:78
static const struct command_registration atsamv_exec_command_handlers[]
Definition: atsamv.c:875
static int samv_erase_user_signature(struct target *target)
Definition: atsamv.c:340
static int samv_efc_wait_status(struct target *target, uint8_t desired, int64_t timeout, uint32_t *status)
Definition: atsamv.c:101
static int samv_write_standard_page(struct target *target, unsigned int pagenum, const uint8_t *buf)
Definition: atsamv.c:598
static const struct command_registration atsamv_command_handlers[]
Definition: atsamv.c:888
#define SAMV_CONTROLLER_ADDR
Definition: atsamv.c:68
#define SAMV_EFC_FCMD_CLB
Definition: atsamv.c:42
#define SAMV_EFC_FSR_FRDY_SET
Definition: atsamv.c:54
#define OFFSET_EFC_FCR
Definition: atsamv.c:58
#define SAMV_EFC_FRS_FRDY_CLR
Definition: atsamv.c:55
static int samv_clear_gpnvm(struct target *target, unsigned int gpnvm)
Definition: atsamv.c:300
static int samv_get_info(struct flash_bank *bank, struct command_invocation *cmd)
Definition: atsamv.c:779
static int samv_protect(struct flash_bank *bank, int set, unsigned int first, unsigned int last)
Definition: atsamv.c:532
static int samv_efc_perform_command(struct target *target, uint8_t command, unsigned int argument, uint32_t *status)
Definition: atsamv.c:163
#define OFFSET_EFC_FSR
Definition: atsamv.c:59
#define SAMV_NUM_GPNVM_BITS
Definition: atsamv.c:67
static int samv_page_write(struct target *target, target_addr_t base, unsigned int pagenum, const uint8_t *buf)
Definition: atsamv.c:626
static int samv_efc_start_command(struct target *target, uint8_t command, unsigned int argument)
Definition: atsamv.c:150
#define TIMEOUT_MS_FRS_CHANGE
Definition: atsamv.c:62
static int samv_erase_pages(struct target *target, int first_page, int num_pages, uint32_t *status)
Definition: atsamv.c:243
static int samv_efc_get_status(struct target *target, uint32_t *v)
Definition: atsamv.c:95
static int samv_get_device_id(struct flash_bank *bank, uint32_t *device_id)
Definition: atsamv.c:419
static int samv_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
Definition: atsamv.c:673
#define SAMV_EFC_FCMD_EUS
Definition: atsamv.c:48
static int samv_page_read(struct target *target, target_addr_t base, unsigned int page_num, uint8_t *buf)
Definition: atsamv.c:566
#define OFFSET_EFC_FMR
Definition: atsamv.c:57
#define SAMV_EFC_FCMD_WUS
Definition: atsamv.c:47
static int samv_write_user_signature(struct target *target, unsigned int pagenum, const uint8_t *buf)
Definition: atsamv.c:578
static int samv_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
Definition: atsamv.c:491
#define SAMV_EFC_FCMD_GLB
Definition: atsamv.c:43
#define SAMV_FLASH_SIGNATURE_SIZE
Definition: atsamv.c:79
static int samv_probe(struct flash_bank *bank)
Definition: atsamv.c:424
static int samv_set_gpnvm(struct target *target, unsigned int gpnvm)
Definition: atsamv.c:319
static int samv_flash_lock(struct target *target, unsigned int start_sector, unsigned int end_sector)
Definition: atsamv.c:371
static int samv_read_user_signature(struct target *target, uint8_t *buf)
Definition: atsamv.c:560
static int samv_efc_set_mode(struct target *target, uint32_t v)
Definition: atsamv.c:145
void command_print_sameline(struct command_invocation *cmd, const char *format,...)
Definition: command.c:378
void command_print(struct command_invocation *cmd, const char *format,...)
Definition: command.c:389
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
Definition: command.h:146
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:161
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:405
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:156
#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:445
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:256
@ COMMAND_ANY
Definition: command.h:42
@ COMMAND_EXEC
Definition: command.h:40
uint64_t buffer
Pointer to data buffer to send over SPI.
Definition: dw-spi-helper.h:0
uint8_t bank
Definition: esirisc.c:135
#define ERROR_FLASH_BUSY
Definition: flash/common.h:33
int default_flash_blank_check(struct flash_bank *bank)
Provides default erased-bank check handling.
struct flash_bank * get_flash_bank_by_num_noprobe(unsigned int num)
Returns the flash bank like get_flash_bank_by_num(), without probing.
void default_flash_free_driver_priv(struct flash_bank *bank)
Deallocates bank->driver_priv.
#define LOG_WARNING(expr ...)
Definition: log.h:144
#define ERROR_FAIL
Definition: log.h:188
#define LOG_ERROR(expr ...)
Definition: log.h:147
#define LOG_INFO(expr ...)
Definition: log.h:141
#define LOG_DEBUG(expr ...)
Definition: log.h:124
#define ERROR_OK
Definition: log.h:182
target_addr_t addr
Start address to search for the control block.
Definition: rtt/rtt.c:28
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:239
Provides details of a flash bank, available either on-chip or through a major interface.
Definition: nor/core.h:75
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
unsigned int gpnvm[SAMV_NUM_GPNVM_BITS]
Definition: atsamv.c:84
unsigned int size_bytes
Definition: atsamv.c:83
bool probed
Definition: atsamv.c:82
Definition: target.h:119
enum target_state state
Definition: target.h:167
Definition: psoc6.c:83
int target_write_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
Write count items of size bytes to the memory of target at the address given.
Definition: target.c:1288
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
Definition: target.c:2635
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
Definition: target.c:2561
int target_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
Read count items of size bytes from the memory of target at the address given.
Definition: target.c:1260
#define ERROR_TARGET_NOT_HALTED
Definition: target.h:817
@ TARGET_HALTED
Definition: target.h:58
int64_t timeval_ms(void)
uint64_t target_addr_t
Definition: types.h:279
#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