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