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