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