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