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 {
562  int r;
563 
565  buf, SAMV_PAGE_SIZE);
566 
567  return r;
568 }
569 
570 static int samv_page_read(struct target *target,
571  target_addr_t base, unsigned int page_num, uint8_t *buf)
572 {
573  int r;
574  if (base == SAMV_FLASH_SIGNATURE_BASE)
576  else
577  r = samv_read_standard_page(target, page_num, buf);
578 
579  return r;
580 }
581 
583  unsigned int pagenum, const uint8_t *buf)
584 {
585  const uint32_t addr = SAMV_FLASH_BASE;
586  int r;
587 
588  r = target_write_memory(target, addr, sizeof(uint32_t),
589  SAMV_PAGE_SIZE / sizeof(uint32_t), buf);
590  if (r != ERROR_OK) {
591  LOG_ERROR("failed to buffer page at 0x%08" PRIx32 "", addr);
592  return r;
593  }
594 
596  if (r != ERROR_OK)
597  LOG_ERROR("error performing user signature write");
598 
599  return r;
600 }
601 
603  unsigned int pagenum, const uint8_t *buf)
604 {
605  uint32_t status;
606  const uint32_t addr = SAMV_FLASH_BASE + pagenum * SAMV_PAGE_SIZE;
607  int r;
608 
609  LOG_DEBUG("write page %u at address 0x%08" PRIx32 "", pagenum, addr);
610  r = target_write_memory(target, addr, 4, SAMV_PAGE_SIZE / 4, buf);
611  if (r != ERROR_OK) {
612  LOG_ERROR("failed to buffer page at 0x%08" PRIx32 "", addr);
613  return r;
614  }
615 
617  if (r != ERROR_OK)
618  LOG_ERROR("error performing write page at 0x%08" PRIx32 "", addr);
619  if (status & (1 << 2)) {
620  LOG_ERROR("page at 0x%08" PRIx32 " is locked", addr);
621  return ERROR_FAIL;
622  }
623  if (status & (1 << 1)) {
624  LOG_ERROR("flash command error at 0x%08" PRIx32 "", addr);
625  return ERROR_FAIL;
626  }
627  return ERROR_OK;
628 }
629 
630 static int samv_page_write(struct target *target,
631  target_addr_t base, unsigned int pagenum, const uint8_t *buf)
632 {
633  int r;
634  if (base == SAMV_FLASH_SIGNATURE_BASE)
635  r = samv_write_user_signature(target, pagenum, buf);
636  else
637  r = samv_write_standard_page(target, pagenum, buf);
638 
639  return r;
640 }
641 
642 static int samv_read(struct flash_bank *bank, uint8_t *buffer,
643  uint32_t offset, uint32_t count)
644 {
645  int r;
646  uint8_t pagebuffer[SAMV_PAGE_SIZE] = {0};
647  struct target *target = bank->target;
648 
649  LOG_DEBUG("offset=0x%08" PRIx32 " count=0x%08" PRIx32 "", offset, count);
650 
651  if (target->state != TARGET_HALTED) {
652  LOG_ERROR("Target not halted");
654  }
655 
656  if (offset + count > bank->size) {
657  LOG_WARNING("Reads past end of flash. Extra data discarded.");
658  count = bank->size - offset;
659  }
660 
661  LOG_DEBUG("offset: 0x%08" PRIx32 ", count: 0x%08" PRIx32 "", offset, count);
662 
663  if (bank->base == SAMV_FLASH_SIGNATURE_BASE) {
664  r = samv_read_user_signature(target, pagebuffer);
665  if (r != ERROR_OK)
666  return r;
667  memcpy(buffer, pagebuffer + offset, count);
668  } else {
670  if (r != ERROR_OK)
671  return r;
672  }
673 
674  return ERROR_OK;
675 }
676 
677 static int samv_write(struct flash_bank *bank, const uint8_t *buffer,
678  uint32_t offset, uint32_t count)
679 {
680  if (bank->target->state != TARGET_HALTED) {
681  LOG_ERROR("target not halted");
683  }
684 
685  if (count == 0)
686  return ERROR_OK;
687 
688  if ((offset + count) > bank->size) {
689  LOG_ERROR("flash write error - past end of bank");
690  LOG_ERROR(" offset: 0x%08" PRIx32 ", count 0x%08" PRIx32 ", bank end: 0x%08" PRIx32 "",
691  offset,
692  count,
693  bank->size);
694  return ERROR_FAIL;
695  }
696 
697  uint8_t pagebuffer[SAMV_PAGE_SIZE] = {0};
698  uint32_t page_cur = offset / SAMV_PAGE_SIZE;
699  uint32_t page_end = (offset + count - 1) / SAMV_PAGE_SIZE;
700 
701  LOG_DEBUG("offset: 0x%08" PRIx32 ", count: 0x%08" PRIx32 "", offset, count);
702  LOG_DEBUG("page start: %" PRIu32 ", page end: %" PRIu32 "", page_cur, page_end);
703 
704  /* Special case: all one page */
705  /* Otherwise: */
706  /* (1) non-aligned start */
707  /* (2) body pages */
708  /* (3) non-aligned end. */
709 
710  int r;
711  uint32_t page_offset;
712 
713  /* handle special case - all one page. */
714  if (page_cur == page_end) {
715  LOG_DEBUG("special case, all in one page");
716  r = samv_page_read(bank->target, bank->base, page_cur, pagebuffer);
717  if (r != ERROR_OK)
718  return r;
719 
720  page_offset = offset & (SAMV_PAGE_SIZE - 1);
721  memcpy(pagebuffer + page_offset, buffer, count);
722 
723  r = samv_page_write(bank->target, bank->base, page_cur, pagebuffer);
724  if (r != ERROR_OK)
725  return r;
726  return ERROR_OK;
727  }
728 
729  /* step 1) handle the non-aligned starting address */
730  page_offset = offset & (SAMV_PAGE_SIZE - 1);
731  if (page_offset) {
732  LOG_DEBUG("non-aligned start");
733  /* read the partial page */
734  r = samv_page_read(bank->target, bank->base, page_cur, pagebuffer);
735  if (r != ERROR_OK)
736  return r;
737 
738  /* over-write with new data */
739  uint32_t n = SAMV_PAGE_SIZE - page_offset;
740  memcpy(pagebuffer + page_offset, buffer, n);
741 
742  r = samv_page_write(bank->target, bank->base, page_cur, pagebuffer);
743  if (r != ERROR_OK)
744  return r;
745 
746  count -= n;
747  offset += n;
748  buffer += n;
749  page_cur++;
750  }
751 
752  /* By checking that offset is correct here, we also fix a clang warning */
753  assert(offset % SAMV_PAGE_SIZE == 0);
754 
755  /* step 2) handle the full pages */
756  LOG_DEBUG("full page loop: cur=%" PRIu32 ", end=%" PRIu32 ", count = 0x%08" PRIx32 "",
757  page_cur, page_end, count);
758 
759  while ((page_cur < page_end) && (count >= SAMV_PAGE_SIZE)) {
760  r = samv_page_write(bank->target, bank->base, page_cur, buffer);
761  if (r != ERROR_OK)
762  return r;
765  page_cur += 1;
766  }
767 
768  /* step 3) write final page, if it's partial (otherwise it's already done) */
769  if (count) {
770  LOG_DEBUG("final partial page, count = 0x%08" PRIx32 "", count);
771  /* we have a partial page */
772  r = samv_page_read(bank->target, bank->base, page_cur, pagebuffer);
773  if (r != ERROR_OK)
774  return r;
775  memcpy(pagebuffer, buffer, count); /* data goes at start of page */
776  r = samv_page_write(bank->target, bank->base, page_cur, pagebuffer);
777  if (r != ERROR_OK)
778  return r;
779  }
780  return ERROR_OK;
781 }
782 
783 static int samv_get_info(struct flash_bank *bank, struct command_invocation *cmd)
784 {
785  struct samv_flash_bank *samv_info = bank->driver_priv;
786  if (!samv_info->probed) {
787  int r = samv_probe(bank);
788  if (r != ERROR_OK)
789  return r;
790  }
791  command_print_sameline(cmd, "Cortex-M7 detected with %" PRIu32 " kB flash\n",
792  bank->size / 1024);
793  return ERROR_OK;
794 }
795 
796 COMMAND_HANDLER(samv_handle_gpnvm_command)
797 {
799  if (!bank)
800  return ERROR_FAIL;
801  struct samv_flash_bank *samv_info = bank->driver_priv;
802  struct target *target = bank->target;
803 
804  if (target->state != TARGET_HALTED) {
805  LOG_ERROR("target not halted");
807  }
808 
809  int r;
810  if (!samv_info->probed) {
811  r = samv_auto_probe(bank);
812  if (r != ERROR_OK)
813  return r;
814  }
815 
816  int who = 0;
817 
818  switch (CMD_ARGC) {
819  case 0:
820  goto showall;
821  case 1:
822  who = -1;
823  break;
824  case 2:
825  if (!strcmp(CMD_ARGV[0], "show") && !strcmp(CMD_ARGV[1], "all"))
826  who = -1;
827  else {
828  uint32_t v32;
829  COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], v32);
830  who = v32;
831  }
832  break;
833  default:
835  }
836 
837  unsigned int v = 0;
838  if (!strcmp("show", CMD_ARGV[0])) {
839  if (who == -1) {
840 showall:
841  r = ERROR_OK;
842  for (int x = 0; x < SAMV_NUM_GPNVM_BITS; x++) {
843  r = samv_get_gpnvm(target, x, &v);
844  if (r != ERROR_OK)
845  break;
846  command_print(CMD, "samv-gpnvm%u: %u", x, v);
847  }
848  return r;
849  }
850  if ((who >= 0) && (((unsigned)who) < SAMV_NUM_GPNVM_BITS)) {
851  r = samv_get_gpnvm(target, who, &v);
852  if (r != ERROR_OK)
853  return r;
854 
855  command_print(CMD, "samv-gpnvm%u: %u", who, v);
856  return r;
857  } else {
858  command_print(CMD, "invalid gpnvm: %u", who);
860  }
861  }
862 
863  if (who == -1) {
864  command_print(CMD, "missing gpnvm number");
866  }
867 
868  if (!strcmp("set", CMD_ARGV[0]))
869  r = samv_set_gpnvm(target, who);
870  else if (!strcmp("clr", CMD_ARGV[0]) || !strcmp("clear", CMD_ARGV[0]))
871  r = samv_clear_gpnvm(target, who);
872  else {
873  command_print(CMD, "unknown command: %s", CMD_ARGV[0]);
875  }
876  return r;
877 }
878 
879 static const struct command_registration atsamv_exec_command_handlers[] = {
880  {
881  .name = "gpnvm",
882  .handler = samv_handle_gpnvm_command,
883  .mode = COMMAND_EXEC,
884  .usage = "[('clr'|'set'|'show') bitnum]",
885  .help = "Without arguments, shows all bits in the gpnvm "
886  "register. Otherwise, clears, sets, or shows one "
887  "General Purpose Non-Volatile Memory (gpnvm) bit.",
888  },
890 };
891 
892 static const struct command_registration atsamv_command_handlers[] = {
893  {
894  .name = "atsamv",
895  .mode = COMMAND_ANY,
896  .help = "atsamv flash command group",
897  .usage = "",
899  },
901 };
902 
903 const struct flash_driver atsamv_flash = {
904  .name = "atsamv",
905  .commands = atsamv_command_handlers,
906  .flash_bank_command = samv_flash_bank_command,
907  .erase = samv_erase,
908  .protect = samv_protect,
909  .write = samv_write,
910  .read = samv_read,
911  .probe = samv_probe,
912  .auto_probe = samv_auto_probe,
913  .erase_check = default_flash_blank_check,
914  .protect_check = samv_protect_check,
915  .info = samv_get_info,
916  .free_driver_priv = default_flash_free_driver_priv,
917 };
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:642
#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:903
#define TIMEOUT_MS_CMD_ERASE
Definition: atsamv.c:64
COMMAND_HANDLER(samv_handle_gpnvm_command)
Definition: atsamv.c:796
#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:879
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:602
static const struct command_registration atsamv_command_handlers[]
Definition: atsamv.c:892
#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:783
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:630
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:677
#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:570
#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:582
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:348
void command_print(struct command_invocation *cmd, const char *format,...)
Definition: command.c:371
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
Definition: command.h:141
#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:400
#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:440
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:251
@ 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:130
#define ERROR_FAIL
Definition: log.h:174
#define LOG_ERROR(expr ...)
Definition: log.h:133
#define LOG_INFO(expr ...)
Definition: log.h:127
#define LOG_DEBUG(expr ...)
Definition: log.h:110
#define ERROR_OK
Definition: log.h:168
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:234
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:160
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:1275
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
Definition: target.c:2650
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
Definition: target.c:2559
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:1247
#define ERROR_TARGET_NOT_HALTED
Definition: target.h:786
@ TARGET_HALTED
Definition: target.h:58
int64_t timeval_ms(void)
uint64_t target_addr_t
Definition: types.h:335
#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