1 /* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-Source-Code) */
4 * Copyright (C) 2009 by Duane Ellis <openocd@duaneellis.com>
7 * Copyright (C) 2010 by Olaf Lüke <olaf@uni-paderborn.de>
9 * at91sam3x* & at91sam4 support
10 * Copyright (C) 2011 by Olivier Schonken and Jim Norris
12 * atsamv, atsams, and atsame support
13 * Copyright (C) 2015 Morgan Quigley
15 * Some of the lower level code was based on code supplied by
16 * ATMEL under BSD-Source-Code License and this copyright.
17 * ATMEL Microcontroller Software Support
18 * Copyright (c) 2009, Atmel Corporation. All rights reserved.
26 #include <helper/time_support.h>
28 #define REG_NAME_WIDTH (12)
30 #define SAMV_EFC_FCMD_GETD (0x0) /* (EFC) Get Flash Descriptor */
31 #define SAMV_EFC_FCMD_WP (0x1) /* (EFC) Write Page */
32 #define SAMV_EFC_FCMD_WPL (0x2) /* (EFC) Write Page and Lock */
33 #define SAMV_EFC_FCMD_EWP (0x3) /* (EFC) Erase Page and Write Page */
34 #define SAMV_EFC_FCMD_EWPL (0x4) /* (EFC) Erase Page, Write Page then Lock*/
35 #define SAMV_EFC_FCMD_EA (0x5) /* (EFC) Erase All */
36 #define SAMV_EFC_FCMD_EPA (0x7) /* (EFC) Erase pages */
37 #define SAMV_EFC_FCMD_SLB (0x8) /* (EFC) Set Lock Bit */
38 #define SAMV_EFC_FCMD_CLB (0x9) /* (EFC) Clear Lock Bit */
39 #define SAMV_EFC_FCMD_GLB (0xA) /* (EFC) Get Lock Bit */
40 #define SAMV_EFC_FCMD_SFB (0xB) /* (EFC) Set Fuse Bit */
41 #define SAMV_EFC_FCMD_CFB (0xC) /* (EFC) Clear Fuse Bit */
42 #define SAMV_EFC_FCMD_GFB (0xD) /* (EFC) Get Fuse Bit */
44 #define OFFSET_EFC_FMR 0
45 #define OFFSET_EFC_FCR 4
46 #define OFFSET_EFC_FSR 8
47 #define OFFSET_EFC_FRR 12
49 #define SAMV_CHIPID_CIDR (0x400E0940)
50 #define SAMV_NUM_GPNVM_BITS 9
51 #define SAMV_CONTROLLER_ADDR (0x400e0c00)
52 #define SAMV_SECTOR_SIZE 16384
53 #define SAMV_PAGE_SIZE 512
54 #define SAMV_FLASH_BASE 0x00400000
56 extern const struct flash_driver atsamv_flash;
58 struct samv_flash_bank {
61 unsigned gpnvm[SAMV_NUM_GPNVM_BITS];
64 /* The actual sector size of the SAMV7 flash memory is 128K bytes.
65 * 16 sectors for a 2048KB device. The lock regions are 16KB per lock
66 * region, with a 2048KB device having 128 lock regions.
67 * For the best results, num_sectors is thus set to the number of lock
68 * regions, and the sector_size set to the lock region size. Page
69 * erases are used to erase 16KB sections when programming */
71 static int samv_efc_get_status(struct target *target, uint32_t *v)
73 int r = target_read_u32(target, SAMV_CONTROLLER_ADDR + OFFSET_EFC_FSR, v);
77 static int samv_efc_get_result(struct target *target, uint32_t *v)
80 int r = target_read_u32(target, SAMV_CONTROLLER_ADDR + OFFSET_EFC_FRR, &rv);
86 static int samv_efc_start_command(struct target *target,
87 unsigned command, unsigned argument)
90 samv_efc_get_status(target, &v);
92 LOG_ERROR("flash controller is not ready");
96 v = (0x5A << 24) | (argument << 8) | command;
97 LOG_DEBUG("starting flash command: 0x%08x", (unsigned int)(v));
98 int r = target_write_u32(target, SAMV_CONTROLLER_ADDR + OFFSET_EFC_FCR, v);
100 LOG_DEBUG("write failed");
104 static int samv_efc_perform_command(struct target *target,
105 unsigned command, unsigned argument, uint32_t *status)
109 int64_t ms_now, ms_end;
114 r = samv_efc_start_command(target, command, argument);
118 ms_end = 10000 + timeval_ms();
121 r = samv_efc_get_status(target, &v);
124 ms_now = timeval_ms();
125 if (ms_now > ms_end) {
127 LOG_ERROR("Command timeout");
130 } while ((v & 1) == 0);
132 /* if requested, copy the flash controller error bits back to the caller */
138 static int samv_erase_pages(struct target *target,
139 int first_page, int num_pages, uint32_t *status)
161 * According to the datasheet FARG[15:2] defines the page from which
162 * the erase will start.This page must be modulo 4, 8, 16 or 32
163 * according to the number of pages to erase. FARG[1:0] defines the
164 * number of pages to be erased. Previously (firstpage << 2) was used
165 * to conform to this, seems it should not be shifted...
167 return samv_efc_perform_command(target, SAMV_EFC_FCMD_EPA,
168 first_page | erase_pages, status);
171 static int samv_get_gpnvm(struct target *target, unsigned gpnvm, unsigned *out)
176 if (gpnvm >= SAMV_NUM_GPNVM_BITS) {
177 LOG_ERROR("invalid gpnvm %d, max: %d", gpnvm, SAMV_NUM_GPNVM_BITS);
181 r = samv_efc_perform_command(target, SAMV_EFC_FCMD_GFB, 0, NULL);
183 LOG_ERROR("samv_get_gpnvm failed");
187 r = samv_efc_get_result(target, &v);
190 *out = (v >> gpnvm) & 1;
195 static int samv_clear_gpnvm(struct target *target, unsigned gpnvm)
200 if (gpnvm >= SAMV_NUM_GPNVM_BITS) {
201 LOG_ERROR("invalid gpnvm %d, max: %d", gpnvm, SAMV_NUM_GPNVM_BITS);
204 r = samv_get_gpnvm(target, gpnvm, &v);
206 LOG_DEBUG("get gpnvm failed: %d", r);
209 r = samv_efc_perform_command(target, SAMV_EFC_FCMD_CFB, gpnvm, NULL);
210 LOG_DEBUG("clear gpnvm result: %d", r);
214 static int samv_set_gpnvm(struct target *target, unsigned gpnvm)
218 if (gpnvm >= SAMV_NUM_GPNVM_BITS) {
219 LOG_ERROR("invalid gpnvm %d, max: %d", gpnvm, SAMV_NUM_GPNVM_BITS);
223 r = samv_get_gpnvm(target, gpnvm, &v);
227 r = ERROR_OK; /* the gpnvm bit is already set */
229 /* we need to set it */
230 r = samv_efc_perform_command(target, SAMV_EFC_FCMD_SFB, gpnvm, NULL);
235 static int samv_flash_unlock(struct target *target,
236 unsigned start_sector, unsigned end_sector)
241 uint32_t pages_per_sector;
243 /* todo: look into this... i think this should be done on lock regions */
244 pages_per_sector = SAMV_SECTOR_SIZE / SAMV_PAGE_SIZE;
245 while (start_sector <= end_sector) {
246 pg = start_sector * pages_per_sector;
247 r = samv_efc_perform_command(target, SAMV_EFC_FCMD_CLB, pg, &status);
255 static int samv_flash_lock(struct target *target,
256 unsigned start_sector, unsigned end_sector)
260 uint32_t pages_per_sector;
263 /* todo: look into this... i think this should be done on lock regions */
264 pages_per_sector = SAMV_SECTOR_SIZE / SAMV_PAGE_SIZE;
265 while (start_sector <= end_sector) {
266 pg = start_sector * pages_per_sector;
267 r = samv_efc_perform_command(target, SAMV_EFC_FCMD_SLB, pg, &status);
275 static int samv_protect_check(struct flash_bank *bank)
280 r = samv_efc_perform_command(bank->target, SAMV_EFC_FCMD_GLB, 0, NULL);
282 samv_efc_get_result(bank->target, &v[0]);
283 samv_efc_get_result(bank->target, &v[1]);
284 samv_efc_get_result(bank->target, &v[2]);
285 r = samv_efc_get_result(bank->target, &v[3]);
290 for (unsigned int x = 0; x < bank->num_sectors; x++)
291 bank->sectors[x].is_protected = (!!(v[x >> 5] & (1 << (x % 32))));
295 FLASH_BANK_COMMAND_HANDLER(samv_flash_bank_command)
297 LOG_INFO("flash bank command");
298 struct samv_flash_bank *samv_info;
299 samv_info = calloc(1, sizeof(struct samv_flash_bank));
300 bank->driver_priv = samv_info;
304 static int samv_get_device_id(struct flash_bank *bank, uint32_t *device_id)
306 return target_read_u32(bank->target, SAMV_CHIPID_CIDR, device_id);
309 static int samv_probe(struct flash_bank *bank)
312 int r = samv_get_device_id(bank, &device_id);
315 LOG_INFO("device id = 0x%08" PRIx32 "", device_id);
317 uint8_t eproc = (device_id >> 5) & 0x7;
319 LOG_ERROR("unexpected eproc code: %d was expecting 0 (Cortex-M7)", eproc);
323 uint8_t nvm_size_code = (device_id >> 8) & 0xf;
324 switch (nvm_size_code) {
326 bank->size = 512 * 1024;
329 bank->size = 1024 * 1024;
332 bank->size = 2048 * 1024;
335 LOG_ERROR("unrecognized flash size code: %d", nvm_size_code);
339 struct samv_flash_bank *samv_info = bank->driver_priv;
340 samv_info->size_bytes = bank->size;
341 samv_info->probed = true;
343 bank->base = SAMV_FLASH_BASE;
344 bank->num_sectors = bank->size / SAMV_SECTOR_SIZE;
345 bank->sectors = calloc(bank->num_sectors, sizeof(struct flash_sector));
346 for (unsigned int s = 0; s < bank->num_sectors; s++) {
347 bank->sectors[s].size = SAMV_SECTOR_SIZE;
348 bank->sectors[s].offset = s * SAMV_SECTOR_SIZE;
349 bank->sectors[s].is_erased = -1;
350 bank->sectors[s].is_protected = -1;
353 r = samv_protect_check(bank);
360 static int samv_auto_probe(struct flash_bank *bank)
362 struct samv_flash_bank *samv_info = bank->driver_priv;
363 if (samv_info->probed)
365 return samv_probe(bank);
368 static int samv_erase(struct flash_bank *bank, unsigned int first,
371 const int page_count = 32; /* 32 pages equals 16 KB lock region */
373 if (bank->target->state != TARGET_HALTED) {
374 LOG_ERROR("Target not halted");
375 return ERROR_TARGET_NOT_HALTED;
378 int r = samv_auto_probe(bank);
382 /* easy case: we've been requested to erase the entire flash */
383 if ((first == 0) && ((last + 1) == bank->num_sectors))
384 return samv_efc_perform_command(bank->target, SAMV_EFC_FCMD_EA, 0, NULL);
386 LOG_INFO("erasing lock regions %u-%u...", first, last);
388 for (unsigned int i = first; i <= last; i++) {
390 r = samv_erase_pages(bank->target, (i * page_count), page_count, &status);
391 LOG_INFO("erasing lock region %u", i);
393 LOG_ERROR("error performing erase page @ lock region number %u", i);
394 if (status & (1 << 2)) {
395 LOG_ERROR("lock region %u is locked", i);
398 if (status & (1 << 1)) {
399 LOG_ERROR("flash command error @lock region %u", i);
406 static int samv_protect(struct flash_bank *bank, int set, unsigned int first,
409 if (bank->target->state != TARGET_HALTED) {
410 LOG_ERROR("Target not halted");
411 return ERROR_TARGET_NOT_HALTED;
416 r = samv_flash_lock(bank->target, first, last);
418 r = samv_flash_unlock(bank->target, first, last);
423 static int samv_page_read(struct target *target,
424 unsigned page_num, uint8_t *buf)
426 uint32_t addr = SAMV_FLASH_BASE + page_num * SAMV_PAGE_SIZE;
427 int r = target_read_memory(target, addr, 4, SAMV_PAGE_SIZE / 4, buf);
429 LOG_ERROR("flash program failed to read page @ 0x%08x",
430 (unsigned int)(addr));
434 static int samv_page_write(struct target *target,
435 unsigned pagenum, const uint8_t *buf)
438 const uint32_t addr = SAMV_FLASH_BASE + pagenum * SAMV_PAGE_SIZE;
441 LOG_DEBUG("write page %u at address 0x%08x", pagenum, (unsigned int)addr);
442 r = target_write_memory(target, addr, 4, SAMV_PAGE_SIZE / 4, buf);
444 LOG_ERROR("failed to buffer page at 0x%08x", (unsigned int)addr);
448 r = samv_efc_perform_command(target, SAMV_EFC_FCMD_WP, pagenum, &status);
450 LOG_ERROR("error performing write page at 0x%08x", (unsigned int)addr);
451 if (status & (1 << 2)) {
452 LOG_ERROR("page at 0x%08x is locked", (unsigned int)addr);
455 if (status & (1 << 1)) {
456 LOG_ERROR("flash command error at 0x%08x", (unsigned int)addr);
462 static int samv_write(struct flash_bank *bank, const uint8_t *buffer,
463 uint32_t offset, uint32_t count)
465 if (bank->target->state != TARGET_HALTED) {
466 LOG_ERROR("target not halted");
467 return ERROR_TARGET_NOT_HALTED;
473 if ((offset + count) > bank->size) {
474 LOG_ERROR("flash write error - past end of bank");
475 LOG_ERROR(" offset: 0x%08x, count 0x%08x, bank end: 0x%08x",
476 (unsigned int)(offset),
477 (unsigned int)(count),
478 (unsigned int)(bank->size));
482 uint8_t pagebuffer[SAMV_PAGE_SIZE] = {0};
483 uint32_t page_cur = offset / SAMV_PAGE_SIZE;
484 uint32_t page_end = (offset + count - 1) / SAMV_PAGE_SIZE;
486 LOG_DEBUG("offset: 0x%08x, count: 0x%08x",
487 (unsigned int)(offset), (unsigned int)(count));
488 LOG_DEBUG("page start: %d, page end: %d", (int)(page_cur), (int)(page_end));
490 /* Special case: all one page */
492 /* (1) non-aligned start */
494 /* (3) non-aligned end. */
497 uint32_t page_offset;
499 /* handle special case - all one page. */
500 if (page_cur == page_end) {
501 LOG_DEBUG("special case, all in one page");
502 r = samv_page_read(bank->target, page_cur, pagebuffer);
506 page_offset = offset & (SAMV_PAGE_SIZE-1);
507 memcpy(pagebuffer + page_offset, buffer, count);
509 r = samv_page_write(bank->target, page_cur, pagebuffer);
515 /* step 1) handle the non-aligned starting address */
516 page_offset = offset & (SAMV_PAGE_SIZE - 1);
518 LOG_DEBUG("non-aligned start");
519 /* read the partial page */
520 r = samv_page_read(bank->target, page_cur, pagebuffer);
524 /* over-write with new data */
525 uint32_t n = SAMV_PAGE_SIZE - page_offset;
526 memcpy(pagebuffer + page_offset, buffer, n);
528 r = samv_page_write(bank->target, page_cur, pagebuffer);
538 /* By checking that offset is correct here, we also fix a clang warning */
539 assert(offset % SAMV_PAGE_SIZE == 0);
541 /* step 2) handle the full pages */
542 LOG_DEBUG("full page loop: cur=%d, end=%d, count = 0x%08x",
543 (int)page_cur, (int)page_end, (unsigned int)(count));
545 while ((page_cur < page_end) && (count >= SAMV_PAGE_SIZE)) {
546 r = samv_page_write(bank->target, page_cur, buffer);
549 count -= SAMV_PAGE_SIZE;
550 buffer += SAMV_PAGE_SIZE;
554 /* step 3) write final page, if it's partial (otherwise it's already done) */
556 LOG_DEBUG("final partial page, count = 0x%08x", (unsigned int)(count));
557 /* we have a partial page */
558 r = samv_page_read(bank->target, page_cur, pagebuffer);
561 memcpy(pagebuffer, buffer, count); /* data goes at start of page */
562 r = samv_page_write(bank->target, page_cur, pagebuffer);
569 static int samv_get_info(struct flash_bank *bank, struct command_invocation *cmd)
571 struct samv_flash_bank *samv_info = bank->driver_priv;
572 if (!samv_info->probed) {
573 int r = samv_probe(bank);
577 command_print_sameline(cmd, "Cortex-M7 detected with %" PRIu32 " kB flash\n",
582 COMMAND_HANDLER(samv_handle_gpnvm_command)
584 struct flash_bank *bank = get_flash_bank_by_num_noprobe(0);
587 struct samv_flash_bank *samv_info = bank->driver_priv;
588 struct target *target = bank->target;
590 if (target->state != TARGET_HALTED) {
591 LOG_ERROR("target not halted");
592 return ERROR_TARGET_NOT_HALTED;
596 if (!samv_info->probed) {
597 r = samv_auto_probe(bank);
611 if (!strcmp(CMD_ARGV[0], "show") && !strcmp(CMD_ARGV[1], "all"))
615 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], v32);
620 return ERROR_COMMAND_SYNTAX_ERROR;
624 if (!strcmp("show", CMD_ARGV[0])) {
628 for (int x = 0; x < SAMV_NUM_GPNVM_BITS; x++) {
629 r = samv_get_gpnvm(target, x, &v);
632 command_print(CMD, "samv-gpnvm%u: %u", x, v);
636 if ((who >= 0) && (((unsigned)who) < SAMV_NUM_GPNVM_BITS)) {
637 r = samv_get_gpnvm(target, who, &v);
641 command_print(CMD, "samv-gpnvm%u: %u", who, v);
644 command_print(CMD, "invalid gpnvm: %u", who);
645 return ERROR_COMMAND_SYNTAX_ERROR;
650 command_print(CMD, "missing gpnvm number");
651 return ERROR_COMMAND_SYNTAX_ERROR;
654 if (!strcmp("set", CMD_ARGV[0]))
655 r = samv_set_gpnvm(target, who);
656 else if (!strcmp("clr", CMD_ARGV[0]) || !strcmp("clear", CMD_ARGV[0]))
657 r = samv_clear_gpnvm(target, who);
659 command_print(CMD, "unknown command: %s", CMD_ARGV[0]);
660 r = ERROR_COMMAND_SYNTAX_ERROR;
665 static const struct command_registration atsamv_exec_command_handlers[] = {
668 .handler = samv_handle_gpnvm_command,
669 .mode = COMMAND_EXEC,
670 .usage = "[('clr'|'set'|'show') bitnum]",
671 .help = "Without arguments, shows all bits in the gpnvm "
672 "register. Otherwise, clears, sets, or shows one "
673 "General Purpose Non-Volatile Memory (gpnvm) bit.",
675 COMMAND_REGISTRATION_DONE
678 static const struct command_registration atsamv_command_handlers[] = {
682 .help = "atsamv flash command group",
684 .chain = atsamv_exec_command_handlers,
686 COMMAND_REGISTRATION_DONE
689 const struct flash_driver atsamv_flash = {
691 .commands = atsamv_command_handlers,
692 .flash_bank_command = samv_flash_bank_command,
694 .protect = samv_protect,
696 .read = default_flash_read,
698 .auto_probe = samv_auto_probe,
699 .erase_check = default_flash_blank_check,
700 .protect_check = samv_protect_check,
701 .info = samv_get_info,
702 .free_driver_priv = default_flash_free_driver_priv,