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