Fix several format specifiers errors exposed by arm-none-eabi
[fw/openocd] / src / flash / nor / at91samd.c
1 /***************************************************************************
2  *   Copyright (C) 2013 by Andrey Yurovsky                                 *
3  *   Andrey Yurovsky <yurovsky@gmail.com>                                  *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
19  ***************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include "imp.h"
26 #include "helper/binarybuffer.h"
27
28 #define SAMD_NUM_SECTORS        16
29 #define SAMD_PAGE_SIZE_MAX      1024
30
31 #define SAMD_FLASH                      ((uint32_t)0x00000000)  /* physical Flash memory */
32 #define SAMD_USER_ROW           ((uint32_t)0x00804000)  /* User Row of Flash */
33 #define SAMD_PAC1                       0x41000000      /* Peripheral Access Control 1 */
34 #define SAMD_DSU                        0x41002000      /* Device Service Unit */
35 #define SAMD_NVMCTRL            0x41004000      /* Non-volatile memory controller */
36
37 #define SAMD_DSU_DID            0x18            /* Device ID register */
38
39 #define SAMD_NVMCTRL_CTRLA              0x00    /* NVM control A register */
40 #define SAMD_NVMCTRL_CTRLB              0x04    /* NVM control B register */
41 #define SAMD_NVMCTRL_PARAM              0x08    /* NVM parameters register */
42 #define SAMD_NVMCTRL_INTFLAG    0x18    /* NVM Interupt Flag Status & Clear */
43 #define SAMD_NVMCTRL_STATUS             0x18    /* NVM status register */
44 #define SAMD_NVMCTRL_ADDR               0x1C    /* NVM address register */
45 #define SAMD_NVMCTRL_LOCK               0x20    /* NVM Lock section register */
46
47 #define SAMD_CMDEX_KEY          0xA5UL
48 #define SAMD_NVM_CMD(n)         ((SAMD_CMDEX_KEY << 8) | (n & 0x7F))
49
50 /* NVMCTRL commands.  See Table 20-4 in 42129F–SAM–10/2013 */
51 #define SAMD_NVM_CMD_ER         0x02            /* Erase Row */
52 #define SAMD_NVM_CMD_WP         0x04            /* Write Page */
53 #define SAMD_NVM_CMD_EAR        0x05            /* Erase Auxilary Row */
54 #define SAMD_NVM_CMD_WAP        0x06            /* Write Auxilary Page */
55 #define SAMD_NVM_CMD_LR         0x40            /* Lock Region */
56 #define SAMD_NVM_CMD_UR         0x41            /* Unlock Region */
57 #define SAMD_NVM_CMD_SPRM       0x42            /* Set Power Reduction Mode */
58 #define SAMD_NVM_CMD_CPRM       0x43            /* Clear Power Reduction Mode */
59 #define SAMD_NVM_CMD_PBC        0x44            /* Page Buffer Clear */
60 #define SAMD_NVM_CMD_SSB        0x45            /* Set Security Bit */
61 #define SAMD_NVM_CMD_INVALL     0x46            /* Invalidate all caches */
62
63 /* Known identifiers */
64 #define SAMD_PROCESSOR_M0       0x01
65 #define SAMD_FAMILY_D           0x00
66 #define SAMD_SERIES_20          0x00
67 #define SAMD_SERIES_21          0x01
68 #define SAMD_SERIES_10          0x02
69 #define SAMD_SERIES_11          0x03
70
71 struct samd_part {
72         uint8_t id;
73         const char *name;
74         uint32_t flash_kb;
75         uint32_t ram_kb;
76 };
77
78 /* Known SAMD10 parts */
79 static const struct samd_part samd10_parts[] = {
80         { 0x0, "SAMD10D14AMU", 16, 4 },
81         { 0x1, "SAMD10D13AMU", 8, 4 },
82         { 0x2, "SAMD10D12AMU", 4, 4 },
83         { 0x3, "SAMD10D14ASU", 16, 4 },
84         { 0x4, "SAMD10D13ASU", 8, 4 },
85         { 0x5, "SAMD10D12ASU", 4, 4 },
86         { 0x6, "SAMD10C14A", 16, 4 },
87         { 0x7, "SAMD10C13A", 8, 4 },
88         { 0x8, "SAMD10C12A", 4, 4 },
89 };
90
91 /* Known SAMD11 parts */
92 static const struct samd_part samd11_parts[] = {
93         { 0x0, "SAMD11D14AMU", 16, 4 },
94         { 0x1, "SAMD11D13AMU", 8, 4 },
95         { 0x2, "SAMD11D12AMU", 4, 4 },
96         { 0x3, "SAMD11D14ASU", 16, 4 },
97         { 0x4, "SAMD11D13ASU", 8, 4 },
98         { 0x5, "SAMD11D12ASU", 4, 4 },
99         { 0x6, "SAMD11C14A", 16, 4 },
100         { 0x7, "SAMD11C13A", 8, 4 },
101         { 0x8, "SAMD11C12A", 4, 4 },
102 };
103
104 /* Known SAMD20 parts. See Table 12-8 in 42129F–SAM–10/2013 */
105 static const struct samd_part samd20_parts[] = {
106         { 0x0, "SAMD20J18A", 256, 32 },
107         { 0x1, "SAMD20J17A", 128, 16 },
108         { 0x2, "SAMD20J16A", 64, 8 },
109         { 0x3, "SAMD20J15A", 32, 4 },
110         { 0x4, "SAMD20J14A", 16, 2 },
111         { 0x5, "SAMD20G18A", 256, 32 },
112         { 0x6, "SAMD20G17A", 128, 16 },
113         { 0x7, "SAMD20G16A", 64, 8 },
114         { 0x8, "SAMD20G15A", 32, 4 },
115         { 0x9, "SAMD20G14A", 16, 2 },
116         { 0xA, "SAMD20E18A", 256, 32 },
117         { 0xB, "SAMD20E17A", 128, 16 },
118         { 0xC, "SAMD20E16A", 64, 8 },
119         { 0xD, "SAMD20E15A", 32, 4 },
120         { 0xE, "SAMD20E14A", 16, 2 },
121 };
122
123 /* Known SAMD21 parts. */
124 static const struct samd_part samd21_parts[] = {
125         { 0x0, "SAMD21J18A", 256, 32 },
126         { 0x1, "SAMD21J17A", 128, 16 },
127         { 0x2, "SAMD21J16A", 64, 8 },
128         { 0x3, "SAMD21J15A", 32, 4 },
129         { 0x4, "SAMD21J14A", 16, 2 },
130         { 0x5, "SAMD21G18A", 256, 32 },
131         { 0x6, "SAMD21G17A", 128, 16 },
132         { 0x7, "SAMD21G16A", 64, 8 },
133         { 0x8, "SAMD21G15A", 32, 4 },
134         { 0x9, "SAMD21G14A", 16, 2 },
135         { 0xA, "SAMD21E18A", 256, 32 },
136         { 0xB, "SAMD21E17A", 128, 16 },
137         { 0xC, "SAMD21E16A", 64, 8 },
138         { 0xD, "SAMD21E15A", 32, 4 },
139         { 0xE, "SAMD21E14A", 16, 2 },
140 };
141
142 /* Known SAMR21 parts. */
143 static const struct samd_part samr21_parts[] = {
144         { 0x19, "SAMR21G18A", 256, 32 },
145         { 0x1A, "SAMR21G17A", 128, 32 },
146         { 0x1B, "SAMR21G16A",  64, 32 },
147         { 0x1C, "SAMR21E18A", 256, 32 },
148         { 0x1D, "SAMR21E17A", 128, 32 },
149         { 0x1E, "SAMR21E16A",  64, 32 },
150 };
151
152
153 /* Each family of parts contains a parts table in the DEVSEL field of DID.  The
154  * processor ID, family ID, and series ID are used to determine which exact
155  * family this is and then we can use the corresponding table. */
156 struct samd_family {
157         uint8_t processor;
158         uint8_t family;
159         uint8_t series;
160         const struct samd_part *parts;
161         size_t num_parts;
162 };
163
164 /* Known SAMD families */
165 static const struct samd_family samd_families[] = {
166         { SAMD_PROCESSOR_M0, SAMD_FAMILY_D, SAMD_SERIES_20,
167                 samd20_parts, ARRAY_SIZE(samd20_parts) },
168         { SAMD_PROCESSOR_M0, SAMD_FAMILY_D, SAMD_SERIES_21,
169                 samd21_parts, ARRAY_SIZE(samd21_parts) },
170         { SAMD_PROCESSOR_M0, SAMD_FAMILY_D, SAMD_SERIES_21,
171                 samr21_parts, ARRAY_SIZE(samr21_parts) },
172         { SAMD_PROCESSOR_M0, SAMD_FAMILY_D, SAMD_SERIES_10,
173                 samd10_parts, ARRAY_SIZE(samd10_parts) },
174         { SAMD_PROCESSOR_M0, SAMD_FAMILY_D, SAMD_SERIES_11,
175                 samd11_parts, ARRAY_SIZE(samd11_parts) },
176 };
177
178 struct samd_info {
179         uint32_t page_size;
180         int num_pages;
181         int sector_size;
182
183         bool probed;
184         struct target *target;
185         struct samd_info *next;
186 };
187
188 static struct samd_info *samd_chips;
189
190 static const struct samd_part *samd_find_part(uint32_t id)
191 {
192         uint8_t processor = (id >> 28);
193         uint8_t family = (id >> 24) & 0x0F;
194         uint8_t series = (id >> 16) & 0xFF;
195         uint8_t devsel = id & 0xFF;
196
197         for (unsigned i = 0; i < ARRAY_SIZE(samd_families); i++) {
198                 if (samd_families[i].processor == processor &&
199                         samd_families[i].series == series &&
200                         samd_families[i].family == family) {
201                         for (unsigned j = 0; j < samd_families[i].num_parts; j++) {
202                                 if (samd_families[i].parts[j].id == devsel)
203                                         return &samd_families[i].parts[j];
204                         }
205                 }
206         }
207
208         return NULL;
209 }
210
211 static int samd_protect_check(struct flash_bank *bank)
212 {
213         int res;
214         uint16_t lock;
215
216         res = target_read_u16(bank->target,
217                         SAMD_NVMCTRL + SAMD_NVMCTRL_LOCK, &lock);
218         if (res != ERROR_OK)
219                 return res;
220
221         /* Lock bits are active-low */
222         for (int i = 0; i < bank->num_sectors; i++)
223                 bank->sectors[i].is_protected = !(lock & (1<<i));
224
225         return ERROR_OK;
226 }
227
228 static int samd_get_flash_page_info(struct target *target,
229                 uint32_t *sizep, int *nump)
230 {
231         int res;
232         uint32_t param;
233
234         res = target_read_u32(target, SAMD_NVMCTRL + SAMD_NVMCTRL_PARAM, &param);
235         if (res == ERROR_OK) {
236                 /* The PSZ field (bits 18:16) indicate the page size bytes as 2^(3+n)
237                  * so 0 is 8KB and 7 is 1024KB. */
238                 if (sizep)
239                         *sizep = (8 << ((param >> 16) & 0x7));
240                 /* The NVMP field (bits 15:0) indicates the total number of pages */
241                 if (nump)
242                         *nump = param & 0xFFFF;
243         } else {
244                 LOG_ERROR("Couldn't read NVM Parameters register");
245         }
246
247         return res;
248 }
249
250 static int samd_probe(struct flash_bank *bank)
251 {
252         uint32_t id;
253         int res;
254         struct samd_info *chip = (struct samd_info *)bank->driver_priv;
255         const struct samd_part *part;
256
257         if (chip->probed)
258                 return ERROR_OK;
259
260         res = target_read_u32(bank->target, SAMD_DSU + SAMD_DSU_DID, &id);
261         if (res != ERROR_OK) {
262                 LOG_ERROR("Couldn't read Device ID register");
263                 return res;
264         }
265
266         part = samd_find_part(id);
267         if (part == NULL) {
268                 LOG_ERROR("Couldn't find part correspoding to DID %08" PRIx32, id);
269                 return ERROR_FAIL;
270         }
271
272         bank->size = part->flash_kb * 1024;
273
274         chip->sector_size = bank->size / SAMD_NUM_SECTORS;
275
276         res = samd_get_flash_page_info(bank->target, &chip->page_size,
277                         &chip->num_pages);
278         if (res != ERROR_OK) {
279                 LOG_ERROR("Couldn't determine Flash page size");
280                 return res;
281         }
282
283         /* Sanity check: the total flash size in the DSU should match the page size
284          * multiplied by the number of pages. */
285         if (bank->size != chip->num_pages * chip->page_size) {
286                 LOG_WARNING("SAMD: bank size doesn't match NVM parameters. "
287                                 "Identified %" PRIu32 "KB Flash but NVMCTRL reports %u %" PRIu32 "B pages",
288                                 part->flash_kb, chip->num_pages, chip->page_size);
289         }
290
291         /* Allocate the sector table */
292         bank->num_sectors = SAMD_NUM_SECTORS;
293         bank->sectors = calloc(bank->num_sectors, sizeof((bank->sectors)[0]));
294         if (!bank->sectors)
295                 return ERROR_FAIL;
296
297         /* Fill out the sector information: all SAMD sectors are the same size and
298          * there is always a fixed number of them. */
299         for (int i = 0; i < bank->num_sectors; i++) {
300                 bank->sectors[i].size = chip->sector_size;
301                 bank->sectors[i].offset = i * chip->sector_size;
302                 /* mark as unknown */
303                 bank->sectors[i].is_erased = -1;
304                 bank->sectors[i].is_protected = -1;
305         }
306
307         samd_protect_check(bank);
308
309         /* Done */
310         chip->probed = true;
311
312         LOG_INFO("SAMD MCU: %s (%" PRIu32 "KB Flash, %" PRIu32 "KB RAM)", part->name,
313                         part->flash_kb, part->ram_kb);
314
315         return ERROR_OK;
316 }
317
318 static bool samd_check_error(struct target *target)
319 {
320         int ret;
321         bool error;
322         uint16_t status;
323
324         ret = target_read_u16(target,
325                         SAMD_NVMCTRL + SAMD_NVMCTRL_STATUS, &status);
326         if (ret != ERROR_OK) {
327                 LOG_ERROR("Can't read NVM status");
328                 return true;
329         }
330
331         if (status & 0x001C) {
332                 if (status & (1 << 4)) /* NVME */
333                         LOG_ERROR("SAMD: NVM Error");
334                 if (status & (1 << 3)) /* LOCKE */
335                         LOG_ERROR("SAMD: NVM lock error");
336                 if (status & (1 << 2)) /* PROGE */
337                         LOG_ERROR("SAMD: NVM programming error");
338
339                 error = true;
340         } else {
341                 error = false;
342         }
343
344         /* Clear the error conditions by writing a one to them */
345         ret = target_write_u16(target,
346                         SAMD_NVMCTRL + SAMD_NVMCTRL_STATUS, status);
347         if (ret != ERROR_OK)
348                 LOG_ERROR("Can't clear NVM error conditions");
349
350         return error;
351 }
352
353 static int samd_issue_nvmctrl_command(struct target *target, uint16_t cmd)
354 {
355         if (target->state != TARGET_HALTED) {
356                 LOG_ERROR("Target not halted");
357                 return ERROR_TARGET_NOT_HALTED;
358         }
359
360         /* Read current configuration. */
361         uint16_t tmp = 0;
362         int res = target_read_u16(target, SAMD_NVMCTRL + SAMD_NVMCTRL_CTRLB,
363                         &tmp);
364         if (res != ERROR_OK)
365                 return res;
366
367         /* Set cache disable. */
368         res = target_write_u16(target, SAMD_NVMCTRL + SAMD_NVMCTRL_CTRLB,
369                         tmp | (1<<18));
370         if (res != ERROR_OK)
371                 return res;
372
373         /* Issue the NVM command */
374         int res_cmd = target_write_u16(target,
375                         SAMD_NVMCTRL + SAMD_NVMCTRL_CTRLA, SAMD_NVM_CMD(cmd));
376
377         /* Try to restore configuration, regardless of NVM command write
378          * status. */
379         res = target_write_u16(target, SAMD_NVMCTRL + SAMD_NVMCTRL_CTRLB, tmp);
380
381         if (res_cmd != ERROR_OK)
382                 return res_cmd;
383
384         if (res != ERROR_OK)
385                 return res;
386
387         /* Check to see if the NVM command resulted in an error condition. */
388         if (samd_check_error(target))
389                 return ERROR_FAIL;
390
391         return ERROR_OK;
392 }
393
394 static int samd_erase_row(struct target *target, uint32_t address)
395 {
396         int res;
397
398         /* Set an address contained in the row to be erased */
399         res = target_write_u32(target,
400                         SAMD_NVMCTRL + SAMD_NVMCTRL_ADDR, address >> 1);
401
402         /* Issue the Erase Row command to erase that row. */
403         if (res == ERROR_OK)
404                 res = samd_issue_nvmctrl_command(target,
405                                 address == SAMD_USER_ROW ? SAMD_NVM_CMD_EAR : SAMD_NVM_CMD_ER);
406
407         if (res != ERROR_OK)  {
408                 LOG_ERROR("Failed to erase row containing %08" PRIx32, address);
409                 return ERROR_FAIL;
410         }
411
412         return ERROR_OK;
413 }
414
415 static bool is_user_row_reserved_bit(uint8_t bit)
416 {
417         /* See Table 9-3 in the SAMD20 datasheet for more information. */
418         switch (bit) {
419                 /* Reserved bits */
420                 case 3:
421                 case 7:
422                 /* Voltage regulator internal configuration with default value of 0x70,
423                  * may not be changed. */
424                 case 17 ... 24:
425                 /* 41 is voltage regulator internal configuration and must not be
426                  * changed.  42 through 47 are reserved. */
427                 case 41 ... 47:
428                         return true;
429                 default:
430                         break;
431         }
432
433         return false;
434 }
435
436 /* Modify the contents of the User Row in Flash.  These are described in Table
437  * 9-3 of the SAMD20 datasheet.  The User Row itself has a size of one page
438  * and contains a combination of "fuses" and calibration data in bits 24:17.
439  * We therefore try not to erase the row's contents unless we absolutely have
440  * to and we don't permit modifying reserved bits. */
441 static int samd_modify_user_row(struct target *target, uint32_t value,
442                 uint8_t startb, uint8_t endb)
443 {
444         int res;
445
446         if (is_user_row_reserved_bit(startb) || is_user_row_reserved_bit(endb)) {
447                 LOG_ERROR("Can't modify bits in the requested range");
448                 return ERROR_FAIL;
449         }
450
451         /* Retrieve the MCU's page size, in bytes. This is also the size of the
452          * entire User Row. */
453         uint32_t page_size;
454         res = samd_get_flash_page_info(target, &page_size, NULL);
455         if (res != ERROR_OK) {
456                 LOG_ERROR("Couldn't determine Flash page size");
457                 return res;
458         }
459
460         /* Make sure the size is sane before we allocate. */
461         assert(page_size > 0 && page_size <= SAMD_PAGE_SIZE_MAX);
462
463         /* Make sure we're within the single page that comprises the User Row. */
464         if (startb >= (page_size * 8) || endb >= (page_size * 8)) {
465                 LOG_ERROR("Can't modify bits outside the User Row page range");
466                 return ERROR_FAIL;
467         }
468
469         uint8_t *buf = malloc(page_size);
470         if (!buf)
471                 return ERROR_FAIL;
472
473         /* Read the user row (comprising one page) by half-words. */
474         res = target_read_memory(target, SAMD_USER_ROW, 2, page_size / 2, buf);
475         if (res != ERROR_OK)
476                 goto out_user_row;
477
478         /* We will need to erase before writing if the new value needs a '1' in any
479          * position for which the current value had a '0'.  Otherwise we can avoid
480          * erasing. */
481         uint32_t cur = buf_get_u32(buf, startb, endb - startb + 1);
482         if ((~cur) & value) {
483                 res = samd_erase_row(target, SAMD_USER_ROW);
484                 if (res != ERROR_OK) {
485                         LOG_ERROR("Couldn't erase user row");
486                         goto out_user_row;
487                 }
488         }
489
490         /* Modify */
491         buf_set_u32(buf, startb, endb - startb + 1, value);
492
493         /* Write the page buffer back out to the target.  A Flash write will be
494          * triggered automatically. */
495         res = target_write_memory(target, SAMD_USER_ROW, 4, page_size / 4, buf);
496         if (res != ERROR_OK)
497                 goto out_user_row;
498
499         if (samd_check_error(target)) {
500                 res = ERROR_FAIL;
501                 goto out_user_row;
502         }
503
504         /* Success */
505         res = ERROR_OK;
506
507 out_user_row:
508         free(buf);
509
510         return res;
511 }
512
513 static int samd_protect(struct flash_bank *bank, int set, int first, int last)
514 {
515         struct samd_info *chip = (struct samd_info *)bank->driver_priv;
516
517         /* We can issue lock/unlock region commands with the target running but
518          * the settings won't persist unless we're able to modify the LOCK regions
519          * and that requires the target to be halted. */
520         if (bank->target->state != TARGET_HALTED) {
521                 LOG_ERROR("Target not halted");
522                 return ERROR_TARGET_NOT_HALTED;
523         }
524
525         int res = ERROR_OK;
526
527         for (int s = first; s <= last; s++) {
528                 if (set != bank->sectors[s].is_protected) {
529                         /* Load an address that is within this sector (we use offset 0) */
530                         res = target_write_u32(bank->target,
531                                                         SAMD_NVMCTRL + SAMD_NVMCTRL_ADDR,
532                                                         ((s * chip->sector_size) >> 1));
533                         if (res != ERROR_OK)
534                                 goto exit;
535
536                         /* Tell the controller to lock that sector */
537                         res = samd_issue_nvmctrl_command(bank->target,
538                                         set ? SAMD_NVM_CMD_LR : SAMD_NVM_CMD_UR);
539                         if (res != ERROR_OK)
540                                 goto exit;
541                 }
542         }
543
544         /* We've now applied our changes, however they will be undone by the next
545          * reset unless we also apply them to the LOCK bits in the User Page.  The
546          * LOCK bits start at bit 48, correspoding to Sector 0 and end with bit 63,
547          * corresponding to Sector 15.  A '1' means unlocked and a '0' means
548          * locked.  See Table 9-3 in the SAMD20 datasheet for more details. */
549
550         res = samd_modify_user_row(bank->target, set ? 0x0000 : 0xFFFF,
551                         48 + first, 48 + last);
552         if (res != ERROR_OK)
553                 LOG_WARNING("SAMD: protect settings were not made persistent!");
554
555         res = ERROR_OK;
556
557 exit:
558         samd_protect_check(bank);
559
560         return res;
561 }
562
563 static int samd_erase(struct flash_bank *bank, int first, int last)
564 {
565         int res;
566         int rows_in_sector;
567         struct samd_info *chip = (struct samd_info *)bank->driver_priv;
568
569         if (bank->target->state != TARGET_HALTED) {
570                 LOG_ERROR("Target not halted");
571
572                 return ERROR_TARGET_NOT_HALTED;
573         }
574
575         if (!chip->probed) {
576                 if (samd_probe(bank) != ERROR_OK)
577                         return ERROR_FLASH_BANK_NOT_PROBED;
578         }
579
580         /* The SAMD NVM has row erase granularity.  There are four pages in a row
581          * and the number of rows in a sector depends on the sector size, which in
582          * turn depends on the Flash capacity as there is a fixed number of
583          * sectors. */
584         rows_in_sector = chip->sector_size / (chip->page_size * 4);
585
586         /* For each sector to be erased */
587         for (int s = first; s <= last; s++) {
588                 if (bank->sectors[s].is_protected) {
589                         LOG_ERROR("SAMD: failed to erase sector %d. That sector is write-protected", s);
590                         return ERROR_FLASH_OPERATION_FAILED;
591                 }
592
593                 if (bank->sectors[s].is_erased != 1) {
594                         /* For each row in that sector */
595                         for (int r = s * rows_in_sector; r < (s + 1) * rows_in_sector; r++) {
596                                 res = samd_erase_row(bank->target, r * chip->page_size * 4);
597                                 if (res != ERROR_OK) {
598                                         LOG_ERROR("SAMD: failed to erase sector %d", s);
599                                         return res;
600                                 }
601                         }
602
603                         bank->sectors[s].is_erased = 1;
604                 }
605         }
606
607         return ERROR_OK;
608 }
609
610 static struct flash_sector *samd_find_sector_by_address(struct flash_bank *bank, uint32_t address)
611 {
612         struct samd_info *chip = (struct samd_info *)bank->driver_priv;
613
614         for (int i = 0; i < bank->num_sectors; i++) {
615                 if (bank->sectors[i].offset <= address &&
616                     address < bank->sectors[i].offset + chip->sector_size)
617                         return &bank->sectors[i];
618         }
619         return NULL;
620 }
621
622 /* Write an entire row (four pages) from host buffer 'buf' to row-aligned
623  * 'address' in the Flash. */
624 static int samd_write_row(struct flash_bank *bank, uint32_t address,
625                 const uint8_t *buf)
626 {
627         int res;
628         struct samd_info *chip = (struct samd_info *)bank->driver_priv;
629
630         struct flash_sector *sector = samd_find_sector_by_address(bank, address);
631
632         if (!sector) {
633                 LOG_ERROR("Can't find sector corresponding to address 0x%08" PRIx32, address);
634                 return ERROR_FLASH_OPERATION_FAILED;
635         }
636
637         if (sector->is_protected) {
638                 LOG_ERROR("Trying to write to a protected sector at 0x%08" PRIx32, address);
639                 return ERROR_FLASH_OPERATION_FAILED;
640         }
641
642         /* Erase the row that we'll be writing to */
643         res = samd_erase_row(bank->target, address);
644         if (res != ERROR_OK)
645                 return res;
646
647         /* Now write the pages in this row. */
648         for (unsigned int i = 0; i < 4; i++) {
649                 bool error;
650
651                 /* Write the page contents to the target's page buffer.  A page write
652                  * is issued automatically once the last location is written in the
653                  * page buffer (ie: a complete page has been written out). */
654                 res = target_write_memory(bank->target, address, 4,
655                                 chip->page_size / 4, buf);
656                 if (res != ERROR_OK) {
657                         LOG_ERROR("%s: %d", __func__, __LINE__);
658                         return res;
659                 }
660
661                 /* Access through AHB is stalled while flash is being programmed */
662                 usleep(200);
663
664                 error = samd_check_error(bank->target);
665                 if (error)
666                         return ERROR_FAIL;
667
668                 /* Next page */
669                 address += chip->page_size;
670                 buf += chip->page_size;
671         }
672
673         sector->is_erased = 0;
674
675         return res;
676 }
677
678 /* Write partial contents into row-aligned 'address' on the Flash from host
679  * buffer 'buf' by writing 'nb' of 'buf' at 'row_offset' into the Flash row. */
680 static int samd_write_row_partial(struct flash_bank *bank, uint32_t address,
681                 const uint8_t *buf, uint32_t row_offset, uint32_t nb)
682 {
683         int res;
684         struct samd_info *chip = (struct samd_info *)bank->driver_priv;
685         uint32_t row_size = chip->page_size * 4;
686         uint8_t *rb = malloc(row_size);
687         if (!rb)
688                 return ERROR_FAIL;
689
690         assert(row_offset + nb < row_size);
691         assert((address % row_size) == 0);
692
693         /* Retrieve the full row contents from Flash */
694         res = target_read_memory(bank->target, address, 4, row_size / 4, rb);
695         if (res != ERROR_OK) {
696                 free(rb);
697                 return res;
698         }
699
700         /* Insert our partial row over the data from Flash */
701         memcpy(rb + (row_offset % row_size), buf, nb);
702
703         /* Write the row back out */
704         res = samd_write_row(bank, address, rb);
705         free(rb);
706
707         return res;
708 }
709
710 static int samd_write(struct flash_bank *bank, const uint8_t *buffer,
711                 uint32_t offset, uint32_t count)
712 {
713         int res;
714         uint32_t address;
715         uint32_t nb = 0;
716         struct samd_info *chip = (struct samd_info *)bank->driver_priv;
717         uint32_t row_size = chip->page_size * 4;
718
719         if (bank->target->state != TARGET_HALTED) {
720                 LOG_ERROR("Target not halted");
721
722                 return ERROR_TARGET_NOT_HALTED;
723         }
724
725         if (!chip->probed) {
726                 if (samd_probe(bank) != ERROR_OK)
727                         return ERROR_FLASH_BANK_NOT_PROBED;
728         }
729
730         if (offset % row_size) {
731                 /* We're starting at an unaligned offset so we'll write a partial row
732                  * comprising that offset and up to the end of that row. */
733                 nb = row_size - (offset % row_size);
734                 if (nb > count)
735                         nb = count;
736         } else if (count < row_size) {
737                 /* We're writing an aligned but partial row. */
738                 nb = count;
739         }
740
741         address = (offset / row_size) * row_size + bank->base;
742
743         if (nb > 0) {
744                 res = samd_write_row_partial(bank, address, buffer,
745                                 offset % row_size, nb);
746                 if (res != ERROR_OK)
747                         return res;
748
749                 /* We're done with the row contents */
750                 count -= nb;
751                 offset += nb;
752                 buffer += row_size;
753         }
754
755         /* There's at least one aligned row to write out. */
756         if (count >= row_size) {
757                 int nr = count / row_size + ((count % row_size) ? 1 : 0);
758                 unsigned int r = 0;
759
760                 for (unsigned int i = address / row_size;
761                                 (i < (address / row_size) + nr) && count > 0; i++) {
762                         address = (i * row_size) + bank->base;
763
764                         if (count >= row_size) {
765                                 res = samd_write_row(bank, address, buffer + (r * row_size));
766                                 /* Advance one row */
767                                 offset += row_size;
768                                 count -= row_size;
769                         } else {
770                                 res = samd_write_row_partial(bank, address,
771                                                 buffer + (r * row_size), 0, count);
772                                 /* We're done after this. */
773                                 offset += count;
774                                 count = 0;
775                         }
776
777                         r++;
778
779                         if (res != ERROR_OK)
780                                 return res;
781                 }
782         }
783
784         return ERROR_OK;
785 }
786
787 FLASH_BANK_COMMAND_HANDLER(samd_flash_bank_command)
788 {
789         struct samd_info *chip = samd_chips;
790
791         while (chip) {
792                 if (chip->target == bank->target)
793                         break;
794                 chip = chip->next;
795         }
796
797         if (!chip) {
798                 /* Create a new chip */
799                 chip = calloc(1, sizeof(*chip));
800                 if (!chip)
801                         return ERROR_FAIL;
802
803                 chip->target = bank->target;
804                 chip->probed = false;
805
806                 bank->driver_priv = chip;
807
808                 /* Insert it into the chips list (at head) */
809                 chip->next = samd_chips;
810                 samd_chips = chip;
811         }
812
813         if (bank->base != SAMD_FLASH) {
814                 LOG_ERROR("Address 0x%08" PRIx32 " invalid bank address (try 0x%08" PRIx32
815                                 "[at91samd series] )",
816                                 bank->base, SAMD_FLASH);
817                 return ERROR_FAIL;
818         }
819
820         return ERROR_OK;
821 }
822
823 COMMAND_HANDLER(samd_handle_info_command)
824 {
825         return ERROR_OK;
826 }
827
828 COMMAND_HANDLER(samd_handle_chip_erase_command)
829 {
830         struct target *target = get_current_target(CMD_CTX);
831
832         if (target) {
833                 /* Enable access to the DSU by disabling the write protect bit */
834                 target_write_u32(target, SAMD_PAC1, (1<<1));
835                 /* Tell the DSU to perform a full chip erase.  It takes about 240ms to
836                  * perform the erase. */
837                 target_write_u8(target, SAMD_DSU, (1<<4));
838
839                 command_print(CMD_CTX, "chip erased");
840         }
841
842         return ERROR_OK;
843 }
844
845 COMMAND_HANDLER(samd_handle_set_security_command)
846 {
847         int res = ERROR_OK;
848         struct target *target = get_current_target(CMD_CTX);
849
850         if (CMD_ARGC < 1 || (CMD_ARGC >= 1 && (strcmp(CMD_ARGV[0], "enable")))) {
851                 command_print(CMD_CTX, "supply the \"enable\" argument to proceed.");
852                 return ERROR_COMMAND_SYNTAX_ERROR;
853         }
854
855         if (target) {
856                 if (target->state != TARGET_HALTED) {
857                         LOG_ERROR("Target not halted");
858                         return ERROR_TARGET_NOT_HALTED;
859                 }
860
861                 res = samd_issue_nvmctrl_command(target, SAMD_NVM_CMD_SSB);
862
863                 /* Check (and clear) error conditions */
864                 if (res == ERROR_OK)
865                         command_print(CMD_CTX, "chip secured on next power-cycle");
866                 else
867                         command_print(CMD_CTX, "failed to secure chip");
868         }
869
870         return res;
871 }
872
873 COMMAND_HANDLER(samd_handle_eeprom_command)
874 {
875         int res = ERROR_OK;
876         struct target *target = get_current_target(CMD_CTX);
877
878         if (target) {
879                 if (target->state != TARGET_HALTED) {
880                         LOG_ERROR("Target not halted");
881                         return ERROR_TARGET_NOT_HALTED;
882                 }
883
884                 if (CMD_ARGC >= 1) {
885                         int val = atoi(CMD_ARGV[0]);
886                         uint32_t code;
887
888                         if (val == 0)
889                                 code = 7;
890                         else {
891                                 /* Try to match size in bytes with corresponding size code */
892                                 for (code = 0; code <= 6; code++) {
893                                         if (val == (2 << (13 - code)))
894                                                 break;
895                                 }
896
897                                 if (code > 6) {
898                                         command_print(CMD_CTX, "Invalid EEPROM size.  Please see "
899                                                         "datasheet for a list valid sizes.");
900                                         return ERROR_COMMAND_SYNTAX_ERROR;
901                                 }
902                         }
903
904                         res = samd_modify_user_row(target, code, 4, 6);
905                 } else {
906                         uint16_t val;
907                         res = target_read_u16(target, SAMD_USER_ROW, &val);
908                         if (res == ERROR_OK) {
909                                 uint32_t size = ((val >> 4) & 0x7); /* grab size code */
910
911                                 if (size == 0x7)
912                                         command_print(CMD_CTX, "EEPROM is disabled");
913                                 else {
914                                         /* Otherwise, 6 is 256B, 0 is 16KB */
915                                         command_print(CMD_CTX, "EEPROM size is %u bytes",
916                                                         (2 << (13 - size)));
917                                 }
918                         }
919                 }
920         }
921
922         return res;
923 }
924
925 COMMAND_HANDLER(samd_handle_bootloader_command)
926 {
927         int res = ERROR_OK;
928         struct target *target = get_current_target(CMD_CTX);
929
930         if (target) {
931                 if (target->state != TARGET_HALTED) {
932                         LOG_ERROR("Target not halted");
933                         return ERROR_TARGET_NOT_HALTED;
934                 }
935
936                 /* Retrieve the MCU's page size, in bytes. */
937                 uint32_t page_size;
938                 res = samd_get_flash_page_info(target, &page_size, NULL);
939                 if (res != ERROR_OK) {
940                         LOG_ERROR("Couldn't determine Flash page size");
941                         return res;
942                 }
943
944                 if (CMD_ARGC >= 1) {
945                         int val = atoi(CMD_ARGV[0]);
946                         uint32_t code;
947
948                         if (val == 0)
949                                 code = 7;
950                         else {
951                                 /* Try to match size in bytes with corresponding size code */
952                                 for (code = 0; code <= 6; code++) {
953                                         if ((unsigned int)val == (2UL << (8UL - code)) * page_size)
954                                                 break;
955                                 }
956
957                                 if (code > 6) {
958                                         command_print(CMD_CTX, "Invalid bootloader size.  Please "
959                                                         "see datasheet for a list valid sizes.");
960                                         return ERROR_COMMAND_SYNTAX_ERROR;
961                                 }
962
963                         }
964
965                         res = samd_modify_user_row(target, code, 0, 2);
966                 } else {
967                         uint16_t val;
968                         res = target_read_u16(target, SAMD_USER_ROW, &val);
969                         if (res == ERROR_OK) {
970                                 uint32_t size = (val & 0x7); /* grab size code */
971                                 uint32_t nb;
972
973                                 if (size == 0x7)
974                                         nb = 0;
975                                 else
976                                         nb = (2 << (8 - size)) * page_size;
977
978                                 /* There are 4 pages per row */
979                                 command_print(CMD_CTX, "Bootloader size is %" PRIu32 " bytes (%" PRIu32 " rows)",
980                                            nb, (uint32_t)(nb / (page_size * 4)));
981                         }
982                 }
983         }
984
985         return res;
986 }
987
988 static const struct command_registration at91samd_exec_command_handlers[] = {
989         {
990                 .name = "info",
991                 .handler = samd_handle_info_command,
992                 .mode = COMMAND_EXEC,
993                 .help = "Print information about the current at91samd chip"
994                         "and its flash configuration.",
995         },
996         {
997                 .name = "chip-erase",
998                 .handler = samd_handle_chip_erase_command,
999                 .mode = COMMAND_EXEC,
1000                 .help = "Erase the entire Flash by using the Chip"
1001                         "Erase feature in the Device Service Unit (DSU).",
1002         },
1003         {
1004                 .name = "set-security",
1005                 .handler = samd_handle_set_security_command,
1006                 .mode = COMMAND_EXEC,
1007                 .help = "Secure the chip's Flash by setting the Security Bit."
1008                         "This makes it impossible to read the Flash contents."
1009                         "The only way to undo this is to issue the chip-erase"
1010                         "command.",
1011         },
1012         {
1013                 .name = "eeprom",
1014                 .usage = "[size_in_bytes]",
1015                 .handler = samd_handle_eeprom_command,
1016                 .mode = COMMAND_EXEC,
1017                 .help = "Show or set the EEPROM size setting, stored in the User Row."
1018                         "Please see Table 20-3 of the SAMD20 datasheet for allowed values."
1019                         "Changes are stored immediately but take affect after the MCU is"
1020                         "reset.",
1021         },
1022         {
1023                 .name = "bootloader",
1024                 .usage = "[size_in_bytes]",
1025                 .handler = samd_handle_bootloader_command,
1026                 .mode = COMMAND_EXEC,
1027                 .help = "Show or set the bootloader size, stored in the User Row."
1028                         "Please see Table 20-2 of the SAMD20 datasheet for allowed values."
1029                         "Changes are stored immediately but take affect after the MCU is"
1030                         "reset.",
1031         },
1032         COMMAND_REGISTRATION_DONE
1033 };
1034
1035 static const struct command_registration at91samd_command_handlers[] = {
1036         {
1037                 .name = "at91samd",
1038                 .mode = COMMAND_ANY,
1039                 .help = "at91samd flash command group",
1040                 .usage = "",
1041                 .chain = at91samd_exec_command_handlers,
1042         },
1043         COMMAND_REGISTRATION_DONE
1044 };
1045
1046 struct flash_driver at91samd_flash = {
1047         .name = "at91samd",
1048         .commands = at91samd_command_handlers,
1049         .flash_bank_command = samd_flash_bank_command,
1050         .erase = samd_erase,
1051         .protect = samd_protect,
1052         .write = samd_write,
1053         .read = default_flash_read,
1054         .probe = samd_probe,
1055         .auto_probe = samd_probe,
1056         .erase_check = default_flash_blank_check,
1057         .protect_check = samd_protect_check,
1058 };