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

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)