flash/nor: at91samd modified to use real erase sector size
[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_PROT_BLOCKS    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         int prot_block_size;
290
291         bool probed;
292         struct target *target;
293         struct samd_info *next;
294 };
295
296 static struct samd_info *samd_chips;
297
298
299
300 static const struct samd_part *samd_find_part(uint32_t id)
301 {
302         uint8_t processor = SAMD_GET_PROCESSOR(id);
303         uint8_t family = SAMD_GET_FAMILY(id);
304         uint8_t series = SAMD_GET_SERIES(id);
305         uint8_t devsel = SAMD_GET_DEVSEL(id);
306
307         for (unsigned i = 0; i < ARRAY_SIZE(samd_families); i++) {
308                 if (samd_families[i].processor == processor &&
309                         samd_families[i].series == series &&
310                         samd_families[i].family == family) {
311                         for (unsigned j = 0; j < samd_families[i].num_parts; j++) {
312                                 if (samd_families[i].parts[j].id == devsel)
313                                         return &samd_families[i].parts[j];
314                         }
315                 }
316         }
317
318         return NULL;
319 }
320
321 static int samd_protect_check(struct flash_bank *bank)
322 {
323         int res, prot_block;
324         uint16_t lock;
325
326         res = target_read_u16(bank->target,
327                         SAMD_NVMCTRL + SAMD_NVMCTRL_LOCK, &lock);
328         if (res != ERROR_OK)
329                 return res;
330
331         /* Lock bits are active-low */
332         for (prot_block = 0; prot_block < bank->num_prot_blocks; prot_block++)
333                 bank->prot_blocks[prot_block].is_protected = !(lock & (1u<<prot_block));
334
335         return ERROR_OK;
336 }
337
338 static int samd_get_flash_page_info(struct target *target,
339                 uint32_t *sizep, int *nump)
340 {
341         int res;
342         uint32_t param;
343
344         res = target_read_u32(target, SAMD_NVMCTRL + SAMD_NVMCTRL_PARAM, &param);
345         if (res == ERROR_OK) {
346                 /* The PSZ field (bits 18:16) indicate the page size bytes as 2^(3+n)
347                  * so 0 is 8KB and 7 is 1024KB. */
348                 if (sizep)
349                         *sizep = (8 << ((param >> 16) & 0x7));
350                 /* The NVMP field (bits 15:0) indicates the total number of pages */
351                 if (nump)
352                         *nump = param & 0xFFFF;
353         } else {
354                 LOG_ERROR("Couldn't read NVM Parameters register");
355         }
356
357         return res;
358 }
359
360 static int samd_probe(struct flash_bank *bank)
361 {
362         uint32_t id;
363         int res;
364         struct samd_info *chip = (struct samd_info *)bank->driver_priv;
365         const struct samd_part *part;
366
367         if (chip->probed)
368                 return ERROR_OK;
369
370         res = target_read_u32(bank->target, SAMD_DSU + SAMD_DSU_DID, &id);
371         if (res != ERROR_OK) {
372                 LOG_ERROR("Couldn't read Device ID register");
373                 return res;
374         }
375
376         part = samd_find_part(id);
377         if (part == NULL) {
378                 LOG_ERROR("Couldn't find part corresponding to DID %08" PRIx32, id);
379                 return ERROR_FAIL;
380         }
381
382         bank->size = part->flash_kb * 1024;
383
384         res = samd_get_flash_page_info(bank->target, &chip->page_size,
385                         &chip->num_pages);
386         if (res != ERROR_OK) {
387                 LOG_ERROR("Couldn't determine Flash page size");
388                 return res;
389         }
390
391         /* Sanity check: the total flash size in the DSU should match the page size
392          * multiplied by the number of pages. */
393         if (bank->size != chip->num_pages * chip->page_size) {
394                 LOG_WARNING("SAMD: bank size doesn't match NVM parameters. "
395                                 "Identified %" PRIu32 "KB Flash but NVMCTRL reports %u %" PRIu32 "B pages",
396                                 part->flash_kb, chip->num_pages, chip->page_size);
397         }
398
399         /* Erase granularity = 1 row = 4 pages */
400         chip->sector_size = chip->page_size * 4;
401
402         /* Allocate the sector table */
403         bank->num_sectors = chip->num_pages / 4;
404         bank->sectors = alloc_block_array(0, chip->sector_size, bank->num_sectors);
405         if (!bank->sectors)
406                 return ERROR_FAIL;
407
408         /* 16 protection blocks per device */
409         chip->prot_block_size = bank->size / SAMD_NUM_PROT_BLOCKS;
410
411         /* Allocate the table of protection blocks */
412         bank->num_prot_blocks = SAMD_NUM_PROT_BLOCKS;
413         bank->prot_blocks = alloc_block_array(0, chip->prot_block_size, bank->num_prot_blocks);
414         if (!bank->prot_blocks)
415                 return ERROR_FAIL;
416
417         samd_protect_check(bank);
418
419         /* Done */
420         chip->probed = true;
421
422         LOG_INFO("SAMD MCU: %s (%" PRIu32 "KB Flash, %" PRIu32 "KB RAM)", part->name,
423                         part->flash_kb, part->ram_kb);
424
425         return ERROR_OK;
426 }
427
428 static int samd_check_error(struct target *target)
429 {
430         int ret, ret2;
431         uint16_t status;
432
433         ret = target_read_u16(target,
434                         SAMD_NVMCTRL + SAMD_NVMCTRL_STATUS, &status);
435         if (ret != ERROR_OK) {
436                 LOG_ERROR("Can't read NVM status");
437                 return ret;
438         }
439
440         if ((status & 0x001C) == 0)
441                 return ERROR_OK;
442
443         if (status & (1 << 4)) { /* NVME */
444                 LOG_ERROR("SAMD: NVM Error");
445                 ret = ERROR_FLASH_OPERATION_FAILED;
446         }
447
448         if (status & (1 << 3)) { /* LOCKE */
449                 LOG_ERROR("SAMD: NVM lock error");
450                 ret = ERROR_FLASH_PROTECTED;
451         }
452
453         if (status & (1 << 2)) { /* PROGE */
454                 LOG_ERROR("SAMD: NVM programming error");
455                 ret = ERROR_FLASH_OPER_UNSUPPORTED;
456         }
457
458         /* Clear the error conditions by writing a one to them */
459         ret2 = target_write_u16(target,
460                         SAMD_NVMCTRL + SAMD_NVMCTRL_STATUS, status);
461         if (ret2 != ERROR_OK)
462                 LOG_ERROR("Can't clear NVM error conditions");
463
464         return ret;
465 }
466
467 static int samd_issue_nvmctrl_command(struct target *target, uint16_t cmd)
468 {
469         int res;
470
471         if (target->state != TARGET_HALTED) {
472                 LOG_ERROR("Target not halted");
473                 return ERROR_TARGET_NOT_HALTED;
474         }
475
476         /* Issue the NVM command */
477         res = target_write_u16(target,
478                         SAMD_NVMCTRL + SAMD_NVMCTRL_CTRLA, SAMD_NVM_CMD(cmd));
479         if (res != ERROR_OK)
480                 return res;
481
482         /* Check to see if the NVM command resulted in an error condition. */
483         return samd_check_error(target);
484 }
485
486 static int samd_erase_row(struct target *target, uint32_t address)
487 {
488         int res;
489
490         /* Set an address contained in the row to be erased */
491         res = target_write_u32(target,
492                         SAMD_NVMCTRL + SAMD_NVMCTRL_ADDR, address >> 1);
493
494         /* Issue the Erase Row command to erase that row. */
495         if (res == ERROR_OK)
496                 res = samd_issue_nvmctrl_command(target,
497                                 address == SAMD_USER_ROW ? SAMD_NVM_CMD_EAR : SAMD_NVM_CMD_ER);
498
499         if (res != ERROR_OK)  {
500                 LOG_ERROR("Failed to erase row containing %08" PRIx32, address);
501                 return ERROR_FAIL;
502         }
503
504         return ERROR_OK;
505 }
506
507 static bool is_user_row_reserved_bit(uint8_t bit)
508 {
509         /* See Table 9-3 in the SAMD20 datasheet for more information. */
510         switch (bit) {
511                 /* Reserved bits */
512                 case 3:
513                 case 7:
514                 /* Voltage regulator internal configuration with default value of 0x70,
515                  * may not be changed. */
516                 case 17 ... 24:
517                 /* 41 is voltage regulator internal configuration and must not be
518                  * changed.  42 through 47 are reserved. */
519                 case 41 ... 47:
520                         return true;
521                 default:
522                         break;
523         }
524
525         return false;
526 }
527
528 /* Modify the contents of the User Row in Flash.  These are described in Table
529  * 9-3 of the SAMD20 datasheet.  The User Row itself has a size of one page
530  * and contains a combination of "fuses" and calibration data in bits 24:17.
531  * We therefore try not to erase the row's contents unless we absolutely have
532  * to and we don't permit modifying reserved bits. */
533 static int samd_modify_user_row(struct target *target, uint32_t value,
534                 uint8_t startb, uint8_t endb)
535 {
536         int res;
537         uint32_t nvm_ctrlb;
538         bool manual_wp = true;
539
540         if (is_user_row_reserved_bit(startb) || is_user_row_reserved_bit(endb)) {
541                 LOG_ERROR("Can't modify bits in the requested range");
542                 return ERROR_FAIL;
543         }
544
545         /* Check if we need to do manual page write commands */
546         res = target_read_u32(target, SAMD_NVMCTRL + SAMD_NVMCTRL_CTRLB, &nvm_ctrlb);
547         if (res == ERROR_OK)
548                 manual_wp = (nvm_ctrlb & SAMD_NVM_CTRLB_MANW) != 0;
549
550         /* Retrieve the MCU's page size, in bytes. This is also the size of the
551          * entire User Row. */
552         uint32_t page_size;
553         res = samd_get_flash_page_info(target, &page_size, NULL);
554         if (res != ERROR_OK) {
555                 LOG_ERROR("Couldn't determine Flash page size");
556                 return res;
557         }
558
559         /* Make sure the size is sane before we allocate. */
560         assert(page_size > 0 && page_size <= SAMD_PAGE_SIZE_MAX);
561
562         /* Make sure we're within the single page that comprises the User Row. */
563         if (startb >= (page_size * 8) || endb >= (page_size * 8)) {
564                 LOG_ERROR("Can't modify bits outside the User Row page range");
565                 return ERROR_FAIL;
566         }
567
568         uint8_t *buf = malloc(page_size);
569         if (!buf)
570                 return ERROR_FAIL;
571
572         /* Read the user row (comprising one page) by words. */
573         res = target_read_memory(target, SAMD_USER_ROW, 4, page_size / 4, buf);
574         if (res != ERROR_OK)
575                 goto out_user_row;
576
577         /* We will need to erase before writing if the new value needs a '1' in any
578          * position for which the current value had a '0'.  Otherwise we can avoid
579          * erasing. */
580         uint32_t cur = buf_get_u32(buf, startb, endb - startb + 1);
581         if ((~cur) & value) {
582                 res = samd_erase_row(target, SAMD_USER_ROW);
583                 if (res != ERROR_OK) {
584                         LOG_ERROR("Couldn't erase user row");
585                         goto out_user_row;
586                 }
587         }
588
589         /* Modify */
590         buf_set_u32(buf, startb, endb - startb + 1, value);
591
592         /* Write the page buffer back out to the target. */
593         res = target_write_memory(target, SAMD_USER_ROW, 4, page_size / 4, buf);
594         if (res != ERROR_OK)
595                 goto out_user_row;
596
597         if (manual_wp) {
598                 /* Trigger flash write */
599                 res = samd_issue_nvmctrl_command(target, SAMD_NVM_CMD_WAP);
600         } else {
601                 res = samd_check_error(target);
602         }
603
604 out_user_row:
605         free(buf);
606
607         return res;
608 }
609
610 static int samd_protect(struct flash_bank *bank, int set, int first_prot_bl, int last_prot_bl)
611 {
612         int res = ERROR_OK;
613         int prot_block;
614
615         /* We can issue lock/unlock region commands with the target running but
616          * the settings won't persist unless we're able to modify the LOCK regions
617          * and that requires the target to be halted. */
618         if (bank->target->state != TARGET_HALTED) {
619                 LOG_ERROR("Target not halted");
620                 return ERROR_TARGET_NOT_HALTED;
621         }
622
623         for (prot_block = first_prot_bl; prot_block <= last_prot_bl; prot_block++) {
624                 if (set != bank->prot_blocks[prot_block].is_protected) {
625                         /* Load an address that is within this protection block (we use offset 0) */
626                         res = target_write_u32(bank->target,
627                                                         SAMD_NVMCTRL + SAMD_NVMCTRL_ADDR,
628                                                         bank->prot_blocks[prot_block].offset >> 1);
629                         if (res != ERROR_OK)
630                                 goto exit;
631
632                         /* Tell the controller to lock that block */
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_prot_bl, 48 + last_prot_bl);
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_sect, int last_sect)
660 {
661         int res, s;
662         struct samd_info *chip = (struct samd_info *)bank->driver_priv;
663
664         if (bank->target->state != TARGET_HALTED) {
665                 LOG_ERROR("Target not halted");
666
667                 return ERROR_TARGET_NOT_HALTED;
668         }
669
670         if (!chip->probed) {
671                 if (samd_probe(bank) != ERROR_OK)
672                         return ERROR_FLASH_BANK_NOT_PROBED;
673         }
674
675         /* For each sector to be erased */
676         for (s = first_sect; s <= last_sect; s++) {
677                 res = samd_erase_row(bank->target, bank->sectors[s].offset);
678                 if (res != ERROR_OK) {
679                         LOG_ERROR("SAMD: failed to erase sector %d at 0x%08" PRIx32, s, bank->sectors[s].offset);
680                         return res;
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                 } else {
780                         /* Access through AHB is stalled while flash is being programmed */
781                         usleep(200);
782
783                         res = samd_check_error(bank->target);
784                 }
785
786                 if (res != ERROR_OK) {
787                         LOG_ERROR("%s: write failed at address 0x%08" PRIx32, __func__, address);
788                         goto free_pb;
789                 }
790
791                 /* We're done with the page contents */
792                 count -= nb;
793                 offset += nb;
794                 buffer += nb;
795         }
796
797 free_pb:
798         if (pb)
799                 free(pb);
800
801         return res;
802 }
803
804 FLASH_BANK_COMMAND_HANDLER(samd_flash_bank_command)
805 {
806         struct samd_info *chip = samd_chips;
807
808         while (chip) {
809                 if (chip->target == bank->target)
810                         break;
811                 chip = chip->next;
812         }
813
814         if (!chip) {
815                 /* Create a new chip */
816                 chip = calloc(1, sizeof(*chip));
817                 if (!chip)
818                         return ERROR_FAIL;
819
820                 chip->target = bank->target;
821                 chip->probed = false;
822
823                 bank->driver_priv = chip;
824
825                 /* Insert it into the chips list (at head) */
826                 chip->next = samd_chips;
827                 samd_chips = chip;
828         }
829
830         if (bank->base != SAMD_FLASH) {
831                 LOG_ERROR("Address 0x%08" PRIx32 " invalid bank address (try 0x%08" PRIx32
832                                 "[at91samd series] )",
833                                 bank->base, SAMD_FLASH);
834                 return ERROR_FAIL;
835         }
836
837         return ERROR_OK;
838 }
839
840 COMMAND_HANDLER(samd_handle_info_command)
841 {
842         return ERROR_OK;
843 }
844
845 COMMAND_HANDLER(samd_handle_chip_erase_command)
846 {
847         struct target *target = get_current_target(CMD_CTX);
848         int res = ERROR_FAIL;
849
850         if (target) {
851                 /* Enable access to the DSU by disabling the write protect bit */
852                 target_write_u32(target, SAMD_PAC1, (1<<1));
853                 /* intentionally without error checking - not accessible on secured chip */
854
855                 /* Tell the DSU to perform a full chip erase.  It takes about 240ms to
856                  * perform the erase. */
857                 res = target_write_u8(target, SAMD_DSU + SAMD_DSU_CTRL_EXT, (1<<4));
858                 if (res == ERROR_OK)
859                         command_print(CMD_CTX, "chip erase started");
860                 else
861                         command_print(CMD_CTX, "write to DSU CTRL failed");
862         }
863
864         return res;
865 }
866
867 COMMAND_HANDLER(samd_handle_set_security_command)
868 {
869         int res = ERROR_OK;
870         struct target *target = get_current_target(CMD_CTX);
871
872         if (CMD_ARGC < 1 || (CMD_ARGC >= 1 && (strcmp(CMD_ARGV[0], "enable")))) {
873                 command_print(CMD_CTX, "supply the \"enable\" argument to proceed.");
874                 return ERROR_COMMAND_SYNTAX_ERROR;
875         }
876
877         if (target) {
878                 if (target->state != TARGET_HALTED) {
879                         LOG_ERROR("Target not halted");
880                         return ERROR_TARGET_NOT_HALTED;
881                 }
882
883                 res = samd_issue_nvmctrl_command(target, SAMD_NVM_CMD_SSB);
884
885                 /* Check (and clear) error conditions */
886                 if (res == ERROR_OK)
887                         command_print(CMD_CTX, "chip secured on next power-cycle");
888                 else
889                         command_print(CMD_CTX, "failed to secure chip");
890         }
891
892         return res;
893 }
894
895 COMMAND_HANDLER(samd_handle_eeprom_command)
896 {
897         int res = ERROR_OK;
898         struct target *target = get_current_target(CMD_CTX);
899
900         if (target) {
901                 if (target->state != TARGET_HALTED) {
902                         LOG_ERROR("Target not halted");
903                         return ERROR_TARGET_NOT_HALTED;
904                 }
905
906                 if (CMD_ARGC >= 1) {
907                         int val = atoi(CMD_ARGV[0]);
908                         uint32_t code;
909
910                         if (val == 0)
911                                 code = 7;
912                         else {
913                                 /* Try to match size in bytes with corresponding size code */
914                                 for (code = 0; code <= 6; code++) {
915                                         if (val == (2 << (13 - code)))
916                                                 break;
917                                 }
918
919                                 if (code > 6) {
920                                         command_print(CMD_CTX, "Invalid EEPROM size.  Please see "
921                                                         "datasheet for a list valid sizes.");
922                                         return ERROR_COMMAND_SYNTAX_ERROR;
923                                 }
924                         }
925
926                         res = samd_modify_user_row(target, code, 4, 6);
927                 } else {
928                         uint16_t val;
929                         res = target_read_u16(target, SAMD_USER_ROW, &val);
930                         if (res == ERROR_OK) {
931                                 uint32_t size = ((val >> 4) & 0x7); /* grab size code */
932
933                                 if (size == 0x7)
934                                         command_print(CMD_CTX, "EEPROM is disabled");
935                                 else {
936                                         /* Otherwise, 6 is 256B, 0 is 16KB */
937                                         command_print(CMD_CTX, "EEPROM size is %u bytes",
938                                                         (2 << (13 - size)));
939                                 }
940                         }
941                 }
942         }
943
944         return res;
945 }
946
947 COMMAND_HANDLER(samd_handle_bootloader_command)
948 {
949         int res = ERROR_OK;
950         struct target *target = get_current_target(CMD_CTX);
951
952         if (target) {
953                 if (target->state != TARGET_HALTED) {
954                         LOG_ERROR("Target not halted");
955                         return ERROR_TARGET_NOT_HALTED;
956                 }
957
958                 /* Retrieve the MCU's page size, in bytes. */
959                 uint32_t page_size;
960                 res = samd_get_flash_page_info(target, &page_size, NULL);
961                 if (res != ERROR_OK) {
962                         LOG_ERROR("Couldn't determine Flash page size");
963                         return res;
964                 }
965
966                 if (CMD_ARGC >= 1) {
967                         int val = atoi(CMD_ARGV[0]);
968                         uint32_t code;
969
970                         if (val == 0)
971                                 code = 7;
972                         else {
973                                 /* Try to match size in bytes with corresponding size code */
974                                 for (code = 0; code <= 6; code++) {
975                                         if ((unsigned int)val == (2UL << (8UL - code)) * page_size)
976                                                 break;
977                                 }
978
979                                 if (code > 6) {
980                                         command_print(CMD_CTX, "Invalid bootloader size.  Please "
981                                                         "see datasheet for a list valid sizes.");
982                                         return ERROR_COMMAND_SYNTAX_ERROR;
983                                 }
984
985                         }
986
987                         res = samd_modify_user_row(target, code, 0, 2);
988                 } else {
989                         uint16_t val;
990                         res = target_read_u16(target, SAMD_USER_ROW, &val);
991                         if (res == ERROR_OK) {
992                                 uint32_t size = (val & 0x7); /* grab size code */
993                                 uint32_t nb;
994
995                                 if (size == 0x7)
996                                         nb = 0;
997                                 else
998                                         nb = (2 << (8 - size)) * page_size;
999
1000                                 /* There are 4 pages per row */
1001                                 command_print(CMD_CTX, "Bootloader size is %" PRIu32 " bytes (%" PRIu32 " rows)",
1002                                            nb, (uint32_t)(nb / (page_size * 4)));
1003                         }
1004                 }
1005         }
1006
1007         return res;
1008 }
1009
1010
1011
1012 COMMAND_HANDLER(samd_handle_reset_deassert)
1013 {
1014         struct target *target = get_current_target(CMD_CTX);
1015         int retval = ERROR_OK;
1016         enum reset_types jtag_reset_config = jtag_get_reset_config();
1017
1018         /* If the target has been unresponsive before, try to re-establish
1019          * communication now - CPU is held in reset by DSU, DAP is working */
1020         if (!target_was_examined(target))
1021                 target_examine_one(target);
1022         target_poll(target);
1023
1024         /* In case of sysresetreq, debug retains state set in cortex_m_assert_reset()
1025          * so we just release reset held by DSU
1026          *
1027          * n_RESET (srst) clears the DP, so reenable debug and set vector catch here
1028          *
1029          * After vectreset DSU release is not needed however makes no harm
1030          */
1031         if (target->reset_halt && (jtag_reset_config & RESET_HAS_SRST)) {
1032                 retval = target_write_u32(target, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN);
1033                 if (retval == ERROR_OK)
1034                         retval = target_write_u32(target, DCB_DEMCR,
1035                                 TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
1036                 /* do not return on error here, releasing DSU reset is more important */
1037         }
1038
1039         /* clear CPU Reset Phase Extension bit */
1040         int retval2 = target_write_u8(target, SAMD_DSU + SAMD_DSU_STATUSA, (1<<1));
1041         if (retval2 != ERROR_OK)
1042                 return retval2;
1043
1044         return retval;
1045 }
1046
1047 static const struct command_registration at91samd_exec_command_handlers[] = {
1048         {
1049                 .name = "dsu_reset_deassert",
1050                 .handler = samd_handle_reset_deassert,
1051                 .mode = COMMAND_EXEC,
1052                 .help = "deasert internal reset held by DSU"
1053         },
1054         {
1055                 .name = "info",
1056                 .handler = samd_handle_info_command,
1057                 .mode = COMMAND_EXEC,
1058                 .help = "Print information about the current at91samd chip"
1059                         "and its flash configuration.",
1060         },
1061         {
1062                 .name = "chip-erase",
1063                 .handler = samd_handle_chip_erase_command,
1064                 .mode = COMMAND_EXEC,
1065                 .help = "Erase the entire Flash by using the Chip"
1066                         "Erase feature in the Device Service Unit (DSU).",
1067         },
1068         {
1069                 .name = "set-security",
1070                 .handler = samd_handle_set_security_command,
1071                 .mode = COMMAND_EXEC,
1072                 .help = "Secure the chip's Flash by setting the Security Bit."
1073                         "This makes it impossible to read the Flash contents."
1074                         "The only way to undo this is to issue the chip-erase"
1075                         "command.",
1076         },
1077         {
1078                 .name = "eeprom",
1079                 .usage = "[size_in_bytes]",
1080                 .handler = samd_handle_eeprom_command,
1081                 .mode = COMMAND_EXEC,
1082                 .help = "Show or set the EEPROM size setting, stored in the User Row."
1083                         "Please see Table 20-3 of the SAMD20 datasheet for allowed values."
1084                         "Changes are stored immediately but take affect after the MCU is"
1085                         "reset.",
1086         },
1087         {
1088                 .name = "bootloader",
1089                 .usage = "[size_in_bytes]",
1090                 .handler = samd_handle_bootloader_command,
1091                 .mode = COMMAND_EXEC,
1092                 .help = "Show or set the bootloader size, stored in the User Row."
1093                         "Please see Table 20-2 of the SAMD20 datasheet for allowed values."
1094                         "Changes are stored immediately but take affect after the MCU is"
1095                         "reset.",
1096         },
1097         COMMAND_REGISTRATION_DONE
1098 };
1099
1100 static const struct command_registration at91samd_command_handlers[] = {
1101         {
1102                 .name = "at91samd",
1103                 .mode = COMMAND_ANY,
1104                 .help = "at91samd flash command group",
1105                 .usage = "",
1106                 .chain = at91samd_exec_command_handlers,
1107         },
1108         COMMAND_REGISTRATION_DONE
1109 };
1110
1111 struct flash_driver at91samd_flash = {
1112         .name = "at91samd",
1113         .commands = at91samd_command_handlers,
1114         .flash_bank_command = samd_flash_bank_command,
1115         .erase = samd_erase,
1116         .protect = samd_protect,
1117         .write = samd_write,
1118         .read = default_flash_read,
1119         .probe = samd_probe,
1120         .auto_probe = samd_probe,
1121         .erase_check = default_flash_blank_check,
1122         .protect_check = samd_protect_check,
1123 };