arm_adi_v5: Remove all mem_ap_sel_* functions
[openocd.git] / src / flash / nor / at91sam4l.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
27 #include <target/cortex_m.h>
28
29 /* At this time, the SAM4L Flash is available in these capacities:
30 * ATSAM4Lx4xx: 256KB (512 pages)
31 * ATSAM4Lx2xx: 128KB (256 pages)
32 * ATSAM4Lx8xx: 512KB (1024 pages)
33 */
34
35 /* There are 16 lockable regions regardless of overall capacity. The number
36 * of pages per sector is therefore dependant on capacity. */
37 #define SAM4L_NUM_SECTORS 16
38
39 /* Locations in memory map */
40 #define SAM4L_FLASH ((uint32_t)0x00000000) /* Flash region */
41 #define SAM4L_FLASH_USER 0x00800000 /* Flash user page region */
42 #define SAM4L_FLASHCALW 0x400A0000 /* Flash controller */
43 #define SAM4L_CHIPID 0x400E0740 /* Chip Identification */
44
45 /* Offsets from SAM4L_FLASHCALW */
46 #define SAM4L_FCR 0x00 /* Flash Control Register (RW) */
47 #define SAM4L_FCMD 0x04 /* Flash Command Register (RW) */
48 #define SAM4L_FSR 0x08 /* Flash Status Register (RO) */
49 #define SAM4L_FPR 0x0C /* Flash Parameter Register (RO) */
50 #define SAM4L_FVR 0x10 /* Flash Version Register (RO) */
51 #define SAM4L_FGPFRHI 0x14 /* Flash General Purpose Register High (RO) */
52 #define SAM4L_FGPFRLO 0x18 /* Flash General Purpose Register Low (RO) */
53
54 /* Offsets from SAM4L_CHIPID */
55 #define SAM4L_CIDR 0x00 /* Chip ID Register (RO) */
56 #define SAM4L_EXID 0x04 /* Chip ID Extension Register (RO) */
57
58 /* Flash commands (for SAM4L_FCMD), see Table 14-5 */
59 #define SAM4L_FCMD_NOP 0 /* No Operation */
60 #define SAM4L_FCMD_WP 1 /* Write Page */
61 #define SAM4L_FCMD_EP 2 /* Erase Page */
62 #define SAM4L_FCMD_CPB 3 /* Clear Page Buffer */
63 #define SAM4L_FCMD_LP 4 /* Lock region containing given page */
64 #define SAM4L_FCMD_UP 5 /* Unlock region containing given page */
65 #define SAM4L_FCMD_EA 6 /* Erase All */
66 #define SAM4L_FCMD_WGPB 7 /* Write general-purpose fuse bit */
67 #define SAM4L_FCMD_EGPB 8 /* Erase general-purpose fuse bit */
68 #define SAM4L_FCMD_SSB 9 /* Set security fuses */
69 #define SAM4L_FCMD_PGPFB 10 /* Program general-purpose fuse byte */
70 #define SAM4L_FCMD_EAGPF 11 /* Erase all general-purpose fuse bits */
71 #define SAM4L_FCMD_QPR 12 /* Quick page read */
72 #define SAM4L_FCMD_WUP 13 /* Write user page */
73 #define SAM4L_FCMD_EUP 14 /* Erase user page */
74 #define SAM4L_FCMD_QPRUP 15 /* Quick page read (user page) */
75 #define SAM4L_FCMD_HSEN 16 /* High speed mode enable */
76 #define SAM4L_FCMD_HSDIS 17 /* High speed mode disable */
77
78 #define SAM4L_FMCD_CMDKEY 0xA5UL /* 'key' to issue commands, see 14.10.2 */
79
80
81 /* SMAP registers and bits */
82 #define SMAP_BASE 0x400A3000
83
84 #define SMAP_SCR (SMAP_BASE + 8)
85 #define SMAP_SCR_HCR (1 << 1)
86
87
88 struct sam4l_chip_info {
89 uint32_t id;
90 uint32_t exid;
91 const char *name;
92 };
93
94 /* These are taken from Table 9-1 in 42023E-SAM-07/2013 */
95 static const struct sam4l_chip_info sam4l_known_chips[] = {
96 { 0xAB0B0AE0, 0x1400000F, "ATSAM4LC8C" },
97 { 0xAB0A09E0, 0x0400000F, "ATSAM4LC4C" },
98 { 0xAB0A07E0, 0x0400000F, "ATSAM4LC2C" },
99 { 0xAB0B0AE0, 0x1300000F, "ATSAM4LC8B" },
100 { 0xAB0A09E0, 0x0300000F, "ATSAM4LC4B" },
101 { 0xAB0A07E0, 0x0300000F, "ATSAM4LC2B" },
102 { 0xAB0B0AE0, 0x1200000F, "ATSAM4LC8A" },
103 { 0xAB0A09E0, 0x0200000F, "ATSAM4LC4A" },
104 { 0xAB0A07E0, 0x0200000F, "ATSAM4LC2A" },
105 { 0xAB0B0AE0, 0x14000002, "ATSAM4LS8C" },
106 { 0xAB0A09E0, 0x04000002, "ATSAM4LS4C" },
107 { 0xAB0A07E0, 0x04000002, "ATSAM4LS2C" },
108 { 0xAB0B0AE0, 0x13000002, "ATSAM4LS8B" },
109 { 0xAB0A09E0, 0x03000002, "ATSAM4LS4B" },
110 { 0xAB0A07E0, 0x03000002, "ATSAM4LS2B" },
111 { 0xAB0B0AE0, 0x12000002, "ATSAM4LS8A" },
112 { 0xAB0A09E0, 0x02000002, "ATSAM4LS4A" },
113 { 0xAB0A07E0, 0x02000002, "ATSAM4LS2A" },
114 };
115
116 /* Meaning of SRAMSIZ field in CHIPID, see 9.3.1 in 42023E-SAM-07/2013 */
117 static const uint16_t sam4l_ram_sizes[16] = { 48, 1, 2, 6, 24, 4, 80, 160, 8, 16, 32, 64, 128, 256, 96, 512 };
118
119 /* Meaning of PSZ field in FPR, see 14.10.4 in 42023E-SAM-07/2013 */
120 static const uint16_t sam4l_page_sizes[8] = { 32, 64, 128, 256, 512, 1024, 2048, 4096 };
121
122 struct sam4l_info {
123 const struct sam4l_chip_info *details;
124
125 uint32_t flash_kb;
126 uint32_t ram_kb;
127 uint32_t page_size;
128 int num_pages;
129 int sector_size;
130 int pages_per_sector;
131
132 bool probed;
133 struct target *target;
134 struct sam4l_info *next;
135 };
136
137 static struct sam4l_info *sam4l_chips;
138
139 static int sam4l_flash_wait_until_ready(struct target *target)
140 {
141 volatile unsigned int t = 0;
142 uint32_t st;
143 int res;
144
145 /* Poll the status register until the FRDY bit is set */
146 do {
147 res = target_read_u32(target, SAM4L_FLASHCALW + SAM4L_FSR, &st);
148 } while (res == ERROR_OK && !(st & (1<<0)) && ++t < 10);
149
150 return res;
151 }
152
153 static int sam4l_flash_check_error(struct target *target, uint32_t *err)
154 {
155 uint32_t st;
156 int res;
157
158 res = target_read_u32(target, SAM4L_FLASHCALW + SAM4L_FSR, &st);
159
160 if (res == ERROR_OK)
161 *err = st & ((1<<3) | (1<<2)); /* grab PROGE and LOCKE bits */
162
163 return res;
164 }
165
166 static int sam4l_flash_command(struct target *target, uint8_t cmd, int page)
167 {
168 int res;
169 uint32_t fcmd;
170 uint32_t err;
171
172 res = sam4l_flash_wait_until_ready(target);
173 if (res != ERROR_OK)
174 return res;
175
176 if (page >= 0) {
177 /* Set the page number. For some commands, the page number is just an
178 * argument (ex: fuse bit number). */
179 fcmd = (SAM4L_FMCD_CMDKEY << 24) | ((page & 0xFFFF) << 8) | (cmd & 0x3F);
180 } else {
181 /* Reuse the page number that was read from the flash command register. */
182 res = target_read_u32(target, SAM4L_FLASHCALW + SAM4L_FCMD, &fcmd);
183 if (res != ERROR_OK)
184 return res;
185
186 fcmd &= ~0x3F; /* clear out the command code */
187 fcmd |= (SAM4L_FMCD_CMDKEY << 24) | (cmd & 0x3F);
188 }
189
190 /* Send the command */
191 res = target_write_u32(target, SAM4L_FLASHCALW + SAM4L_FCMD, fcmd);
192 if (res != ERROR_OK)
193 return res;
194
195 res = sam4l_flash_check_error(target, &err);
196 if (res != ERROR_OK)
197 return res;
198
199 if (err != 0)
200 LOG_ERROR("%s got error status 0x%08" PRIx32, __func__, err);
201
202 res = sam4l_flash_wait_until_ready(target);
203
204 return res;
205 }
206
207 FLASH_BANK_COMMAND_HANDLER(sam4l_flash_bank_command)
208 {
209 struct sam4l_info *chip = sam4l_chips;
210
211 while (chip) {
212 if (chip->target == bank->target)
213 break;
214 chip = chip->next;
215 }
216
217 if (!chip) {
218 /* Create a new chip */
219 chip = calloc(1, sizeof(*chip));
220 if (!chip)
221 return ERROR_FAIL;
222
223 chip->target = bank->target;
224 chip->probed = false;
225
226 bank->driver_priv = chip;
227
228 /* Insert it into the chips list (at head) */
229 chip->next = sam4l_chips;
230 sam4l_chips = chip;
231 }
232
233 if (bank->base != SAM4L_FLASH) {
234 LOG_ERROR("Address 0x%08" PRIx32 " invalid bank address (try 0x%08" PRIx32
235 "[at91sam4l series] )",
236 bank->base, SAM4L_FLASH);
237 return ERROR_FAIL;
238 }
239
240 return ERROR_OK;
241 }
242
243 static const struct sam4l_chip_info *sam4l_find_chip_name(uint32_t id, uint32_t exid)
244 {
245 unsigned int i;
246
247 id &= ~0xF;
248
249 for (i = 0; i < ARRAY_SIZE(sam4l_known_chips); i++) {
250 if (sam4l_known_chips[i].id == id && sam4l_known_chips[i].exid == exid)
251 return &sam4l_known_chips[i];
252 }
253
254 return NULL;
255 }
256
257 static int sam4l_check_page_erased(struct flash_bank *bank, uint32_t pn,
258 bool *is_erased_p)
259 {
260 int res;
261 uint32_t st;
262
263 /* Issue a quick page read to verify that we've erased this page */
264 res = sam4l_flash_command(bank->target, SAM4L_FCMD_QPR, pn);
265 if (res != ERROR_OK) {
266 LOG_ERROR("Quick page read %" PRIu32 " failed", pn);
267 return res;
268 }
269
270 /* Retrieve the flash status */
271 res = target_read_u32(bank->target, SAM4L_FLASHCALW + SAM4L_FSR, &st);
272 if (res != ERROR_OK) {
273 LOG_ERROR("Couldn't read erase status");
274 return res;
275 }
276
277 /* Is the page in question really erased? */
278 *is_erased_p = !!(st & (1<<5));
279
280 return ERROR_OK;
281 }
282
283 static int sam4l_probe(struct flash_bank *bank)
284 {
285 uint32_t id, exid, param;
286 int res;
287 struct sam4l_info *chip = (struct sam4l_info *)bank->driver_priv;
288
289 if (chip->probed)
290 return ERROR_OK;
291
292 res = target_read_u32(bank->target, SAM4L_CHIPID + SAM4L_CIDR, &id);
293 if (res != ERROR_OK) {
294 LOG_ERROR("Couldn't read chip ID");
295 return res;
296 }
297
298 res = target_read_u32(bank->target, SAM4L_CHIPID + SAM4L_EXID, &exid);
299 if (res != ERROR_OK) {
300 LOG_ERROR("Couldn't read extended chip ID");
301 return res;
302 }
303
304 chip->details = sam4l_find_chip_name(id, exid);
305
306 /* The RAM capacity is in a lookup table. */
307 chip->ram_kb = sam4l_ram_sizes[0xF & (id >> 16)];
308
309 switch (0xF & (id >> 8)) {
310 case 0x07:
311 chip->flash_kb = 128;
312 break;
313 case 0x09:
314 chip->flash_kb = 256;
315 break;
316 case 0x0A:
317 chip->flash_kb = 512;
318 break;
319 default:
320 LOG_ERROR("Unknown flash size (chip ID is %08" PRIx32 "), assuming 128K", id);
321 chip->flash_kb = 128;
322 break;
323 }
324
325 /* Retrieve the Flash parameters */
326 res = target_read_u32(bank->target, SAM4L_FLASHCALW + SAM4L_FPR, &param);
327 if (res != ERROR_OK) {
328 LOG_ERROR("Couldn't read Flash parameters");
329 return res;
330 }
331
332 /* Fetch the page size from the parameter register. Technically the flash
333 * capacity is there too though the manual mentions that not all parts will
334 * have it set so we use the Chip ID capacity information instead. */
335 chip->page_size = sam4l_page_sizes[0x7 & (param >> 8)];
336 assert(chip->page_size);
337 chip->num_pages = chip->flash_kb * 1024 / chip->page_size;
338
339 chip->sector_size = (chip->flash_kb * 1024) / SAM4L_NUM_SECTORS;
340 chip->pages_per_sector = chip->sector_size / chip->page_size;
341
342 /* Make sure the bank size is correct */
343 bank->size = chip->flash_kb * 1024;
344
345 /* Allocate the sector table. */
346 bank->num_sectors = SAM4L_NUM_SECTORS;
347 bank->sectors = calloc(bank->num_sectors, (sizeof((bank->sectors)[0])));
348 if (!bank->sectors)
349 return ERROR_FAIL;
350
351 /* Fill out the sector information: all SAM4L sectors are the same size and
352 * there is always a fixed number of them. */
353 for (int i = 0; i < bank->num_sectors; i++) {
354 bank->sectors[i].size = chip->sector_size;
355 bank->sectors[i].offset = i * chip->sector_size;
356 /* mark as unknown */
357 bank->sectors[i].is_erased = -1;
358 bank->sectors[i].is_protected = -1;
359 }
360
361 /* Done */
362 chip->probed = true;
363
364 LOG_INFO("SAM4L MCU: %s (Rev %c) (%" PRIu32 "KB Flash with %d %" PRId32 "B pages, %" PRIu32 "KB RAM)",
365 chip->details ? chip->details->name : "unknown", (char)('A' + (id & 0xF)),
366 chip->flash_kb, chip->num_pages, chip->page_size, chip->ram_kb);
367
368 return ERROR_OK;
369 }
370
371 static int sam4l_protect_check(struct flash_bank *bank)
372 {
373 int res;
374 uint32_t st;
375 struct sam4l_info *chip = (struct sam4l_info *)bank->driver_priv;
376
377 if (bank->target->state != TARGET_HALTED) {
378 LOG_ERROR("Target not halted");
379
380 return ERROR_TARGET_NOT_HALTED;
381 }
382
383 if (!chip->probed) {
384 if (sam4l_probe(bank) != ERROR_OK)
385 return ERROR_FLASH_BANK_NOT_PROBED;
386 }
387
388 res = target_read_u32(bank->target, SAM4L_FLASHCALW + SAM4L_FSR, &st);
389 if (res != ERROR_OK)
390 return res;
391
392 st >>= 16; /* There are 16 lock region bits in the upper half word */
393 for (int i = 0; i < bank->num_sectors; i++)
394 bank->sectors[i].is_protected = !!(st & (1<<i));
395
396 return ERROR_OK;
397 }
398
399 static int sam4l_protect(struct flash_bank *bank, int set, int first, int last)
400 {
401 struct sam4l_info *chip = sam4l_chips;
402
403 if (bank->target->state != TARGET_HALTED) {
404 LOG_ERROR("Target not halted");
405
406 return ERROR_TARGET_NOT_HALTED;
407 }
408
409 if (!chip->probed) {
410 if (sam4l_probe(bank) != ERROR_OK)
411 return ERROR_FLASH_BANK_NOT_PROBED;
412 }
413
414 /* Make sure the pages make sense. */
415 if (first >= bank->num_sectors || last >= bank->num_sectors) {
416 LOG_ERROR("Protect range %d - %d not valid (%d sectors total)", first, last,
417 bank->num_sectors);
418 return ERROR_FAIL;
419 }
420
421 /* Try to lock or unlock each sector in the range. This is done by locking
422 * a region containing one page in that sector, we arbitrarily choose the 0th
423 * page in the sector. */
424 for (int i = first; i <= last; i++) {
425 int res;
426
427 res = sam4l_flash_command(bank->target,
428 set ? SAM4L_FCMD_LP : SAM4L_FCMD_UP, i * chip->pages_per_sector);
429 if (res != ERROR_OK) {
430 LOG_ERROR("Can't %slock region containing page %d", set ? "" : "un", i);
431 return res;
432 }
433 }
434
435 return ERROR_OK;
436 }
437
438 static int sam4l_erase(struct flash_bank *bank, int first, int last)
439 {
440 int ret;
441 struct sam4l_info *chip = (struct sam4l_info *)bank->driver_priv;
442
443 if (bank->target->state != TARGET_HALTED) {
444 LOG_ERROR("Target not halted");
445
446 return ERROR_TARGET_NOT_HALTED;
447 }
448
449 if (!chip->probed) {
450 if (sam4l_probe(bank) != ERROR_OK)
451 return ERROR_FLASH_BANK_NOT_PROBED;
452 }
453
454 /* Make sure the pages make sense. */
455 if (first >= bank->num_sectors || last >= bank->num_sectors) {
456 LOG_ERROR("Erase range %d - %d not valid (%d sectors total)", first, last,
457 bank->num_sectors);
458 return ERROR_FAIL;
459 }
460
461 /* Erase */
462 if ((first == 0) && ((last + 1) == bank->num_sectors)) {
463 LOG_DEBUG("Erasing the whole chip");
464
465 ret = sam4l_flash_command(bank->target, SAM4L_FCMD_EA, -1);
466 if (ret != ERROR_OK) {
467 LOG_ERROR("Erase All failed");
468 return ret;
469 }
470 } else {
471 LOG_DEBUG("Erasing sectors %d through %d...\n", first, last);
472
473 /* For each sector... */
474 for (int i = first; i <= last; i++) {
475 /* For each page in that sector... */
476 for (int j = 0; j < chip->pages_per_sector; j++) {
477 int pn = i * chip->pages_per_sector + j;
478 bool is_erased = false;
479
480 /* Issue the page erase */
481 ret = sam4l_flash_command(bank->target, SAM4L_FCMD_EP, pn);
482 if (ret != ERROR_OK) {
483 LOG_ERROR("Erasing page %d failed", pn);
484 return ret;
485 }
486
487 ret = sam4l_check_page_erased(bank, pn, &is_erased);
488 if (ret != ERROR_OK)
489 return ret;
490
491 if (!is_erased) {
492 LOG_DEBUG("Page %d was not erased.", pn);
493 return ERROR_FAIL;
494 }
495 }
496
497 /* This sector is definitely erased. */
498 bank->sectors[i].is_erased = 1;
499 }
500 }
501
502 return ERROR_OK;
503 }
504
505 /* Write an entire page from host buffer 'buf' to page-aligned 'address' in the
506 * Flash. */
507 static int sam4l_write_page(struct sam4l_info *chip, struct target *target,
508 uint32_t address, const uint8_t *buf)
509 {
510 int res;
511
512 LOG_DEBUG("sam4l_write_page address=%08" PRIx32, address);
513
514 /* Clear the page buffer before we write to it */
515 res = sam4l_flash_command(target, SAM4L_FCMD_CPB, -1);
516 if (res != ERROR_OK) {
517 LOG_ERROR("%s: can't clear page buffer", __func__);
518 return res;
519 }
520
521 /* Write the modified page back to the target's page buffer */
522 res = target_write_memory(target, address, 4, chip->page_size / 4, buf);
523
524 if (res != ERROR_OK) {
525 LOG_ERROR("%s: %d", __func__, __LINE__);
526 return res;
527 }
528
529 /* Commit the page contents to Flash: erase the current page and then
530 * write it out. */
531 res = sam4l_flash_command(target, SAM4L_FCMD_EP, -1);
532 if (res != ERROR_OK)
533 return res;
534 res = sam4l_flash_command(target, SAM4L_FCMD_WP, -1);
535
536 return res;
537 }
538
539 /* Write partial contents into page-aligned 'address' on the Flash from host
540 * buffer 'buf' by writing 'nb' of 'buf' at 'offset' into the Flash page. */
541 static int sam4l_write_page_partial(struct sam4l_info *chip,
542 struct flash_bank *bank, uint32_t address, const uint8_t *buf,
543 uint32_t page_offset, uint32_t nb)
544 {
545 int res;
546 uint8_t *pg = malloc(chip->page_size);
547 if (!pg)
548 return ERROR_FAIL;
549
550 LOG_DEBUG("sam4l_write_page_partial address=%08" PRIx32 " nb=%08" PRIx32, address, nb);
551
552 assert(page_offset + nb < chip->page_size);
553 assert((address % chip->page_size) == 0);
554
555 /* Retrieve the full page contents from Flash */
556 res = target_read_memory(bank->target, address, 4,
557 chip->page_size / 4, pg);
558 if (res != ERROR_OK) {
559 free(pg);
560 return res;
561 }
562
563 /* Insert our partial page over the data from Flash */
564 memcpy(pg + (page_offset % chip->page_size), buf, nb);
565
566 /* Write the page back out */
567 res = sam4l_write_page(chip, bank->target, address, pg);
568 free(pg);
569
570 return res;
571 }
572
573 static int sam4l_write(struct flash_bank *bank, const uint8_t *buffer,
574 uint32_t offset, uint32_t count)
575 {
576 int res;
577 uint32_t nb = 0;
578 struct sam4l_info *chip = (struct sam4l_info *)bank->driver_priv;
579
580 LOG_DEBUG("sam4l_write offset=%08" PRIx32 " count=%08" PRIx32, offset, count);
581
582 if (bank->target->state != TARGET_HALTED) {
583 LOG_ERROR("Target not halted");
584
585 return ERROR_TARGET_NOT_HALTED;
586 }
587
588 if (!chip->probed) {
589 if (sam4l_probe(bank) != ERROR_OK)
590 return ERROR_FLASH_BANK_NOT_PROBED;
591 }
592
593 if (offset % chip->page_size) {
594 /* We're starting at an unaligned offset so we'll write a partial page
595 * comprising that offset and up to the end of that page. */
596 nb = chip->page_size - (offset % chip->page_size);
597 if (nb > count)
598 nb = count;
599 } else if (count < chip->page_size) {
600 /* We're writing an aligned but partial page. */
601 nb = count;
602 }
603
604 if (nb > 0) {
605 res = sam4l_write_page_partial(chip, bank,
606 (offset / chip->page_size) * chip->page_size + bank->base,
607 buffer,
608 offset % chip->page_size, nb);
609 if (res != ERROR_OK)
610 return res;
611
612 /* We're done with the page contents */
613 count -= nb;
614 offset += nb;
615 }
616
617 /* There's at least one aligned page to write out. */
618 if (count >= chip->page_size) {
619 int np = count / chip->page_size + ((count % chip->page_size) ? 1 : 0);
620
621 for (int i = 0; i < np; i++) {
622 if (count >= chip->page_size) {
623 res = sam4l_write_page(chip, bank->target,
624 bank->base + offset,
625 buffer + (i * chip->page_size));
626 /* Advance one page */
627 offset += chip->page_size;
628 count -= chip->page_size;
629 } else {
630 res = sam4l_write_page_partial(chip, bank,
631 bank->base + offset,
632 buffer + (i * chip->page_size), 0, count);
633 /* We're done after this. */
634 offset += count;
635 count = 0;
636 }
637
638 if (res != ERROR_OK)
639 return res;
640 }
641 }
642
643 return ERROR_OK;
644 }
645
646
647 COMMAND_HANDLER(sam4l_handle_reset_deassert)
648 {
649 struct target *target = get_current_target(CMD_CTX);
650 struct armv7m_common *armv7m = target_to_armv7m(target);
651 int retval = ERROR_OK;
652 enum reset_types jtag_reset_config = jtag_get_reset_config();
653
654 /* In case of sysresetreq, debug retains state set in cortex_m_assert_reset()
655 * so we just release reset held by SMAP
656 *
657 * n_RESET (srst) clears the DP, so reenable debug and set vector catch here
658 *
659 * After vectreset SMAP release is not needed however makes no harm
660 */
661 if (target->reset_halt && (jtag_reset_config & RESET_HAS_SRST)) {
662 retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN);
663 if (retval == ERROR_OK)
664 retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DEMCR,
665 TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
666 /* do not return on error here, releasing SMAP reset is more important */
667 }
668
669 int retval2 = mem_ap_write_atomic_u32(armv7m->debug_ap, SMAP_SCR, SMAP_SCR_HCR);
670 if (retval2 != ERROR_OK)
671 return retval2;
672
673 return retval;
674 }
675
676 static const struct command_registration at91sam4l_exec_command_handlers[] = {
677 {
678 .name = "smap_reset_deassert",
679 .handler = sam4l_handle_reset_deassert,
680 .mode = COMMAND_EXEC,
681 .help = "deasert internal reset held by SMAP"
682 },
683 COMMAND_REGISTRATION_DONE
684 };
685
686 static const struct command_registration at91sam4l_command_handlers[] = {
687 {
688 .name = "at91sam4l",
689 .mode = COMMAND_ANY,
690 .help = "at91sam4l flash command group",
691 .usage = "",
692 .chain = at91sam4l_exec_command_handlers,
693 },
694 COMMAND_REGISTRATION_DONE
695 };
696
697 struct flash_driver at91sam4l_flash = {
698 .name = "at91sam4l",
699 .commands = at91sam4l_command_handlers,
700 .flash_bank_command = sam4l_flash_bank_command,
701 .erase = sam4l_erase,
702 .protect = sam4l_protect,
703 .write = sam4l_write,
704 .read = default_flash_read,
705 .probe = sam4l_probe,
706 .auto_probe = sam4l_probe,
707 .erase_check = default_flash_blank_check,
708 .protect_check = sam4l_protect_check,
709 };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)