stellaris: automatically generate and update device IDs
[openocd.git] / src / flash / nor / stellaris.c
1 /***************************************************************************
2 * Copyright (C) 2006 by Magnus Lundin *
3 * lundin@mlu.mine.nu *
4 * *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
23
24 /***************************************************************************
25 * STELLARIS flash is tested on LM3S811, LM3S6965, LM3s3748, more.
26 ***************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include "imp.h"
32 #include <target/algorithm.h>
33 #include <target/armv7m.h>
34
35
36 #define DID0_VER(did0) ((did0 >> 28)&0x07)
37
38 /* STELLARIS control registers */
39 #define SCB_BASE 0x400FE000
40 #define DID0 0x000
41 #define DID1 0x004
42 #define DC0 0x008
43 #define DC1 0x010
44 #define DC2 0x014
45 #define DC3 0x018
46 #define DC4 0x01C
47
48 #define RIS 0x050
49 #define RCC 0x060
50 #define PLLCFG 0x064
51 #define RCC2 0x070
52 #define NVMSTAT 0x1a0
53
54 /* "legacy" flash memory protection registers (64KB max) */
55 #define FMPRE 0x130
56 #define FMPPE 0x134
57
58 /* new flash memory protection registers (for more than 64KB) */
59 #define FMPRE0 0x200 /* PRE1 = PRE0 + 4, etc */
60 #define FMPPE0 0x400 /* PPE1 = PPE0 + 4, etc */
61
62 #define USECRL 0x140
63
64 #define FLASH_CONTROL_BASE 0x400FD000
65 #define FLASH_FMA (FLASH_CONTROL_BASE | 0x000)
66 #define FLASH_FMD (FLASH_CONTROL_BASE | 0x004)
67 #define FLASH_FMC (FLASH_CONTROL_BASE | 0x008)
68 #define FLASH_CRIS (FLASH_CONTROL_BASE | 0x00C)
69 #define FLASH_CIM (FLASH_CONTROL_BASE | 0x010)
70 #define FLASH_MISC (FLASH_CONTROL_BASE | 0x014)
71
72 #define AMISC 1
73 #define PMISC 2
74
75 #define AMASK 1
76 #define PMASK 2
77
78 /* Flash Controller Command bits */
79 #define FMC_WRKEY (0xA442 << 16)
80 #define FMC_COMT (1 << 3)
81 #define FMC_MERASE (1 << 2)
82 #define FMC_ERASE (1 << 1)
83 #define FMC_WRITE (1 << 0)
84
85 /* STELLARIS constants */
86
87 /* values to write in FMA to commit write-"once" values */
88 #define FLASH_FMA_PRE(x) (2 * (x)) /* for FMPPREx */
89 #define FLASH_FMA_PPE(x) (2 * (x) + 1) /* for FMPPPEx */
90
91
92 static void stellaris_read_clock_info(struct flash_bank *bank);
93 static int stellaris_mass_erase(struct flash_bank *bank);
94
95 struct stellaris_flash_bank
96 {
97 /* chip id register */
98 uint32_t did0;
99 uint32_t did1;
100 uint32_t dc0;
101 uint32_t dc1;
102
103 const char * target_name;
104
105 uint32_t sramsiz;
106 uint32_t flshsz;
107 /* flash geometry */
108 uint32_t num_pages;
109 uint32_t pagesize;
110 uint32_t pages_in_lockregion;
111
112 /* nv memory bits */
113 uint16_t num_lockbits;
114
115 /* main clock status */
116 uint32_t rcc;
117 uint32_t rcc2;
118 uint8_t mck_valid;
119 uint8_t xtal_mask;
120 uint32_t iosc_freq;
121 uint32_t mck_freq;
122 const char *iosc_desc;
123 const char *mck_desc;
124 };
125
126 // Autogenerated by contrib/gen-stellaris-part-header.pl
127 // From Stellaris Firmware Development Package revision 6734
128 static struct {
129 uint32_t partno;
130 const char *partname;
131 } StellarisParts[] =
132 {
133 {0x0001,"LM3S101"},
134 {0x0002,"LM3S102"},
135 {0x0019,"LM3S300"},
136 {0x0011,"LM3S301"},
137 {0x001A,"LM3S308"},
138 {0x0012,"LM3S310"},
139 {0x0013,"LM3S315"},
140 {0x0014,"LM3S316"},
141 {0x0017,"LM3S317"},
142 {0x0015,"LM3S328"},
143 {0x002A,"LM3S600"},
144 {0x0021,"LM3S601"},
145 {0x002B,"LM3S608"},
146 {0x0022,"LM3S610"},
147 {0x0023,"LM3S611"},
148 {0x0024,"LM3S612"},
149 {0x0025,"LM3S613"},
150 {0x0026,"LM3S615"},
151 {0x0028,"LM3S617"},
152 {0x0029,"LM3S618"},
153 {0x0027,"LM3S628"},
154 {0x0038,"LM3S800"},
155 {0x0031,"LM3S801"},
156 {0x0039,"LM3S808"},
157 {0x0032,"LM3S811"},
158 {0x0033,"LM3S812"},
159 {0x0034,"LM3S815"},
160 {0x0036,"LM3S817"},
161 {0x0037,"LM3S818"},
162 {0x0035,"LM3S828"},
163 {0x10BF,"LM3S1110"},
164 {0x10C3,"LM3S1133"},
165 {0x10C5,"LM3S1138"},
166 {0x10C1,"LM3S1150"},
167 {0x10C4,"LM3S1162"},
168 {0x10C2,"LM3S1165"},
169 {0x10C6,"LM3S1332"},
170 {0x10BC,"LM3S1435"},
171 {0x10BA,"LM3S1439"},
172 {0x10BB,"LM3S1512"},
173 {0x10C7,"LM3S1538"},
174 {0x10DB,"LM3S1601"},
175 {0x1006,"LM3S1607"},
176 {0x10DA,"LM3S1608"},
177 {0x10C0,"LM3S1620"},
178 {0x1003,"LM3S1625"},
179 {0x1004,"LM3S1626"},
180 {0x1005,"LM3S1627"},
181 {0x10B3,"LM3S1635"},
182 {0x10BD,"LM3S1637"},
183 {0x10B1,"LM3S1651"},
184 {0x10B9,"LM3S1751"},
185 {0x1010,"LM3S1776"},
186 {0x1016,"LM3S1811"},
187 {0x103D,"LM3S1816"},
188 {0x10B4,"LM3S1850"},
189 {0x10DD,"LM3S1911"},
190 {0x10DC,"LM3S1918"},
191 {0x10B7,"LM3S1937"},
192 {0x10BE,"LM3S1958"},
193 {0x10B5,"LM3S1960"},
194 {0x10B8,"LM3S1968"},
195 {0x100F,"LM3S1J11"},
196 {0x103C,"LM3S1J16"},
197 {0x100E,"LM3S1N11"},
198 {0x103B,"LM3S1N16"},
199 {0x10B2,"LM3S1P51"},
200 {0x109E,"LM3S1R21"},
201 {0x1030,"LM3S1W16"},
202 {0x102F,"LM3S1Z16"},
203 {0x1051,"LM3S2110"},
204 {0x1084,"LM3S2139"},
205 {0x1039,"LM3S2276"},
206 {0x10A2,"LM3S2410"},
207 {0x1059,"LM3S2412"},
208 {0x1056,"LM3S2432"},
209 {0x105A,"LM3S2533"},
210 {0x10E1,"LM3S2601"},
211 {0x10E0,"LM3S2608"},
212 {0x1033,"LM3S2616"},
213 {0x1057,"LM3S2620"},
214 {0x1085,"LM3S2637"},
215 {0x1053,"LM3S2651"},
216 {0x1080,"LM3S2671"},
217 {0x1050,"LM3S2678"},
218 {0x10A4,"LM3S2730"},
219 {0x1052,"LM3S2739"},
220 {0x103A,"LM3S2776"},
221 {0x106D,"LM3S2793"},
222 {0x10E3,"LM3S2911"},
223 {0x10E2,"LM3S2918"},
224 {0x1054,"LM3S2939"},
225 {0x108F,"LM3S2948"},
226 {0x1058,"LM3S2950"},
227 {0x1055,"LM3S2965"},
228 {0x106C,"LM3S2B93"},
229 {0x1008,"LM3S3634"},
230 {0x1043,"LM3S3651"},
231 {0x1044,"LM3S3739"},
232 {0x1049,"LM3S3748"},
233 {0x1045,"LM3S3749"},
234 {0x1042,"LM3S3826"},
235 {0x1041,"LM3S3J26"},
236 {0x1040,"LM3S3N26"},
237 {0x103F,"LM3S3W26"},
238 {0x103E,"LM3S3Z26"},
239 {0x1081,"LM3S5632"},
240 {0x100C,"LM3S5651"},
241 {0x108A,"LM3S5652"},
242 {0x104D,"LM3S5656"},
243 {0x1091,"LM3S5662"},
244 {0x1096,"LM3S5732"},
245 {0x1097,"LM3S5737"},
246 {0x10A0,"LM3S5739"},
247 {0x1099,"LM3S5747"},
248 {0x10A7,"LM3S5749"},
249 {0x109A,"LM3S5752"},
250 {0x109C,"LM3S5762"},
251 {0x1069,"LM3S5791"},
252 {0x100B,"LM3S5951"},
253 {0x104E,"LM3S5956"},
254 {0x1068,"LM3S5B91"},
255 {0x1009,"LM3S5K31"},
256 {0x104A,"LM3S5K36"},
257 {0x100A,"LM3S5P31"},
258 {0x1048,"LM3S5P36"},
259 {0x100D,"LM3S5P51"},
260 {0x104C,"LM3S5P56"},
261 {0x1007,"LM3S5R31"},
262 {0x104B,"LM3S5R36"},
263 {0x1047,"LM3S5T36"},
264 {0x1046,"LM3S5Y36"},
265 {0x10A1,"LM3S6100"},
266 {0x1074,"LM3S6110"},
267 {0x10A5,"LM3S6420"},
268 {0x1082,"LM3S6422"},
269 {0x1075,"LM3S6432"},
270 {0x1076,"LM3S6537"},
271 {0x1071,"LM3S6610"},
272 {0x10E7,"LM3S6611"},
273 {0x10E6,"LM3S6618"},
274 {0x1083,"LM3S6633"},
275 {0x108B,"LM3S6637"},
276 {0x10A3,"LM3S6730"},
277 {0x1077,"LM3S6753"},
278 {0x10E9,"LM3S6911"},
279 {0x10E8,"LM3S6918"},
280 {0x1089,"LM3S6938"},
281 {0x1072,"LM3S6950"},
282 {0x1078,"LM3S6952"},
283 {0x1073,"LM3S6965"},
284 {0x1064,"LM3S8530"},
285 {0x108E,"LM3S8538"},
286 {0x1061,"LM3S8630"},
287 {0x1063,"LM3S8730"},
288 {0x108D,"LM3S8733"},
289 {0x1086,"LM3S8738"},
290 {0x1065,"LM3S8930"},
291 {0x108C,"LM3S8933"},
292 {0x1088,"LM3S8938"},
293 {0x10A6,"LM3S8962"},
294 {0x1062,"LM3S8970"},
295 {0x10D7,"LM3S8971"},
296 {0x1067,"LM3S9790"},
297 {0x106B,"LM3S9792"},
298 {0x1020,"LM3S9997"},
299 {0x1066,"LM3S9B90"},
300 {0x106A,"LM3S9B92"},
301 {0x106E,"LM3S9B95"},
302 {0x106F,"LM3S9B96"},
303 {0x1018,"LM3S9L97"},
304 {0,"Unknown part"}
305 };
306
307 static char * StellarisClassname[5] =
308 {
309 "Sandstorm",
310 "Fury",
311 "Unknown",
312 "DustDevil",
313 "Tempest"
314 };
315
316 /***************************************************************************
317 * openocd command interface *
318 ***************************************************************************/
319
320 /* flash_bank stellaris <base> <size> 0 0 <target#>
321 */
322 FLASH_BANK_COMMAND_HANDLER(stellaris_flash_bank_command)
323 {
324 struct stellaris_flash_bank *stellaris_info;
325
326 if (CMD_ARGC < 6)
327 {
328 LOG_WARNING("incomplete flash_bank stellaris configuration");
329 return ERROR_FLASH_BANK_INVALID;
330 }
331
332 stellaris_info = calloc(sizeof(struct stellaris_flash_bank), 1);
333 bank->base = 0x0;
334 bank->driver_priv = stellaris_info;
335
336 stellaris_info->target_name = "Unknown target";
337
338 /* part wasn't probed for info yet */
339 stellaris_info->did1 = 0;
340
341 /* TODO Specify the main crystal speed in kHz using an optional
342 * argument; ditto, the speed of an external oscillator used
343 * instead of a crystal. Avoid programming flash using IOSC.
344 */
345 return ERROR_OK;
346 }
347
348 static int get_stellaris_info(struct flash_bank *bank, char *buf, int buf_size)
349 {
350 int printed, device_class;
351 struct stellaris_flash_bank *stellaris_info = bank->driver_priv;
352
353 if (stellaris_info->did1 == 0)
354 return ERROR_FLASH_BANK_NOT_PROBED;
355
356 /* Read main and master clock freqency register */
357 stellaris_read_clock_info(bank);
358
359 if (DID0_VER(stellaris_info->did0) > 0)
360 {
361 device_class = (stellaris_info->did0 >> 16) & 0xFF;
362 }
363 else
364 {
365 device_class = 0;
366 }
367 printed = snprintf(buf,
368 buf_size,
369 "\nTI/LMI Stellaris information: Chip is "
370 "class %i (%s) %s rev %c%i\n",
371 device_class,
372 StellarisClassname[device_class],
373 stellaris_info->target_name,
374 (int)('A' + ((stellaris_info->did0 >> 8) & 0xFF)),
375 (int)((stellaris_info->did0) & 0xFF));
376 buf += printed;
377 buf_size -= printed;
378
379 printed = snprintf(buf,
380 buf_size,
381 "did1: 0x%8.8" PRIx32 ", arch: 0x%4.4" PRIx32
382 ", eproc: %s, ramsize: %ik, flashsize: %ik\n",
383 stellaris_info->did1,
384 stellaris_info->did1,
385 "ARMv7M",
386 (int)((1 + ((stellaris_info->dc0 >> 16) & 0xFFFF))/4),
387 (int)((1 + (stellaris_info->dc0 & 0xFFFF))*2));
388 buf += printed;
389 buf_size -= printed;
390
391 printed = snprintf(buf,
392 buf_size,
393 "master clock: %ikHz%s, "
394 "rcc is 0x%" PRIx32 ", rcc2 is 0x%" PRIx32 "\n",
395 (int)(stellaris_info->mck_freq / 1000),
396 stellaris_info->mck_desc,
397 stellaris_info->rcc,
398 stellaris_info->rcc2);
399 buf += printed;
400 buf_size -= printed;
401
402 if (stellaris_info->num_lockbits > 0)
403 {
404 printed = snprintf(buf,
405 buf_size,
406 "pagesize: %" PRIi32 ", pages: %d, "
407 "lockbits: %i, pages per lockbit: %i\n",
408 stellaris_info->pagesize,
409 (unsigned) stellaris_info->num_pages,
410 stellaris_info->num_lockbits,
411 (unsigned) stellaris_info->pages_in_lockregion);
412 buf += printed;
413 buf_size -= printed;
414 }
415 return ERROR_OK;
416 }
417
418 /***************************************************************************
419 * chip identification and status *
420 ***************************************************************************/
421
422 /* Set the flash timimg register to match current clocking */
423 static void stellaris_set_flash_timing(struct flash_bank *bank)
424 {
425 struct stellaris_flash_bank *stellaris_info = bank->driver_priv;
426 struct target *target = bank->target;
427 uint32_t usecrl = (stellaris_info->mck_freq/1000000ul-1);
428
429 LOG_DEBUG("usecrl = %i",(int)(usecrl));
430 target_write_u32(target, SCB_BASE | USECRL, usecrl);
431 }
432
433 static const unsigned rcc_xtal[32] = {
434 [0x00] = 1000000, /* no pll */
435 [0x01] = 1843200, /* no pll */
436 [0x02] = 2000000, /* no pll */
437 [0x03] = 2457600, /* no pll */
438
439 [0x04] = 3579545,
440 [0x05] = 3686400,
441 [0x06] = 4000000, /* usb */
442 [0x07] = 4096000,
443
444 [0x08] = 4915200,
445 [0x09] = 5000000, /* usb */
446 [0x0a] = 5120000,
447 [0x0b] = 6000000, /* (reset) usb */
448
449 [0x0c] = 6144000,
450 [0x0d] = 7372800,
451 [0x0e] = 8000000, /* usb */
452 [0x0f] = 8192000,
453
454 /* parts before DustDevil use just 4 bits for xtal spec */
455
456 [0x10] = 10000000, /* usb */
457 [0x11] = 12000000, /* usb */
458 [0x12] = 12288000,
459 [0x13] = 13560000,
460
461 [0x14] = 14318180,
462 [0x15] = 16000000, /* usb */
463 [0x16] = 16384000,
464 };
465
466 /** Read clock configuration and set stellaris_info->usec_clocks. */
467 static void stellaris_read_clock_info(struct flash_bank *bank)
468 {
469 struct stellaris_flash_bank *stellaris_info = bank->driver_priv;
470 struct target *target = bank->target;
471 uint32_t rcc, rcc2, pllcfg, sysdiv, usesysdiv, bypass, oscsrc;
472 unsigned xtal;
473 unsigned long mainfreq;
474
475 target_read_u32(target, SCB_BASE | RCC, &rcc);
476 LOG_DEBUG("Stellaris RCC %" PRIx32 "", rcc);
477
478 target_read_u32(target, SCB_BASE | RCC2, &rcc2);
479 LOG_DEBUG("Stellaris RCC2 %" PRIx32 "", rcc);
480
481 target_read_u32(target, SCB_BASE | PLLCFG, &pllcfg);
482 LOG_DEBUG("Stellaris PLLCFG %" PRIx32 "", pllcfg);
483
484 stellaris_info->rcc = rcc;
485 stellaris_info->rcc = rcc2;
486
487 sysdiv = (rcc >> 23) & 0xF;
488 usesysdiv = (rcc >> 22) & 0x1;
489 bypass = (rcc >> 11) & 0x1;
490 oscsrc = (rcc >> 4) & 0x3;
491 xtal = (rcc >> 6) & stellaris_info->xtal_mask;
492
493 /* NOTE: post-Sandstorm parts have RCC2 which may override
494 * parts of RCC ... with more sysdiv options, option for
495 * 32768 Hz mainfreq, PLL controls. On Sandstorm it reads
496 * as zero, so the "use RCC2" flag is always clear.
497 */
498 if (rcc2 & (1 << 31)) {
499 sysdiv = (rcc2 >> 23) & 0x3F;
500 bypass = (rcc2 >> 11) & 0x1;
501 oscsrc = (rcc2 >> 4) & 0x7;
502
503 /* FIXME Tempest parts have an additional lsb for
504 * fractional sysdiv (200 MHz / 2.5 == 80 MHz)
505 */
506 }
507
508 stellaris_info->mck_desc = "";
509
510 switch (oscsrc)
511 {
512 case 0: /* MOSC */
513 mainfreq = rcc_xtal[xtal];
514 break;
515 case 1: /* IOSC */
516 mainfreq = stellaris_info->iosc_freq;
517 stellaris_info->mck_desc = stellaris_info->iosc_desc;
518 break;
519 case 2: /* IOSC/4 */
520 mainfreq = stellaris_info->iosc_freq / 4;
521 stellaris_info->mck_desc = stellaris_info->iosc_desc;
522 break;
523 case 3: /* lowspeed */
524 /* Sandstorm doesn't have this 30K +/- 30% osc */
525 mainfreq = 30000;
526 stellaris_info->mck_desc = " (±30%)";
527 break;
528 case 8: /* hibernation osc */
529 /* not all parts support hibernation */
530 mainfreq = 32768;
531 break;
532
533 default: /* NOTREACHED */
534 mainfreq = 0;
535 break;
536 }
537
538 /* PLL is used if it's not bypassed; its output is 200 MHz
539 * even when it runs at 400 MHz (adds divide-by-two stage).
540 */
541 if (!bypass)
542 mainfreq = 200000000;
543
544 if (usesysdiv)
545 stellaris_info->mck_freq = mainfreq/(1 + sysdiv);
546 else
547 stellaris_info->mck_freq = mainfreq;
548 }
549
550 /* Read device id register, main clock frequency register and fill in driver info structure */
551 static int stellaris_read_part_info(struct flash_bank *bank)
552 {
553 struct stellaris_flash_bank *stellaris_info = bank->driver_priv;
554 struct target *target = bank->target;
555 uint32_t did0, did1, ver, fam;
556 int i;
557
558 /* Read and parse chip identification register */
559 target_read_u32(target, SCB_BASE | DID0, &did0);
560 target_read_u32(target, SCB_BASE | DID1, &did1);
561 target_read_u32(target, SCB_BASE | DC0, &stellaris_info->dc0);
562 target_read_u32(target, SCB_BASE | DC1, &stellaris_info->dc1);
563 LOG_DEBUG("did0 0x%" PRIx32 ", did1 0x%" PRIx32 ", dc0 0x%" PRIx32 ", dc1 0x%" PRIx32 "",
564 did0, did1, stellaris_info->dc0, stellaris_info->dc1);
565
566 ver = did0 >> 28;
567 if ((ver != 0) && (ver != 1))
568 {
569 LOG_WARNING("Unknown did0 version, cannot identify target");
570 return ERROR_FLASH_OPERATION_FAILED;
571 }
572
573 if (did1 == 0)
574 {
575 LOG_WARNING("Cannot identify target as a Stellaris");
576 return ERROR_FLASH_OPERATION_FAILED;
577 }
578
579 ver = did1 >> 28;
580 fam = (did1 >> 24) & 0xF;
581 if (((ver != 0) && (ver != 1)) || (fam != 0))
582 {
583 LOG_WARNING("Unknown did1 version/family.");
584 return ERROR_FLASH_OPERATION_FAILED;
585 }
586
587 /* For Sandstorm, Fury, DustDevil: current data sheets say IOSC
588 * is 12 MHz, but some older parts have 15 MHz. A few data sheets
589 * even give _both_ numbers! We'll use current numbers; IOSC is
590 * always approximate.
591 *
592 * For Tempest: IOSC is calibrated, 16 MHz
593 */
594 stellaris_info->iosc_freq = 12000000;
595 stellaris_info->iosc_desc = " (±30%)";
596 stellaris_info->xtal_mask = 0x0f;
597
598 switch ((did0 >> 28) & 0x7) {
599 case 0: /* Sandstorm */
600 /*
601 * Current (2009-August) parts seem to be rev C2 and use 12 MHz.
602 * Parts before rev C0 used 15 MHz; some C0 parts use 15 MHz
603 * (LM3S618), but some other C0 parts are 12 MHz (LM3S811).
604 */
605 if (((did0 >> 8) & 0xff) < 2) {
606 stellaris_info->iosc_freq = 15000000;
607 stellaris_info->iosc_desc = " (±50%)";
608 }
609 break;
610 case 1:
611 switch ((did0 >> 16) & 0xff) {
612 case 1: /* Fury */
613 break;
614 case 4: /* Tempest */
615 stellaris_info->iosc_freq = 16000000; /* +/- 1% */
616 stellaris_info->iosc_desc = " (±1%)";
617 /* FALL THROUGH */
618 case 3: /* DustDevil */
619 stellaris_info->xtal_mask = 0x1f;
620 break;
621 default:
622 LOG_WARNING("Unknown did0 class");
623 }
624 break;
625 default:
626 LOG_WARNING("Unknown did0 version");
627 break;
628 }
629
630 for (i = 0; StellarisParts[i].partno; i++)
631 {
632 if (StellarisParts[i].partno == ((did1 >> 16) & 0xFFFF))
633 break;
634 }
635
636 stellaris_info->target_name = StellarisParts[i].partname;
637
638 stellaris_info->did0 = did0;
639 stellaris_info->did1 = did1;
640
641 stellaris_info->num_lockbits = 1 + (stellaris_info->dc0 & 0xFFFF);
642 stellaris_info->num_pages = 2 *(1 + (stellaris_info->dc0 & 0xFFFF));
643 stellaris_info->pagesize = 1024;
644 stellaris_info->pages_in_lockregion = 2;
645
646 /* REVISIT for at least Tempest parts, read NVMSTAT.FWB too.
647 * That exposes a 32-word Flash Write Buffer ... enabling
648 * writes of more than one word at a time.
649 */
650
651 return ERROR_OK;
652 }
653
654 /***************************************************************************
655 * flash operations *
656 ***************************************************************************/
657
658 static int stellaris_protect_check(struct flash_bank *bank)
659 {
660 struct stellaris_flash_bank *stellaris = bank->driver_priv;
661 int status = ERROR_OK;
662 unsigned i;
663 unsigned page;
664
665 if (stellaris->did1 == 0)
666 return ERROR_FLASH_BANK_NOT_PROBED;
667
668 for (i = 0; i < (unsigned) bank->num_sectors; i++)
669 bank->sectors[i].is_protected = -1;
670
671 /* Read each Flash Memory Protection Program Enable (FMPPE) register
672 * to report any pages that we can't write. Ignore the Read Enable
673 * register (FMPRE).
674 */
675 for (i = 0, page = 0;
676 i < DIV_ROUND_UP(stellaris->num_lockbits, 32u);
677 i++) {
678 uint32_t lockbits;
679
680 status = target_read_u32(bank->target,
681 SCB_BASE + (i ? (FMPPE0 + 4 * i) : FMPPE),
682 &lockbits);
683 LOG_DEBUG("FMPPE%d = %#8.8x (status %d)", i,
684 (unsigned) lockbits, status);
685 if (status != ERROR_OK)
686 goto done;
687
688 for (unsigned j = 0; j < 32; j++) {
689 unsigned k;
690
691 for (k = 0; k < stellaris->pages_in_lockregion; k++) {
692 if (page >= (unsigned) bank->num_sectors)
693 goto done;
694 bank->sectors[page++].is_protected =
695 !(lockbits & (1 << j));
696 }
697 }
698 }
699
700 done:
701 return status;
702 }
703
704 static int stellaris_erase(struct flash_bank *bank, int first, int last)
705 {
706 int banknr;
707 uint32_t flash_fmc, flash_cris;
708 struct stellaris_flash_bank *stellaris_info = bank->driver_priv;
709 struct target *target = bank->target;
710
711 if (bank->target->state != TARGET_HALTED)
712 {
713 LOG_ERROR("Target not halted");
714 return ERROR_TARGET_NOT_HALTED;
715 }
716
717 if (stellaris_info->did1 == 0)
718 return ERROR_FLASH_BANK_NOT_PROBED;
719
720 if ((first < 0) || (last < first) || (last >= (int)stellaris_info->num_pages))
721 {
722 return ERROR_FLASH_SECTOR_INVALID;
723 }
724
725 if ((first == 0) && (last == ((int)stellaris_info->num_pages-1)))
726 {
727 return stellaris_mass_erase(bank);
728 }
729
730 /* Refresh flash controller timing */
731 stellaris_read_clock_info(bank);
732 stellaris_set_flash_timing(bank);
733
734 /* Clear and disable flash programming interrupts */
735 target_write_u32(target, FLASH_CIM, 0);
736 target_write_u32(target, FLASH_MISC, PMISC | AMISC);
737
738 /* REVISIT this clobbers state set by any halted firmware ...
739 * it might want to process those IRQs.
740 */
741
742 for (banknr = first; banknr <= last; banknr++)
743 {
744 /* Address is first word in page */
745 target_write_u32(target, FLASH_FMA, banknr * stellaris_info->pagesize);
746 /* Write erase command */
747 target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_ERASE);
748 /* Wait until erase complete */
749 do
750 {
751 target_read_u32(target, FLASH_FMC, &flash_fmc);
752 }
753 while (flash_fmc & FMC_ERASE);
754
755 /* Check acess violations */
756 target_read_u32(target, FLASH_CRIS, &flash_cris);
757 if (flash_cris & (AMASK))
758 {
759 LOG_WARNING("Error erasing flash page %i, flash_cris 0x%" PRIx32 "", banknr, flash_cris);
760 target_write_u32(target, FLASH_CRIS, 0);
761 return ERROR_FLASH_OPERATION_FAILED;
762 }
763
764 bank->sectors[banknr].is_erased = 1;
765 }
766
767 return ERROR_OK;
768 }
769
770 static int stellaris_protect(struct flash_bank *bank, int set, int first, int last)
771 {
772 uint32_t fmppe, flash_fmc, flash_cris;
773 int lockregion;
774
775 struct stellaris_flash_bank *stellaris_info = bank->driver_priv;
776 struct target *target = bank->target;
777
778 if (bank->target->state != TARGET_HALTED)
779 {
780 LOG_ERROR("Target not halted");
781 return ERROR_TARGET_NOT_HALTED;
782 }
783
784 if (!set)
785 {
786 LOG_ERROR("Hardware doesn't suppport page-level unprotect. "
787 "Try the 'recover' command.");
788 return ERROR_INVALID_ARGUMENTS;
789 }
790
791 if (stellaris_info->did1 == 0)
792 return ERROR_FLASH_BANK_NOT_PROBED;
793
794 /* lockregions are 2 pages ... must protect [even..odd] */
795 if ((first < 0) || (first & 1)
796 || (last < first) || !(last & 1)
797 || (last >= 2 * stellaris_info->num_lockbits))
798 {
799 LOG_ERROR("Can't protect unaligned or out-of-range pages.");
800 return ERROR_FLASH_SECTOR_INVALID;
801 }
802
803 /* Refresh flash controller timing */
804 stellaris_read_clock_info(bank);
805 stellaris_set_flash_timing(bank);
806
807 /* convert from pages to lockregions */
808 first /= 2;
809 last /= 2;
810
811 /* FIXME this assumes single FMPPE, for a max of 64K of flash!!
812 * Current parts can be much bigger.
813 */
814 if (last >= 32) {
815 LOG_ERROR("No support yet for protection > 64K");
816 return ERROR_FLASH_OPERATION_FAILED;
817 }
818
819 target_read_u32(target, SCB_BASE | FMPPE, &fmppe);
820
821 for (lockregion = first; lockregion <= last; lockregion++)
822 fmppe &= ~(1 << lockregion);
823
824 /* Clear and disable flash programming interrupts */
825 target_write_u32(target, FLASH_CIM, 0);
826 target_write_u32(target, FLASH_MISC, PMISC | AMISC);
827
828 /* REVISIT this clobbers state set by any halted firmware ...
829 * it might want to process those IRQs.
830 */
831
832 LOG_DEBUG("fmppe 0x%" PRIx32 "",fmppe);
833 target_write_u32(target, SCB_BASE | FMPPE, fmppe);
834
835 /* Commit FMPPE */
836 target_write_u32(target, FLASH_FMA, 1);
837
838 /* Write commit command */
839 /* REVISIT safety check, since this cannot be undone
840 * except by the "Recover a locked device" procedure.
841 * REVISIT DustDevil-A0 parts have an erratum making FMPPE commits
842 * inadvisable ... it makes future mass erase operations fail.
843 */
844 LOG_WARNING("Flash protection cannot be removed once commited, commit is NOT executed !");
845 /* target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_COMT); */
846
847 /* Wait until erase complete */
848 do
849 {
850 target_read_u32(target, FLASH_FMC, &flash_fmc);
851 }
852 while (flash_fmc & FMC_COMT);
853
854 /* Check acess violations */
855 target_read_u32(target, FLASH_CRIS, &flash_cris);
856 if (flash_cris & (AMASK))
857 {
858 LOG_WARNING("Error setting flash page protection, flash_cris 0x%" PRIx32 "", flash_cris);
859 target_write_u32(target, FLASH_CRIS, 0);
860 return ERROR_FLASH_OPERATION_FAILED;
861 }
862
863 return ERROR_OK;
864 }
865
866 /* see contib/loaders/flash/stellaris.s for src */
867
868 static const uint8_t stellaris_write_code[] =
869 {
870 /*
871 Call with :
872 r0 = buffer address
873 r1 = destination address
874 r2 = bytecount (in) - endaddr (work)
875
876 Used registers:
877 r3 = pFLASH_CTRL_BASE
878 r4 = FLASHWRITECMD
879 r5 = #1
880 r6 = bytes written
881 r7 = temp reg
882 */
883 0x07,0x4B, /* ldr r3,pFLASH_CTRL_BASE */
884 0x08,0x4C, /* ldr r4,FLASHWRITECMD */
885 0x01,0x25, /* movs r5, 1 */
886 0x00,0x26, /* movs r6, #0 */
887 /* mainloop: */
888 0x19,0x60, /* str r1, [r3, #0] */
889 0x87,0x59, /* ldr r7, [r0, r6] */
890 0x5F,0x60, /* str r7, [r3, #4] */
891 0x9C,0x60, /* str r4, [r3, #8] */
892 /* waitloop: */
893 0x9F,0x68, /* ldr r7, [r3, #8] */
894 0x2F,0x42, /* tst r7, r5 */
895 0xFC,0xD1, /* bne waitloop */
896 0x04,0x31, /* adds r1, r1, #4 */
897 0x04,0x36, /* adds r6, r6, #4 */
898 0x96,0x42, /* cmp r6, r2 */
899 0xF4,0xD1, /* bne mainloop */
900 0x00,0xBE, /* bkpt #0 */
901 /* pFLASH_CTRL_BASE: */
902 0x00,0xD0,0x0F,0x40, /* .word 0x400FD000 */
903 /* FLASHWRITECMD: */
904 0x01,0x00,0x42,0xA4 /* .word 0xA4420001 */
905 };
906
907 static int stellaris_write_block(struct flash_bank *bank,
908 uint8_t *buffer, uint32_t offset, uint32_t wcount)
909 {
910 struct target *target = bank->target;
911 uint32_t buffer_size = 16384;
912 struct working_area *source;
913 struct working_area *write_algorithm;
914 uint32_t address = bank->base + offset;
915 struct reg_param reg_params[3];
916 struct armv7m_algorithm armv7m_info;
917 int retval = ERROR_OK;
918
919 /* power of two, and multiple of word size */
920 static const unsigned buf_min = 128;
921
922 /* for small buffers it's faster not to download an algorithm */
923 if (wcount * 4 < buf_min)
924 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
925
926 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32 " wcount=%08" PRIx32 "",
927 bank, buffer, offset, wcount);
928
929 /* flash write code */
930 if (target_alloc_working_area(target, sizeof(stellaris_write_code), &write_algorithm) != ERROR_OK)
931 {
932 LOG_DEBUG("no working area for block memory writes");
933 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
934 };
935
936 /* plus a buffer big enough for this data */
937 if (wcount * 4 < buffer_size)
938 buffer_size = wcount * 4;
939
940 /* memory buffer */
941 while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK)
942 {
943 buffer_size /= 2;
944 if (buffer_size <= buf_min)
945 {
946 target_free_working_area(target, write_algorithm);
947 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
948 }
949 LOG_DEBUG("retry target_alloc_working_area(%s, size=%u)",
950 target_name(target), (unsigned) buffer_size);
951 };
952
953 retval = target_write_buffer(target, write_algorithm->address,
954 sizeof(stellaris_write_code),
955 (uint8_t *) stellaris_write_code);
956
957 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
958 armv7m_info.core_mode = ARMV7M_MODE_ANY;
959
960 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
961 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
962 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
963
964 while (wcount > 0)
965 {
966 uint32_t thisrun_count = (wcount > (buffer_size / 4)) ? (buffer_size / 4) : wcount;
967
968 target_write_buffer(target, source->address, thisrun_count * 4, buffer);
969
970 buf_set_u32(reg_params[0].value, 0, 32, source->address);
971 buf_set_u32(reg_params[1].value, 0, 32, address);
972 buf_set_u32(reg_params[2].value, 0, 32, 4*thisrun_count);
973 LOG_DEBUG("Algorithm flash write %u words to 0x%" PRIx32
974 ", %u remaining",
975 (unsigned) thisrun_count, address,
976 (unsigned) (wcount - thisrun_count));
977 retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
978 write_algorithm->address,
979 0,
980 10000, &armv7m_info);
981 if (retval != ERROR_OK)
982 {
983 LOG_ERROR("error %d executing stellaris "
984 "flash write algorithm",
985 retval);
986 retval = ERROR_FLASH_OPERATION_FAILED;
987 break;
988 }
989
990 buffer += thisrun_count * 4;
991 address += thisrun_count * 4;
992 wcount -= thisrun_count;
993 }
994
995 /* REVISIT we could speed up writing multi-section images by
996 * not freeing the initialized write_algorithm this way.
997 */
998
999 target_free_working_area(target, write_algorithm);
1000 target_free_working_area(target, source);
1001
1002 destroy_reg_param(&reg_params[0]);
1003 destroy_reg_param(&reg_params[1]);
1004 destroy_reg_param(&reg_params[2]);
1005
1006 return retval;
1007 }
1008
1009 static int stellaris_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
1010 {
1011 struct stellaris_flash_bank *stellaris_info = bank->driver_priv;
1012 struct target *target = bank->target;
1013 uint32_t address = offset;
1014 uint32_t flash_cris, flash_fmc;
1015 uint32_t words_remaining = (count / 4);
1016 uint32_t bytes_remaining = (count & 0x00000003);
1017 uint32_t bytes_written = 0;
1018 int retval;
1019
1020 if (bank->target->state != TARGET_HALTED)
1021 {
1022 LOG_ERROR("Target not halted");
1023 return ERROR_TARGET_NOT_HALTED;
1024 }
1025
1026 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32 " count=%08" PRIx32 "",
1027 bank, buffer, offset, count);
1028
1029 if (stellaris_info->did1 == 0)
1030 return ERROR_FLASH_BANK_NOT_PROBED;
1031
1032 if (offset & 0x3)
1033 {
1034 LOG_WARNING("offset size must be word aligned");
1035 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
1036 }
1037
1038 if (offset + count > bank->size)
1039 return ERROR_FLASH_DST_OUT_OF_BANK;
1040
1041 /* Refresh flash controller timing */
1042 stellaris_read_clock_info(bank);
1043 stellaris_set_flash_timing(bank);
1044
1045 /* Clear and disable flash programming interrupts */
1046 target_write_u32(target, FLASH_CIM, 0);
1047 target_write_u32(target, FLASH_MISC, PMISC | AMISC);
1048
1049 /* REVISIT this clobbers state set by any halted firmware ...
1050 * it might want to process those IRQs.
1051 */
1052
1053 /* multiple words to be programmed? */
1054 if (words_remaining > 0)
1055 {
1056 /* try using a block write */
1057 retval = stellaris_write_block(bank, buffer, offset,
1058 words_remaining);
1059 if (retval != ERROR_OK)
1060 {
1061 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
1062 {
1063 LOG_DEBUG("writing flash word-at-a-time");
1064 }
1065 else if (retval == ERROR_FLASH_OPERATION_FAILED)
1066 {
1067 /* if an error occured, we examine the reason, and quit */
1068 target_read_u32(target, FLASH_CRIS, &flash_cris);
1069
1070 LOG_ERROR("flash writing failed with CRIS: 0x%" PRIx32 "", flash_cris);
1071 return ERROR_FLASH_OPERATION_FAILED;
1072 }
1073 }
1074 else
1075 {
1076 buffer += words_remaining * 4;
1077 address += words_remaining * 4;
1078 words_remaining = 0;
1079 }
1080 }
1081
1082 while (words_remaining > 0)
1083 {
1084 if (!(address & 0xff))
1085 LOG_DEBUG("0x%" PRIx32 "", address);
1086
1087 /* Program one word */
1088 target_write_u32(target, FLASH_FMA, address);
1089 target_write_buffer(target, FLASH_FMD, 4, buffer);
1090 target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_WRITE);
1091 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
1092 /* Wait until write complete */
1093 do
1094 {
1095 target_read_u32(target, FLASH_FMC, &flash_fmc);
1096 } while (flash_fmc & FMC_WRITE);
1097
1098 buffer += 4;
1099 address += 4;
1100 words_remaining--;
1101 }
1102
1103 if (bytes_remaining)
1104 {
1105 uint8_t last_word[4] = {0xff, 0xff, 0xff, 0xff};
1106 int i = 0;
1107
1108 while (bytes_remaining > 0)
1109 {
1110 last_word[i++] = *(buffer + bytes_written);
1111 bytes_remaining--;
1112 bytes_written++;
1113 }
1114
1115 if (!(address & 0xff))
1116 LOG_DEBUG("0x%" PRIx32 "", address);
1117
1118 /* Program one word */
1119 target_write_u32(target, FLASH_FMA, address);
1120 target_write_buffer(target, FLASH_FMD, 4, last_word);
1121 target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_WRITE);
1122 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
1123 /* Wait until write complete */
1124 do
1125 {
1126 target_read_u32(target, FLASH_FMC, &flash_fmc);
1127 } while (flash_fmc & FMC_WRITE);
1128 }
1129
1130 /* Check access violations */
1131 target_read_u32(target, FLASH_CRIS, &flash_cris);
1132 if (flash_cris & (AMASK))
1133 {
1134 LOG_DEBUG("flash_cris 0x%" PRIx32 "", flash_cris);
1135 return ERROR_FLASH_OPERATION_FAILED;
1136 }
1137 return ERROR_OK;
1138 }
1139
1140 static int stellaris_probe(struct flash_bank *bank)
1141 {
1142 struct stellaris_flash_bank *stellaris_info = bank->driver_priv;
1143 int retval;
1144
1145 /* If this is a stellaris chip, it has flash; probe() is just
1146 * to figure out how much is present. Only do it once.
1147 */
1148 if (stellaris_info->did1 != 0)
1149 return ERROR_OK;
1150
1151 /* stellaris_read_part_info() already handled error checking and
1152 * reporting. Note that it doesn't write, so we don't care about
1153 * whether the target is halted or not.
1154 */
1155 retval = stellaris_read_part_info(bank);
1156 if (retval != ERROR_OK)
1157 return retval;
1158
1159 if (bank->sectors)
1160 {
1161 free(bank->sectors);
1162 bank->sectors = NULL;
1163 }
1164
1165 /* provide this for the benefit of the NOR flash framework */
1166 bank->size = 1024 * stellaris_info->num_pages;
1167 bank->num_sectors = stellaris_info->num_pages;
1168 bank->sectors = calloc(bank->num_sectors, sizeof(struct flash_sector));
1169 for (int i = 0; i < bank->num_sectors; i++)
1170 {
1171 bank->sectors[i].offset = i * stellaris_info->pagesize;
1172 bank->sectors[i].size = stellaris_info->pagesize;
1173 bank->sectors[i].is_erased = -1;
1174 bank->sectors[i].is_protected = -1;
1175 }
1176
1177 return retval;
1178 }
1179
1180 static int stellaris_mass_erase(struct flash_bank *bank)
1181 {
1182 struct target *target = NULL;
1183 struct stellaris_flash_bank *stellaris_info = NULL;
1184 uint32_t flash_fmc;
1185
1186 stellaris_info = bank->driver_priv;
1187 target = bank->target;
1188
1189 if (target->state != TARGET_HALTED)
1190 {
1191 LOG_ERROR("Target not halted");
1192 return ERROR_TARGET_NOT_HALTED;
1193 }
1194
1195 if (stellaris_info->did1 == 0)
1196 return ERROR_FLASH_BANK_NOT_PROBED;
1197
1198 /* Refresh flash controller timing */
1199 stellaris_read_clock_info(bank);
1200 stellaris_set_flash_timing(bank);
1201
1202 /* Clear and disable flash programming interrupts */
1203 target_write_u32(target, FLASH_CIM, 0);
1204 target_write_u32(target, FLASH_MISC, PMISC | AMISC);
1205
1206 /* REVISIT this clobbers state set by any halted firmware ...
1207 * it might want to process those IRQs.
1208 */
1209
1210 target_write_u32(target, FLASH_FMA, 0);
1211 target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_MERASE);
1212 /* Wait until erase complete */
1213 do
1214 {
1215 target_read_u32(target, FLASH_FMC, &flash_fmc);
1216 }
1217 while (flash_fmc & FMC_MERASE);
1218
1219 /* if device has > 128k, then second erase cycle is needed
1220 * this is only valid for older devices, but will not hurt */
1221 if (stellaris_info->num_pages * stellaris_info->pagesize > 0x20000)
1222 {
1223 target_write_u32(target, FLASH_FMA, 0x20000);
1224 target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_MERASE);
1225 /* Wait until erase complete */
1226 do
1227 {
1228 target_read_u32(target, FLASH_FMC, &flash_fmc);
1229 }
1230 while (flash_fmc & FMC_MERASE);
1231 }
1232
1233 return ERROR_OK;
1234 }
1235
1236 COMMAND_HANDLER(stellaris_handle_mass_erase_command)
1237 {
1238 int i;
1239
1240 if (CMD_ARGC < 1)
1241 {
1242 command_print(CMD_CTX, "stellaris mass_erase <bank>");
1243 return ERROR_OK;
1244 }
1245
1246 struct flash_bank *bank;
1247 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1248 if (ERROR_OK != retval)
1249 return retval;
1250
1251 if (stellaris_mass_erase(bank) == ERROR_OK)
1252 {
1253 /* set all sectors as erased */
1254 for (i = 0; i < bank->num_sectors; i++)
1255 {
1256 bank->sectors[i].is_erased = 1;
1257 }
1258
1259 command_print(CMD_CTX, "stellaris mass erase complete");
1260 }
1261 else
1262 {
1263 command_print(CMD_CTX, "stellaris mass erase failed");
1264 }
1265
1266 return ERROR_OK;
1267 }
1268
1269 /**
1270 * Perform the Stellaris "Recovering a 'Locked' Device procedure.
1271 * This performs a mass erase and then restores all nonvolatile registers
1272 * (including USER_* registers and flash lock bits) to their defaults.
1273 * Accordingly, flash can be reprogrammed, and JTAG can be used.
1274 *
1275 * NOTE that DustDevil parts (at least rev A0 silicon) have errata which
1276 * can affect this operation if flash protection has been enabled.
1277 */
1278 COMMAND_HANDLER(stellaris_handle_recover_command)
1279 {
1280 struct flash_bank *bank;
1281 int retval;
1282
1283 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1284 if (retval != ERROR_OK)
1285 return retval;
1286
1287 /* REVISIT ... it may be worth sanity checking that the AP is
1288 * inactive before we start. ARM documents that switching a DP's
1289 * mode while it's active can cause fault modes that need a power
1290 * cycle to recover.
1291 */
1292
1293 /* assert SRST */
1294 if (!(jtag_get_reset_config() & RESET_HAS_SRST)) {
1295 LOG_ERROR("Can't recover Stellaris flash without SRST");
1296 return ERROR_FAIL;
1297 }
1298 jtag_add_reset(0, 1);
1299
1300 for (int i = 0; i < 5; i++) {
1301 retval = dap_to_swd(bank->target);
1302 if (retval != ERROR_OK)
1303 goto done;
1304
1305 retval = dap_to_jtag(bank->target);
1306 if (retval != ERROR_OK)
1307 goto done;
1308 }
1309
1310 /* de-assert SRST */
1311 jtag_add_reset(0, 0);
1312 retval = jtag_execute_queue();
1313
1314 /* wait 400+ msec ... OK, "1+ second" is simpler */
1315 usleep(1000);
1316
1317 /* USER INTERVENTION required for the power cycle
1318 * Restarting OpenOCD is likely needed because of mode switching.
1319 */
1320 LOG_INFO("USER ACTION: "
1321 "power cycle Stellaris chip, then restart OpenOCD.");
1322
1323 done:
1324 return retval;
1325 }
1326
1327 static const struct command_registration stellaris_exec_command_handlers[] = {
1328 {
1329 .name = "mass_erase",
1330 .handler = stellaris_handle_mass_erase_command,
1331 .mode = COMMAND_EXEC,
1332 .usage = "bank_id",
1333 .help = "erase entire device",
1334 },
1335 {
1336 .name = "recover",
1337 .handler = stellaris_handle_recover_command,
1338 .mode = COMMAND_EXEC,
1339 .usage = "bank_id",
1340 .help = "recover (and erase) locked device",
1341 },
1342 COMMAND_REGISTRATION_DONE
1343 };
1344 static const struct command_registration stellaris_command_handlers[] = {
1345 {
1346 .name = "stellaris",
1347 .mode = COMMAND_EXEC,
1348 .help = "Stellaris flash command group",
1349 .chain = stellaris_exec_command_handlers,
1350 },
1351 COMMAND_REGISTRATION_DONE
1352 };
1353
1354 struct flash_driver stellaris_flash = {
1355 .name = "stellaris",
1356 .commands = stellaris_command_handlers,
1357 .flash_bank_command = stellaris_flash_bank_command,
1358 .erase = stellaris_erase,
1359 .protect = stellaris_protect,
1360 .write = stellaris_write,
1361 .read = default_flash_read,
1362 .probe = stellaris_probe,
1363 .auto_probe = stellaris_probe,
1364 .erase_check = default_flash_mem_blank_check,
1365 .protect_check = stellaris_protect_check,
1366 .info = get_stellaris_info,
1367 };

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)