OpenOCD
stellaris.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2006 by Magnus Lundin *
5  * lundin@mlu.mine.nu *
6  * *
7  * Copyright (C) 2008 by Spencer Oliver *
8  * spen@spen-soft.co.uk *
9  ***************************************************************************/
10 
11 /***************************************************************************
12 * STELLARIS flash is tested on LM3S811, LM3S6965, LM3s3748, more.
13 ***************************************************************************/
14 
15 #ifdef HAVE_CONFIG_H
16 #include "config.h"
17 #endif
18 
19 #include "jtag/interface.h"
20 #include "imp.h"
21 #include <target/algorithm.h>
22 #include <target/arm_adi_v5.h>
23 #include <target/armv7m.h>
24 
25 #define DID0_VER(did0) ((did0 >> 28)&0x07)
26 
27 /* STELLARIS control registers */
28 #define SCB_BASE 0x400FE000
29 #define DID0 0x000
30 #define DID1 0x004
31 #define DC0 0x008
32 #define DC1 0x010
33 #define DC2 0x014
34 #define DC3 0x018
35 #define DC4 0x01C
36 
37 #define RIS 0x050
38 #define RCC 0x060
39 #define PLLCFG 0x064
40 #define RCC2 0x070
41 #define NVMSTAT 0x1a0
42 
43 /* "legacy" flash memory protection registers (64KB max) */
44 #define FMPRE 0x130
45 #define FMPPE 0x134
46 
47 /* new flash memory protection registers (for more than 64KB) */
48 #define FMPRE0 0x200 /* PRE1 = PRE0 + 4, etc */
49 #define FMPPE0 0x400 /* PPE1 = PPE0 + 4, etc */
50 
51 #define USECRL 0x140
52 
53 #define FLASH_CONTROL_BASE 0x400FD000
54 #define FLASH_FMA (FLASH_CONTROL_BASE | 0x000)
55 #define FLASH_FMD (FLASH_CONTROL_BASE | 0x004)
56 #define FLASH_FMC (FLASH_CONTROL_BASE | 0x008)
57 #define FLASH_CRIS (FLASH_CONTROL_BASE | 0x00C)
58 #define FLASH_CIM (FLASH_CONTROL_BASE | 0x010)
59 #define FLASH_MISC (FLASH_CONTROL_BASE | 0x014)
60 #define FLASH_FSIZE (FLASH_CONTROL_BASE | 0xFC0)
61 #define FLASH_SSIZE (FLASH_CONTROL_BASE | 0xFC4)
62 
63 #define AMISC 1
64 #define PMISC 2
65 
66 #define AMASK 1
67 #define PMASK 2
68 
69 /* Flash Controller Command bits */
70 #define FMC_WRKEY (0xA442 << 16)
71 #define FMC_COMT (1 << 3)
72 #define FMC_MERASE (1 << 2)
73 #define FMC_ERASE (1 << 1)
74 #define FMC_WRITE (1 << 0)
75 
76 /* STELLARIS constants */
77 
78 /* values to write in FMA to commit write-"once" values */
79 #define FLASH_FMA_PRE(x) (2 * (x)) /* for FMPPREx */
80 #define FLASH_FMA_PPE(x) (2 * (x) + 1) /* for FMPPPEx */
81 
82 static void stellaris_read_clock_info(struct flash_bank *bank);
83 static int stellaris_mass_erase(struct flash_bank *bank);
84 
86  /* chip id register */
87  uint32_t did0;
88  uint32_t did1;
89  uint32_t dc0;
90  uint32_t dc1;
91  uint32_t fsize;
92  uint32_t ssize;
93 
94  const char *target_name;
95  uint8_t target_class;
96 
97  uint32_t sramsiz;
98  /* flash geometry */
99  uint32_t num_pages;
100  uint32_t pagesize;
101 
102  /* main clock status */
103  uint32_t rcc;
104  uint32_t rcc2;
105  uint8_t mck_valid;
106  uint8_t xtal_mask;
107  uint32_t iosc_freq;
108  uint32_t mck_freq;
109  const char *iosc_desc;
110  const char *mck_desc;
111 };
112 
113 /* Autogenerated by contrib/gen-stellaris-part-header.pl */
114 /* From Stellaris Firmware Development Package revision 9453 */
115 static const struct {
116  uint8_t class;
117  uint8_t partno;
118  const char *partname;
119 } stellaris_parts[] = {
120  {0x00, 0x01, "LM3S101"},
121  {0x00, 0x02, "LM3S102"},
122  {0x01, 0xBF, "LM3S1110"},
123  {0x01, 0xC3, "LM3S1133"},
124  {0x01, 0xC5, "LM3S1138"},
125  {0x01, 0xC1, "LM3S1150"},
126  {0x01, 0xC4, "LM3S1162"},
127  {0x01, 0xC2, "LM3S1165"},
128  {0x01, 0xEC, "LM3S1166"},
129  {0x01, 0xC6, "LM3S1332"},
130  {0x01, 0xBC, "LM3S1435"},
131  {0x01, 0xBA, "LM3S1439"},
132  {0x01, 0xBB, "LM3S1512"},
133  {0x01, 0xC7, "LM3S1538"},
134  {0x01, 0xDB, "LM3S1601"},
135  {0x03, 0x06, "LM3S1607"},
136  {0x01, 0xDA, "LM3S1608"},
137  {0x01, 0xC0, "LM3S1620"},
138  {0x04, 0xCD, "LM3S1621"},
139  {0x03, 0x03, "LM3S1625"},
140  {0x03, 0x04, "LM3S1626"},
141  {0x03, 0x05, "LM3S1627"},
142  {0x01, 0xB3, "LM3S1635"},
143  {0x01, 0xEB, "LM3S1636"},
144  {0x01, 0xBD, "LM3S1637"},
145  {0x04, 0xB1, "LM3S1651"},
146  {0x01, 0xB9, "LM3S1751"},
147  {0x03, 0x10, "LM3S1776"},
148  {0x04, 0x16, "LM3S1811"},
149  {0x04, 0x3D, "LM3S1816"},
150  {0x01, 0xB4, "LM3S1850"},
151  {0x01, 0xDD, "LM3S1911"},
152  {0x01, 0xDC, "LM3S1918"},
153  {0x01, 0xB7, "LM3S1937"},
154  {0x01, 0xBE, "LM3S1958"},
155  {0x01, 0xB5, "LM3S1960"},
156  {0x01, 0xB8, "LM3S1968"},
157  {0x01, 0xEA, "LM3S1969"},
158  {0x04, 0xCE, "LM3S1B21"},
159  {0x06, 0xCA, "LM3S1C21"},
160  {0x06, 0xCB, "LM3S1C26"},
161  {0x06, 0x98, "LM3S1C58"},
162  {0x06, 0xB0, "LM3S1D21"},
163  {0x06, 0xCC, "LM3S1D26"},
164  {0x06, 0x1D, "LM3S1F11"},
165  {0x06, 0x1B, "LM3S1F16"},
166  {0x06, 0xAF, "LM3S1G21"},
167  {0x06, 0x95, "LM3S1G58"},
168  {0x06, 0x1E, "LM3S1H11"},
169  {0x06, 0x1C, "LM3S1H16"},
170  {0x04, 0x0F, "LM3S1J11"},
171  {0x04, 0x3C, "LM3S1J16"},
172  {0x04, 0x0E, "LM3S1N11"},
173  {0x04, 0x3B, "LM3S1N16"},
174  {0x04, 0xB2, "LM3S1P51"},
175  {0x04, 0x9E, "LM3S1R21"},
176  {0x04, 0xC9, "LM3S1R26"},
177  {0x04, 0x30, "LM3S1W16"},
178  {0x04, 0x2F, "LM3S1Z16"},
179  {0x01, 0x51, "LM3S2110"},
180  {0x01, 0x84, "LM3S2139"},
181  {0x03, 0x39, "LM3S2276"},
182  {0x01, 0xA2, "LM3S2410"},
183  {0x01, 0x59, "LM3S2412"},
184  {0x01, 0x56, "LM3S2432"},
185  {0x01, 0x5A, "LM3S2533"},
186  {0x01, 0xE1, "LM3S2601"},
187  {0x01, 0xE0, "LM3S2608"},
188  {0x03, 0x33, "LM3S2616"},
189  {0x01, 0x57, "LM3S2620"},
190  {0x01, 0x85, "LM3S2637"},
191  {0x01, 0x53, "LM3S2651"},
192  {0x03, 0x80, "LM3S2671"},
193  {0x03, 0x50, "LM3S2678"},
194  {0x01, 0xA4, "LM3S2730"},
195  {0x01, 0x52, "LM3S2739"},
196  {0x03, 0x3A, "LM3S2776"},
197  {0x04, 0x6D, "LM3S2793"},
198  {0x01, 0xE3, "LM3S2911"},
199  {0x01, 0xE2, "LM3S2918"},
200  {0x01, 0xED, "LM3S2919"},
201  {0x01, 0x54, "LM3S2939"},
202  {0x01, 0x8F, "LM3S2948"},
203  {0x01, 0x58, "LM3S2950"},
204  {0x01, 0x55, "LM3S2965"},
205  {0x04, 0x6C, "LM3S2B93"},
206  {0x06, 0x94, "LM3S2D93"},
207  {0x06, 0x93, "LM3S2U93"},
208  {0x00, 0x19, "LM3S300"},
209  {0x00, 0x11, "LM3S301"},
210  {0x00, 0x1A, "LM3S308"},
211  {0x00, 0x12, "LM3S310"},
212  {0x00, 0x13, "LM3S315"},
213  {0x00, 0x14, "LM3S316"},
214  {0x00, 0x17, "LM3S317"},
215  {0x00, 0x15, "LM3S328"},
216  {0x03, 0x08, "LM3S3634"},
217  {0x03, 0x43, "LM3S3651"},
218  {0x04, 0xC8, "LM3S3654"},
219  {0x03, 0x44, "LM3S3739"},
220  {0x03, 0x49, "LM3S3748"},
221  {0x03, 0x45, "LM3S3749"},
222  {0x04, 0x42, "LM3S3826"},
223  {0x04, 0x41, "LM3S3J26"},
224  {0x04, 0x40, "LM3S3N26"},
225  {0x04, 0x3F, "LM3S3W26"},
226  {0x04, 0x3E, "LM3S3Z26"},
227  {0x03, 0x81, "LM3S5632"},
228  {0x04, 0x0C, "LM3S5651"},
229  {0x03, 0x8A, "LM3S5652"},
230  {0x04, 0x4D, "LM3S5656"},
231  {0x03, 0x91, "LM3S5662"},
232  {0x03, 0x96, "LM3S5732"},
233  {0x03, 0x97, "LM3S5737"},
234  {0x03, 0xA0, "LM3S5739"},
235  {0x03, 0x99, "LM3S5747"},
236  {0x03, 0xA7, "LM3S5749"},
237  {0x03, 0x9A, "LM3S5752"},
238  {0x03, 0x9C, "LM3S5762"},
239  {0x04, 0x69, "LM3S5791"},
240  {0x04, 0x0B, "LM3S5951"},
241  {0x04, 0x4E, "LM3S5956"},
242  {0x04, 0x68, "LM3S5B91"},
243  {0x06, 0x2E, "LM3S5C31"},
244  {0x06, 0x2C, "LM3S5C36"},
245  {0x06, 0x5E, "LM3S5C51"},
246  {0x06, 0x5B, "LM3S5C56"},
247  {0x06, 0x5F, "LM3S5D51"},
248  {0x06, 0x5C, "LM3S5D56"},
249  {0x06, 0x87, "LM3S5D91"},
250  {0x06, 0x2D, "LM3S5G31"},
251  {0x06, 0x1F, "LM3S5G36"},
252  {0x06, 0x5D, "LM3S5G51"},
253  {0x06, 0x4F, "LM3S5G56"},
254  {0x04, 0x09, "LM3S5K31"},
255  {0x04, 0x4A, "LM3S5K36"},
256  {0x04, 0x0A, "LM3S5P31"},
257  {0x04, 0x48, "LM3S5P36"},
258  {0x04, 0xB6, "LM3S5P3B"},
259  {0x04, 0x0D, "LM3S5P51"},
260  {0x04, 0x4C, "LM3S5P56"},
261  {0x04, 0x07, "LM3S5R31"},
262  {0x04, 0x4B, "LM3S5R36"},
263  {0x04, 0x47, "LM3S5T36"},
264  {0x06, 0x7F, "LM3S5U91"},
265  {0x04, 0x46, "LM3S5Y36"},
266  {0x00, 0x2A, "LM3S600"},
267  {0x00, 0x21, "LM3S601"},
268  {0x00, 0x2B, "LM3S608"},
269  {0x00, 0x22, "LM3S610"},
270  {0x01, 0xA1, "LM3S6100"},
271  {0x00, 0x23, "LM3S611"},
272  {0x01, 0x74, "LM3S6110"},
273  {0x00, 0x24, "LM3S612"},
274  {0x00, 0x25, "LM3S613"},
275  {0x00, 0x26, "LM3S615"},
276  {0x00, 0x28, "LM3S617"},
277  {0x00, 0x29, "LM3S618"},
278  {0x00, 0x27, "LM3S628"},
279  {0x01, 0xA5, "LM3S6420"},
280  {0x01, 0x82, "LM3S6422"},
281  {0x01, 0x75, "LM3S6432"},
282  {0x01, 0x76, "LM3S6537"},
283  {0x01, 0x71, "LM3S6610"},
284  {0x01, 0xE7, "LM3S6611"},
285  {0x01, 0xE6, "LM3S6618"},
286  {0x01, 0x83, "LM3S6633"},
287  {0x01, 0x8B, "LM3S6637"},
288  {0x01, 0xA3, "LM3S6730"},
289  {0x01, 0x77, "LM3S6753"},
290  {0x01, 0xE9, "LM3S6911"},
291  {0x01, 0xE8, "LM3S6918"},
292  {0x01, 0x89, "LM3S6938"},
293  {0x01, 0x72, "LM3S6950"},
294  {0x01, 0x78, "LM3S6952"},
295  {0x01, 0x73, "LM3S6965"},
296  {0x06, 0xAA, "LM3S6C11"},
297  {0x06, 0xAC, "LM3S6C65"},
298  {0x06, 0x9F, "LM3S6G11"},
299  {0x06, 0xAB, "LM3S6G65"},
300  {0x00, 0x38, "LM3S800"},
301  {0x00, 0x31, "LM3S801"},
302  {0x00, 0x39, "LM3S808"},
303  {0x00, 0x32, "LM3S811"},
304  {0x00, 0x33, "LM3S812"},
305  {0x00, 0x34, "LM3S815"},
306  {0x00, 0x36, "LM3S817"},
307  {0x00, 0x37, "LM3S818"},
308  {0x00, 0x35, "LM3S828"},
309  {0x01, 0x64, "LM3S8530"},
310  {0x01, 0x8E, "LM3S8538"},
311  {0x01, 0x61, "LM3S8630"},
312  {0x01, 0x63, "LM3S8730"},
313  {0x01, 0x8D, "LM3S8733"},
314  {0x01, 0x86, "LM3S8738"},
315  {0x01, 0x65, "LM3S8930"},
316  {0x01, 0x8C, "LM3S8933"},
317  {0x01, 0x88, "LM3S8938"},
318  {0x01, 0xA6, "LM3S8962"},
319  {0x01, 0x62, "LM3S8970"},
320  {0x01, 0xD7, "LM3S8971"},
321  {0x06, 0xAE, "LM3S8C62"},
322  {0x06, 0xAD, "LM3S8G62"},
323  {0x04, 0xCF, "LM3S9781"},
324  {0x04, 0x67, "LM3S9790"},
325  {0x04, 0x6B, "LM3S9792"},
326  {0x04, 0x2D, "LM3S9971"},
327  {0x04, 0x20, "LM3S9997"},
328  {0x04, 0xD0, "LM3S9B81"},
329  {0x04, 0x66, "LM3S9B90"},
330  {0x04, 0x6A, "LM3S9B92"},
331  {0x04, 0x6E, "LM3S9B95"},
332  {0x04, 0x6F, "LM3S9B96"},
333  {0x04, 0x1D, "LM3S9BN2"},
334  {0x04, 0x1E, "LM3S9BN5"},
335  {0x04, 0x1F, "LM3S9BN6"},
336  {0x06, 0x70, "LM3S9C97"},
337  {0x06, 0xA9, "LM3S9D81"},
338  {0x06, 0x7E, "LM3S9D90"},
339  {0x06, 0x92, "LM3S9D92"},
340  {0x06, 0x9D, "LM3S9D96"},
341  {0x06, 0x7B, "LM3S9DN5"},
342  {0x06, 0x7C, "LM3S9DN6"},
343  {0x06, 0x60, "LM3S9G97"},
344  {0x06, 0x79, "LM3S9GN5"},
345  {0x04, 0x1B, "LM3S9L71"},
346  {0x04, 0x18, "LM3S9L97"},
347  {0x06, 0xA8, "LM3S9U81"},
348  {0x06, 0x7D, "LM3S9U90"},
349  {0x06, 0x90, "LM3S9U92"},
350  {0x06, 0x9B, "LM3S9U96"},
351  {0x05, 0x01, "LM4F120B2QR/TM4C1233C3PM"},
352  {0x05, 0x02, "LM4F120C4QR/TM4C1233D5PM"},
353  {0x05, 0x03, "LM4F120E5QR/TM4C1233E6PM"},
354  {0x05, 0x04, "LM4F120H5QR/TM4C1233H6PM"},
355  {0x05, 0x08, "LM4F121B2QR/TM4C1232C3PM"},
356  {0x05, 0x09, "LM4F121C4QR/TM4C1232D5PM"},
357  {0x05, 0x0A, "LM4F121E5QR/TM4C1232E6PM"},
358  {0x05, 0x0B, "LM4F121H5QR/TM4C1232H6PM"},
359  {0x05, 0x10, "LM4F110E5QR/TM4C1231E6PM"},
360  {0x05, 0x11, "LM4F110H5QR/TM4C1231H6PM"},
361  {0x05, 0x18, "LM4F110B2QR/TM4C1231C3PM"},
362  {0x05, 0x19, "LM4F110C4QR/TM4C1231D5PM"},
363  {0x05, 0x20, "LM4F111E5QR/TM4C1230E6PM"},
364  {0x05, 0x21, "LM4F111H5QR/TM4C1230H6PM"},
365  {0x05, 0x22, "LM4F111B2QR/TM4C1230C3PM"},
366  {0x05, 0x23, "LM4F111C4QR/TM4C1230D5PM"},
367  {0x05, 0x30, "LM4F112E5QC/TM4C1231E6PZ"},
368  {0x05, 0x31, "LM4F112H5QC/TM4C1231H6PZ"},
369  {0x05, 0x35, "LM4F112H5QD/TM4C1231H6PGE"},
370  {0x05, 0x36, "LM4F112C4QC/TM4C1231D5PZ"},
371  {0x05, 0x40, "LM4F130E5QR/TM4C1237E6PM"},
372  {0x05, 0x41, "LM4F130H5QR/TM4C1237H6PM"},
373  {0x05, 0x48, "LM4F130C4QR/TM4C1237D5PM"},
374  {0x05, 0x50, "LM4F131E5QR/TM4C1236E6PM"},
375  {0x05, 0x51, "LM4F131H5QR/TM4C1236H6PM"},
376  {0x05, 0x52, "LM4F131C4QR/TM4C1236D5PM"},
377  {0x05, 0x60, "LM4F132E5QC/TM4C1237E6PZ"},
378  {0x05, 0x61, "LM4F132H5QC/TM4C1237H6PZ"},
379  {0x05, 0x65, "LM4F132H5QD/TM4C1237H6PGE"},
380  {0x05, 0x66, "LM4F132C4QC/TM4C1237D5PZ"},
381  {0x05, 0x70, "LM4F210E5QR/TM4C123BE6PM"},
382  {0x05, 0x73, "LM4F210H5QR/TM4C123BH6PM"},
383  {0x05, 0x80, "LM4F211E5QR/TM4C123AE6PM"},
384  {0x05, 0x83, "LM4F211H5QR/TM4C123AH6PM"},
385  {0x05, 0xA0, "LM4F230E5QR/TM4C123GE6PM"},
386  {0x05, 0xA1, "LM4F230H5QR/TM4C123GH6PM"},
387  {0x05, 0xB0, "LM4F231E5QR/TM4C123FE6PM"},
388  {0x05, 0xB1, "LM4F231H5QR/TM4C123FH6PM"},
389  {0x05, 0xC0, "LM4F232E5QC/TM4C123GE6PZ"},
390  {0x05, 0xC1, "LM4F232H5QC/TM4C123GH6PZ"},
391  {0x05, 0xC3, "LM4F212E5QC/TM4C123BE6PZ"},
392  {0x05, 0xC4, "LM4F212H5QC/TM4C123BH6PZ"},
393  {0x05, 0xC5, "LM4F232H5QD/TM4C123GH6PGE"},
394  {0x05, 0xC6, "LM4F212H5QD/TM4C123BH6PGE"},
395  {0x05, 0xD0, "LM4F122C4QC/TM4C1233D5PZ"},
396  {0x05, 0xD1, "LM4F122E5QC/TM4C1233E6PZ"},
397  {0x05, 0xD2, "LM4F122H5QC/TM4C1233H6PZ"},
398  {0x05, 0xD6, "LM4F122H5QD/TM4C1233H6PGE"},
399  {0x05, 0xE1, "LM4FSXLH5BB"},
400  {0x05, 0xE3, "LM4F232H5BB/TM4C123GH6ZRB"},
401  {0x05, 0xE4, "LM4FS99H5BB"},
402  {0x05, 0xE5, "LM4FS1AH5BB"},
403  {0x05, 0xE9, "LM4F212H5BB/TM4C123BH6ZRB"},
404  {0x05, 0xEA, "LM4FS1GH5BB"},
405  {0x05, 0xF0, "TM4C123GH6ZXR"},
406  {0x0A, 0x19, "TM4C1290NCPDT"},
407  {0x0A, 0x1B, "TM4C1290NCZAD"},
408  {0x0A, 0x1C, "TM4C1292NCPDT"},
409  {0x0A, 0x1E, "TM4C1292NCZAD"},
410  {0x0A, 0x1F, "TM4C1294NCPDT"},
411  {0x0A, 0x21, "TM4C1294NCZAD"},
412  {0x0A, 0x22, "TM4C1297NCZAD"},
413  {0x0A, 0x23, "TM4C1299NCZAD"},
414  {0x0A, 0x24, "TM4C129CNCPDT"},
415  {0x0A, 0x26, "TM4C129CNCZAD"},
416  {0x0A, 0x27, "TM4C129DNCPDT"},
417  {0x0A, 0x29, "TM4C129DNCZAD"},
418  {0x0A, 0x2D, "TM4C129ENCPDT"},
419  {0x0A, 0x2F, "TM4C129ENCZAD"},
420  {0x0A, 0x30, "TM4C129LNCZAD"},
421  {0x0A, 0x32, "TM4C129XNCZAD"},
422  {0x0A, 0x34, "TM4C1294KCPDT"},
423  {0x0A, 0x35, "TM4C129EKCPDT"},
424  {0x0A, 0x36, "TM4C1299KCZAD"},
425  {0x0A, 0x37, "TM4C129XKCZAD"},
426  {0xFF, 0x00, "Unknown Part"}
427 };
428 
429 static const char * const stellaris_classname[] = {
430  "Sandstorm",
431  "Fury",
432  "Unknown",
433  "DustDevil",
434  "Tempest",
435  "Blizzard/TM4C123x",
436  "Firestorm",
437  "",
438  "",
439  "",
440  "Snowflake",
441 };
442 
443 /***************************************************************************
444 * openocd command interface *
445 ***************************************************************************/
446 
447 /* flash_bank stellaris <base> <size> 0 0 <target#>
448  */
449 FLASH_BANK_COMMAND_HANDLER(stellaris_flash_bank_command)
450 {
451  struct stellaris_flash_bank *stellaris_info;
452 
453  if (CMD_ARGC < 6)
455 
456  stellaris_info = calloc(sizeof(struct stellaris_flash_bank), 1);
457  bank->base = 0x0;
458  bank->driver_priv = stellaris_info;
459 
460  stellaris_info->target_name = "Unknown target";
461 
462  /* part wasn't probed for info yet */
463  stellaris_info->did1 = 0;
464 
465  /* TODO Specify the main crystal speed in kHz using an optional
466  * argument; ditto, the speed of an external oscillator used
467  * instead of a crystal. Avoid programming flash using IOSC.
468  */
469  return ERROR_OK;
470 }
471 
473 {
474  struct stellaris_flash_bank *stellaris_info = bank->driver_priv;
475 
476  if (stellaris_info->did1 == 0)
478 
479  /* Read main and master clock frequency register */
481 
483  "\nTI/LMI Stellaris information: Chip is "
484  "class %i (%s) %s rev %c%i\n",
485  stellaris_info->target_class,
486  stellaris_classname[stellaris_info->target_class],
487  stellaris_info->target_name,
488  (int)('A' + ((stellaris_info->did0 >> 8) & 0xFF)),
489  (int)((stellaris_info->did0) & 0xFF));
490 
492  "did1: 0x%8.8" PRIx32 ", arch: 0x%4.4" PRIx32
493  ", eproc: %s, ramsize: %" PRIu32 "k, flashsize: %" PRIu32 "k\n",
494  stellaris_info->did1,
495  stellaris_info->did1,
496  "ARMv7M",
497  stellaris_info->sramsiz,
498  (uint32_t)(stellaris_info->num_pages * stellaris_info->pagesize / 1024));
499 
501  "master clock: %ikHz%s, "
502  "rcc is 0x%" PRIx32 ", rcc2 is 0x%" PRIx32 ", "
503  "pagesize: %" PRIu32 ", pages: %" PRIu32,
504  (int)(stellaris_info->mck_freq / 1000),
505  stellaris_info->mck_desc,
506  stellaris_info->rcc,
507  stellaris_info->rcc2,
508  stellaris_info->pagesize,
509  stellaris_info->num_pages);
510 
511  return ERROR_OK;
512 }
513 
514 /***************************************************************************
515 * chip identification and status *
516 ***************************************************************************/
517 
518 /* Set the flash timing register to match current clocking */
520 {
521  struct stellaris_flash_bank *stellaris_info = bank->driver_priv;
522  struct target *target = bank->target;
523  uint32_t usecrl = (stellaris_info->mck_freq/1000000ul-1);
524 
525  /* only valid for Sandstorm and Fury class devices */
526  if (stellaris_info->target_class > 1)
527  return;
528 
529  LOG_DEBUG("usecrl = %i", (int)(usecrl));
531 }
532 
533 static const unsigned rcc_xtal[32] = {
534  [0x00] = 1000000, /* no pll */
535  [0x01] = 1843200, /* no pll */
536  [0x02] = 2000000, /* no pll */
537  [0x03] = 2457600, /* no pll */
538 
539  [0x04] = 3579545,
540  [0x05] = 3686400,
541  [0x06] = 4000000, /* usb */
542  [0x07] = 4096000,
543 
544  [0x08] = 4915200,
545  [0x09] = 5000000, /* usb */
546  [0x0a] = 5120000,
547  [0x0b] = 6000000, /* (reset) usb */
548 
549  [0x0c] = 6144000,
550  [0x0d] = 7372800,
551  [0x0e] = 8000000, /* usb */
552  [0x0f] = 8192000,
553 
554  /* parts before DustDevil use just 4 bits for xtal spec */
555 
556  [0x10] = 10000000, /* usb */
557  [0x11] = 12000000, /* usb */
558  [0x12] = 12288000,
559  [0x13] = 13560000,
560 
561  [0x14] = 14318180,
562  [0x15] = 16000000, /* usb */
563  [0x16] = 16384000,
564 };
565 
568 {
569  struct stellaris_flash_bank *stellaris_info = bank->driver_priv;
570  struct target *target = bank->target;
571  uint32_t rcc, rcc2, pllcfg, sysdiv, usesysdiv, bypass, oscsrc;
572  unsigned xtal;
573  unsigned long mainfreq;
574 
576  LOG_DEBUG("Stellaris RCC %" PRIx32 "", rcc);
577 
578  target_read_u32(target, SCB_BASE | RCC2, &rcc2);
579  LOG_DEBUG("Stellaris RCC2 %" PRIx32 "", rcc);
580 
581  target_read_u32(target, SCB_BASE | PLLCFG, &pllcfg);
582  LOG_DEBUG("Stellaris PLLCFG %" PRIx32 "", pllcfg);
583 
584  stellaris_info->rcc = rcc;
585  stellaris_info->rcc2 = rcc2;
586 
587  sysdiv = (rcc >> 23) & 0xF;
588  usesysdiv = (rcc >> 22) & 0x1;
589  bypass = (rcc >> 11) & 0x1;
590  oscsrc = (rcc >> 4) & 0x3;
591  xtal = (rcc >> 6) & stellaris_info->xtal_mask;
592 
593  /* NOTE: post-Sandstorm parts have RCC2 which may override
594  * parts of RCC ... with more sysdiv options, option for
595  * 32768 Hz mainfreq, PLL controls. On Sandstorm it reads
596  * as zero, so the "use RCC2" flag is always clear.
597  */
598  if (rcc2 & (1 << 31)) {
599  sysdiv = (rcc2 >> 23) & 0x3F;
600  bypass = (rcc2 >> 11) & 0x1;
601  oscsrc = (rcc2 >> 4) & 0x7;
602 
603  /* FIXME Tempest parts have an additional lsb for
604  * fractional sysdiv (200 MHz / 2.5 == 80 MHz)
605  */
606  }
607 
608  stellaris_info->mck_desc = "";
609 
610  switch (oscsrc) {
611  case 0: /* MOSC */
612  mainfreq = rcc_xtal[xtal];
613  break;
614  case 1: /* IOSC */
615  mainfreq = stellaris_info->iosc_freq;
616  stellaris_info->mck_desc = stellaris_info->iosc_desc;
617  break;
618  case 2: /* IOSC/4 */
619  mainfreq = stellaris_info->iosc_freq / 4;
620  stellaris_info->mck_desc = stellaris_info->iosc_desc;
621  break;
622  case 3: /* lowspeed */
623  /* Sandstorm doesn't have this 30K +/- 30% osc */
624  mainfreq = 30000;
625  stellaris_info->mck_desc = " (±30%)";
626  break;
627  case 8: /* hibernation osc */
628  /* not all parts support hibernation */
629  mainfreq = 32768;
630  break;
631 
632  default: /* NOTREACHED */
633  mainfreq = 0;
634  break;
635  }
636 
637  /* PLL is used if it's not bypassed; its output is 200 MHz
638  * even when it runs at 400 MHz (adds divide-by-two stage).
639  */
640  if (!bypass)
641  mainfreq = 200000000;
642 
643  if (usesysdiv)
644  stellaris_info->mck_freq = mainfreq/(1 + sysdiv);
645  else
646  stellaris_info->mck_freq = mainfreq;
647 }
648 
649 /* Read device id register, main clock frequency register and fill in driver info structure */
651 {
652  struct stellaris_flash_bank *stellaris_info = bank->driver_priv;
653  struct target *target = bank->target;
654  uint32_t did0, did1, ver, fam;
655  int i;
656 
657  /* Read and parse chip identification register */
658  target_read_u32(target, SCB_BASE | DID0, &did0);
659  target_read_u32(target, SCB_BASE | DID1, &did1);
660  target_read_u32(target, SCB_BASE | DC0, &stellaris_info->dc0);
661  target_read_u32(target, SCB_BASE | DC1, &stellaris_info->dc1);
662  LOG_DEBUG("did0 0x%" PRIx32 ", did1 0x%" PRIx32 ", dc0 0x%" PRIx32 ", dc1 0x%" PRIx32 "",
663  did0, did1, stellaris_info->dc0, stellaris_info->dc1);
664 
665  ver = DID0_VER(did0);
666  if ((ver != 0) && (ver != 1)) {
667  LOG_WARNING("Unknown did0 version, cannot identify target");
669  }
670 
671  if (did1 == 0) {
672  LOG_WARNING("Cannot identify target as a Stellaris");
674  }
675 
676  ver = did1 >> 28;
677  fam = (did1 >> 24) & 0xF;
678  if (((ver != 0) && (ver != 1)) || (fam != 0)) {
679  LOG_WARNING("Unknown did1 version/family.");
681  }
682 
683  /* For Sandstorm, Fury, DustDevil: current data sheets say IOSC
684  * is 12 MHz, but some older parts have 15 MHz. A few data sheets
685  * even give _both_ numbers! We'll use current numbers; IOSC is
686  * always approximate.
687  *
688  * For Tempest: IOSC is calibrated, 16 MHz
689  * For Blizzard: IOSC is calibrated, 16 MHz
690  * For Firestorm: IOSC is calibrated, 16 MHz
691  */
692  stellaris_info->iosc_freq = 12000000;
693  stellaris_info->iosc_desc = " (±30%)";
694  stellaris_info->xtal_mask = 0x0f;
695 
696  /* get device class */
697  if (DID0_VER(did0) > 0) {
698  stellaris_info->target_class = (did0 >> 16) & 0xFF;
699  } else {
700  /* Sandstorm class */
701  stellaris_info->target_class = 0;
702  }
703 
704  switch (stellaris_info->target_class) {
705  case 0: /* Sandstorm */
706  /*
707  * Current (2009-August) parts seem to be rev C2 and use 12 MHz.
708  * Parts before rev C0 used 15 MHz; some C0 parts use 15 MHz
709  * (LM3S618), but some other C0 parts are 12 MHz (LM3S811).
710  */
711  if (((did0 >> 8) & 0xff) < 2) {
712  stellaris_info->iosc_freq = 15000000;
713  stellaris_info->iosc_desc = " (±50%)";
714  }
715  break;
716 
717  case 1: /* Fury */
718  break;
719 
720  case 4: /* Tempest */
721  case 5: /* Blizzard */
722  case 6: /* Firestorm */
723  case 0xa: /* Snowflake */
724  stellaris_info->iosc_freq = 16000000; /* +/- 1% */
725  stellaris_info->iosc_desc = " (±1%)";
726  /* FALL THROUGH */
727 
728  case 3: /* DustDevil */
729  stellaris_info->xtal_mask = 0x1f;
730  break;
731 
732  default:
733  LOG_WARNING("Unknown did0 class");
734  }
735 
736  for (i = 0; stellaris_parts[i].partno; i++) {
737  if ((stellaris_parts[i].partno == ((did1 >> 16) & 0xFF)) &&
738  (stellaris_parts[i].class == stellaris_info->target_class))
739  break;
740  }
741 
742  stellaris_info->target_name = stellaris_parts[i].partname;
743 
744  stellaris_info->did0 = did0;
745  stellaris_info->did1 = did1;
746 
747  if (stellaris_info->target_class == 5) { /* Blizzard */
748  target_read_u32(target, FLASH_FSIZE, &stellaris_info->fsize);
749  target_read_u32(target, FLASH_SSIZE, &stellaris_info->ssize);
750 
751  stellaris_info->num_pages = 2 * (1 + (stellaris_info->fsize & 0xFFFF));
752  stellaris_info->sramsiz = (1 + (stellaris_info->ssize & 0xFFFF)) / 4;
753  stellaris_info->pagesize = 1024;
754  } else if (stellaris_info->target_class == 0xa) { /* Snowflake */
755  target_read_u32(target, FLASH_FSIZE, &stellaris_info->fsize);
756  target_read_u32(target, FLASH_SSIZE, &stellaris_info->ssize);
757 
758  stellaris_info->pagesize = (1 << ((stellaris_info->fsize >> 16) & 7)) * 1024;
759  stellaris_info->num_pages = 2048 * (1 + (stellaris_info->fsize & 0xFFFF)) /
760  stellaris_info->pagesize;
761  stellaris_info->sramsiz = (1 + (stellaris_info->ssize & 0xFFFF)) / 4;
762  } else {
763  stellaris_info->num_pages = 2 * (1 + (stellaris_info->dc0 & 0xFFFF));
764  stellaris_info->sramsiz = (1 + ((stellaris_info->dc0 >> 16) & 0xFFFF)) / 4;
765  stellaris_info->pagesize = 1024;
766  }
767 
768  /* REVISIT for at least Tempest parts, read NVMSTAT.FWB too.
769  * That exposes a 32-word Flash Write Buffer ... enabling
770  * writes of more than one word at a time.
771  */
772 
773  return ERROR_OK;
774 }
775 
776 /***************************************************************************
777 * flash operations *
778 ***************************************************************************/
779 
781 {
782  struct stellaris_flash_bank *stellaris = bank->driver_priv;
783  struct target *target = bank->target;
784  uint32_t flash_sizek = stellaris->pagesize / 1024 *
785  stellaris->num_pages;
786  uint32_t fmppe_addr;
787  int status = ERROR_OK;
788 
789  if (stellaris->did1 == 0)
791 
792  for (unsigned int i = 0; i < bank->num_sectors; i++)
793  bank->sectors[i].is_protected = -1;
794 
795  /* Read each Flash Memory Protection Program Enable (FMPPE) register
796  * to report any pages that we can't write. Ignore the Read Enable
797  * register (FMPRE).
798  */
799 
800  if (stellaris->target_class >= 0x0a || flash_sizek > 64)
801  fmppe_addr = SCB_BASE | FMPPE0;
802  else
803  fmppe_addr = SCB_BASE | FMPPE;
804 
805  unsigned int page = 0, lockbitnum, lockbitcnt = flash_sizek / 2;
806  unsigned int bits_per_page = stellaris->pagesize / 2048;
807  /* Every lock bit always corresponds to a 2k region */
808  for (lockbitnum = 0; lockbitnum < lockbitcnt; lockbitnum += 32) {
809  uint32_t fmppe;
810 
811  target_read_u32(target, fmppe_addr, &fmppe);
812  for (unsigned int i = 0; i < 32 && lockbitnum + i < lockbitcnt; i++) {
813  bool protect = !(fmppe & (1 << i));
814  if (bits_per_page) {
815  bank->sectors[page++].is_protected = protect;
816  i += bits_per_page - 1;
817  } else { /* 1024k pages, every lockbit covers 2 pages */
818  bank->sectors[page++].is_protected = protect;
819  bank->sectors[page++].is_protected = protect;
820  }
821  }
822  fmppe_addr += 4;
823  }
824 
825  return status;
826 }
827 
828 static int stellaris_erase(struct flash_bank *bank, unsigned int first,
829  unsigned int last)
830 {
831  uint32_t flash_fmc, flash_cris;
832  struct stellaris_flash_bank *stellaris_info = bank->driver_priv;
833  struct target *target = bank->target;
834 
835  if (bank->target->state != TARGET_HALTED) {
836  LOG_ERROR("Target not halted");
838  }
839 
840  if (stellaris_info->did1 == 0)
842 
843  if ((last < first) || (last >= stellaris_info->num_pages))
845 
846  if ((first == 0) && (last == (stellaris_info->num_pages - 1)))
847  return stellaris_mass_erase(bank);
848 
849  /* Refresh flash controller timing */
852 
853  /* Clear and disable flash programming interrupts */
856 
857  /* REVISIT this clobbers state set by any halted firmware ...
858  * it might want to process those IRQs.
859  */
860 
861  for (unsigned int banknr = first; banknr <= last; banknr++) {
862  /* Address is first word in page */
863  target_write_u32(target, FLASH_FMA, banknr * stellaris_info->pagesize);
864  /* Write erase command */
866  /* Wait until erase complete */
867  do {
868  target_read_u32(target, FLASH_FMC, &flash_fmc);
869  } while (flash_fmc & FMC_ERASE);
870 
871  /* Check access violations */
872  target_read_u32(target, FLASH_CRIS, &flash_cris);
873  if (flash_cris & (AMASK)) {
874  LOG_WARNING("Error erasing flash page %i, flash_cris 0x%" PRIx32 "",
875  banknr, flash_cris);
878  }
879  }
880 
881  return ERROR_OK;
882 }
883 
884 static int stellaris_protect(struct flash_bank *bank, int set,
885  unsigned int first, unsigned int last)
886 {
887  struct stellaris_flash_bank *stellaris = bank->driver_priv;
888  struct target *target = bank->target;
889  uint32_t flash_fmc, flash_cris;
890  unsigned int bits_per_page = stellaris->pagesize / 2048;
891 
892  if (target->state != TARGET_HALTED) {
893  LOG_ERROR("Target not halted");
895  }
896 
897  if (!set) {
898  LOG_ERROR("Hardware doesn't support page-level unprotect. "
899  "Try the 'recover' command.");
901  }
902 
903  if (stellaris->did1 == 0)
905 
906  if (stellaris->target_class == 0x03 &&
907  !((stellaris->did0 >> 8) & 0xFF) &&
908  !((stellaris->did0) & 0xFF)) {
909  LOG_ERROR("DustDevil A0 parts can't be unprotected, see errata; refusing to proceed");
911  }
912 
913  if (!bits_per_page && (first % 2 || !(last % 2))) {
914  LOG_ERROR("Can't protect unaligned pages");
916  }
917 
918  /* Refresh flash controller timing */
921 
922  /* Clear and disable flash programming interrupts */
925 
926  uint32_t flash_sizek = stellaris->pagesize / 1024 *
927  stellaris->num_pages;
928  uint32_t fmppe_addr;
929 
930  if (stellaris->target_class >= 0x0a || flash_sizek > 64)
931  fmppe_addr = SCB_BASE | FMPPE0;
932  else
933  fmppe_addr = SCB_BASE | FMPPE;
934 
935  unsigned int page = 0;
936  unsigned int lockbitnum, lockbitcnt = flash_sizek / 2;
937  /* Every lock bit always corresponds to a 2k region */
938  for (lockbitnum = 0; lockbitnum < lockbitcnt; lockbitnum += 32) {
939  uint32_t fmppe;
940 
941  target_read_u32(target, fmppe_addr, &fmppe);
942  for (unsigned int i = 0;
943  i < 32 && lockbitnum + i < lockbitcnt;
944  i++) {
945  if (page >= first && page <= last)
946  fmppe &= ~(1 << i);
947 
948  if (bits_per_page) {
949  if (!((i + 1) % bits_per_page))
950  page++;
951  } else { /* 1024k pages, every lockbit covers 2 pages */
952  page += 2;
953  }
954  }
955  target_write_u32(target, fmppe_addr, fmppe);
956 
957  /* Commit FMPPE* */
958  target_write_u32(target, FLASH_FMA, 1 + lockbitnum / 16);
959  /* Write commit command */
961 
962  /* Wait until commit complete */
963  do {
964  target_read_u32(target, FLASH_FMC, &flash_fmc);
965  } while (flash_fmc & FMC_COMT);
966 
967  /* Check access violations */
968  target_read_u32(target, FLASH_CRIS, &flash_cris);
969  if (flash_cris & (AMASK)) {
970  LOG_WARNING("Error setting flash page protection, flash_cris 0x%" PRIx32 "", flash_cris);
973  }
974 
975  fmppe_addr += 4;
976  }
977 
978  return ERROR_OK;
979 }
980 
981 /* see contrib/loaders/flash/stellaris.s for src */
982 
983 static const uint8_t stellaris_write_code[] = {
984  /* write: */
985  0xDF, 0xF8, 0x40, 0x40, /* ldr r4, pFLASH_CTRL_BASE */
986  0xDF, 0xF8, 0x40, 0x50, /* ldr r5, FLASHWRITECMD */
987  /* wait_fifo: */
988  0xD0, 0xF8, 0x00, 0x80, /* ldr r8, [r0, #0] */
989  0xB8, 0xF1, 0x00, 0x0F, /* cmp r8, #0 */
990  0x17, 0xD0, /* beq exit */
991  0x47, 0x68, /* ldr r7, [r0, #4] */
992  0x47, 0x45, /* cmp r7, r8 */
993  0xF7, 0xD0, /* beq wait_fifo */
994  /* mainloop: */
995  0x22, 0x60, /* str r2, [r4, #0] */
996  0x02, 0xF1, 0x04, 0x02, /* add r2, r2, #4 */
997  0x57, 0xF8, 0x04, 0x8B, /* ldr r8, [r7], #4 */
998  0xC4, 0xF8, 0x04, 0x80, /* str r8, [r4, #4] */
999  0xA5, 0x60, /* str r5, [r4, #8] */
1000  /* busy: */
1001  0xD4, 0xF8, 0x08, 0x80, /* ldr r8, [r4, #8] */
1002  0x18, 0xF0, 0x01, 0x0F, /* tst r8, #1 */
1003  0xFA, 0xD1, /* bne busy */
1004  0x8F, 0x42, /* cmp r7, r1 */
1005  0x28, 0xBF, /* it cs */
1006  0x00, 0xF1, 0x08, 0x07, /* addcs r7, r0, #8 */
1007  0x47, 0x60, /* str r7, [r0, #4] */
1008  0x01, 0x3B, /* subs r3, r3, #1 */
1009  0x03, 0xB1, /* cbz r3, exit */
1010  0xE2, 0xE7, /* b wait_fifo */
1011  /* exit: */
1012  0x00, 0xBE, /* bkpt #0 */
1013 
1014  /* pFLASH_CTRL_BASE: */
1015  0x00, 0xD0, 0x0F, 0x40, /* .word 0x400FD000 */
1016  /* FLASHWRITECMD: */
1017  0x01, 0x00, 0x42, 0xA4 /* .word 0xA4420001 */
1018 };
1020  const uint8_t *buffer, uint32_t offset, uint32_t wcount)
1021 {
1022  struct target *target = bank->target;
1023  uint32_t buffer_size = 16384;
1024  struct working_area *source;
1025  struct working_area *write_algorithm;
1026  uint32_t address = bank->base + offset;
1027  struct reg_param reg_params[4];
1028  struct armv7m_algorithm armv7m_info;
1029  int retval = ERROR_OK;
1030 
1031  /* power of two, and multiple of word size */
1032  static const unsigned buf_min = 128;
1033 
1034  /* for small buffers it's faster not to download an algorithm */
1035  if (wcount * 4 < buf_min)
1037 
1038  LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32 " wcount=%08" PRIx32 "",
1039  bank, buffer, offset, wcount);
1040 
1041  /* flash write code */
1043  &write_algorithm) != ERROR_OK) {
1044  LOG_DEBUG("no working area for block memory writes");
1046  }
1047 
1048  /* plus a buffer big enough for this data */
1049  if (wcount * 4 < buffer_size)
1050  buffer_size = wcount * 4;
1051 
1052  /* memory buffer */
1053  while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {
1054  buffer_size /= 2;
1055  if (buffer_size <= buf_min) {
1056  target_free_working_area(target, write_algorithm);
1058  }
1059  LOG_DEBUG("retry target_alloc_working_area(%s, size=%u)",
1060  target_name(target), (unsigned) buffer_size);
1061  }
1062 
1063  target_write_buffer(target, write_algorithm->address,
1064  sizeof(stellaris_write_code),
1066 
1067  armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
1068  armv7m_info.core_mode = ARM_MODE_THREAD;
1069 
1070  init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
1071  init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
1072  init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
1073  init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
1074 
1075  buf_set_u32(reg_params[0].value, 0, 32, source->address);
1076  buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size);
1077  buf_set_u32(reg_params[2].value, 0, 32, address);
1078  buf_set_u32(reg_params[3].value, 0, 32, wcount);
1079 
1080  retval = target_run_flash_async_algorithm(target, buffer, wcount, 4,
1081  0, NULL,
1082  4, reg_params,
1083  source->address, source->size,
1084  write_algorithm->address, 0,
1085  &armv7m_info);
1086 
1087  if (retval == ERROR_FLASH_OPERATION_FAILED)
1088  LOG_ERROR("error %d executing stellaris flash write algorithm", retval);
1089 
1090  target_free_working_area(target, write_algorithm);
1092 
1093  destroy_reg_param(&reg_params[0]);
1094  destroy_reg_param(&reg_params[1]);
1095  destroy_reg_param(&reg_params[2]);
1096  destroy_reg_param(&reg_params[3]);
1097 
1098  return retval;
1099 }
1100 
1101 static int stellaris_write(struct flash_bank *bank, const uint8_t *buffer,
1102  uint32_t offset, uint32_t count)
1103 {
1104  struct stellaris_flash_bank *stellaris_info = bank->driver_priv;
1105  struct target *target = bank->target;
1106  uint32_t address = offset;
1107  uint32_t flash_cris, flash_fmc;
1108  uint32_t words_remaining = (count / 4);
1109  uint32_t bytes_remaining = (count & 0x00000003);
1110  uint32_t bytes_written = 0;
1111  int retval;
1112 
1113  if (bank->target->state != TARGET_HALTED) {
1114  LOG_ERROR("Target not halted");
1115  return ERROR_TARGET_NOT_HALTED;
1116  }
1117 
1118  LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32 " count=%08" PRIx32 "",
1119  bank, buffer, offset, count);
1120 
1121  if (stellaris_info->did1 == 0)
1123 
1124  if (offset & 0x3) {
1125  LOG_WARNING("offset size must be word aligned");
1127  }
1128 
1129  if (offset + count > bank->size)
1131 
1132  /* Refresh flash controller timing */
1135 
1136  /* Clear and disable flash programming interrupts */
1139 
1140  /* REVISIT this clobbers state set by any halted firmware ...
1141  * it might want to process those IRQs.
1142  */
1143 
1144  /* multiple words to be programmed? */
1145  if (words_remaining > 0) {
1146  /* try using a block write */
1148  words_remaining);
1149  if (retval != ERROR_OK) {
1150  if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
1151  LOG_DEBUG("writing flash word-at-a-time");
1152  } else if (retval == ERROR_FLASH_OPERATION_FAILED) {
1153  /* if an error occurred, we examine the reason, and quit */
1154  target_read_u32(target, FLASH_CRIS, &flash_cris);
1155 
1156  LOG_ERROR("flash writing failed with CRIS: 0x%" PRIx32 "", flash_cris);
1158  }
1159  } else {
1160  buffer += words_remaining * 4;
1161  address += words_remaining * 4;
1162  words_remaining = 0;
1163  }
1164  }
1165 
1166  while (words_remaining > 0) {
1167  if (!(address & 0xff))
1168  LOG_DEBUG("0x%" PRIx32 "", address);
1169 
1170  /* Program one word */
1171  target_write_u32(target, FLASH_FMA, address);
1174  /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
1175  /* Wait until write complete */
1176  do {
1177  target_read_u32(target, FLASH_FMC, &flash_fmc);
1178  } while (flash_fmc & FMC_WRITE);
1179 
1180  buffer += 4;
1181  address += 4;
1182  words_remaining--;
1183  }
1184 
1185  if (bytes_remaining) {
1186  uint8_t last_word[4] = {0xff, 0xff, 0xff, 0xff};
1187 
1188  /* copy the last remaining bytes into the write buffer */
1189  memcpy(last_word, buffer+bytes_written, bytes_remaining);
1190 
1191  if (!(address & 0xff))
1192  LOG_DEBUG("0x%" PRIx32 "", address);
1193 
1194  /* Program one word */
1195  target_write_u32(target, FLASH_FMA, address);
1196  target_write_buffer(target, FLASH_FMD, 4, last_word);
1198  /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
1199  /* Wait until write complete */
1200  do {
1201  target_read_u32(target, FLASH_FMC, &flash_fmc);
1202  } while (flash_fmc & FMC_WRITE);
1203  }
1204 
1205  /* Check access violations */
1206  target_read_u32(target, FLASH_CRIS, &flash_cris);
1207  if (flash_cris & (AMASK)) {
1208  LOG_DEBUG("flash_cris 0x%" PRIx32 "", flash_cris);
1210  }
1211  return ERROR_OK;
1212 }
1213 
1214 static int stellaris_probe(struct flash_bank *bank)
1215 {
1216  struct stellaris_flash_bank *stellaris_info = bank->driver_priv;
1217  int retval;
1218 
1219  /* If this is a stellaris chip, it has flash; probe() is just
1220  * to figure out how much is present. Only do it once.
1221  */
1222  if (stellaris_info->did1 != 0)
1223  return ERROR_OK;
1224 
1225  /* stellaris_read_part_info() already handled error checking and
1226  * reporting. Note that it doesn't write, so we don't care about
1227  * whether the target is halted or not.
1228  */
1229  retval = stellaris_read_part_info(bank);
1230  if (retval != ERROR_OK)
1231  return retval;
1232 
1233  free(bank->sectors);
1234 
1235  /* provide this for the benefit of the NOR flash framework */
1236  bank->size = stellaris_info->num_pages * stellaris_info->pagesize;
1237  bank->num_sectors = stellaris_info->num_pages;
1238  bank->sectors = calloc(bank->num_sectors, sizeof(struct flash_sector));
1239  for (unsigned int i = 0; i < bank->num_sectors; i++) {
1240  bank->sectors[i].offset = i * stellaris_info->pagesize;
1241  bank->sectors[i].size = stellaris_info->pagesize;
1242  bank->sectors[i].is_erased = -1;
1243  bank->sectors[i].is_protected = -1;
1244  }
1245 
1246  return retval;
1247 }
1248 
1250 {
1251  struct target *target = NULL;
1252  struct stellaris_flash_bank *stellaris_info = NULL;
1253  uint32_t flash_fmc;
1254 
1255  stellaris_info = bank->driver_priv;
1256  target = bank->target;
1257 
1258  if (target->state != TARGET_HALTED) {
1259  LOG_ERROR("Target not halted");
1260  return ERROR_TARGET_NOT_HALTED;
1261  }
1262 
1263  if (stellaris_info->did1 == 0)
1265 
1266  /* Refresh flash controller timing */
1269 
1270  /* Clear and disable flash programming interrupts */
1273 
1274  /* REVISIT this clobbers state set by any halted firmware ...
1275  * it might want to process those IRQs.
1276  */
1277 
1280  /* Wait until erase complete */
1281  do {
1282  target_read_u32(target, FLASH_FMC, &flash_fmc);
1283  } while (flash_fmc & FMC_MERASE);
1284 
1285  /* if device has > 128k, then second erase cycle is needed
1286  * this is only valid for older devices, but will not hurt */
1287  if (stellaris_info->num_pages * stellaris_info->pagesize > 0x20000) {
1288  target_write_u32(target, FLASH_FMA, 0x20000);
1290  /* Wait until erase complete */
1291  do {
1292  target_read_u32(target, FLASH_FMC, &flash_fmc);
1293  } while (flash_fmc & FMC_MERASE);
1294  }
1295 
1296  return ERROR_OK;
1297 }
1298 
1299 COMMAND_HANDLER(stellaris_handle_mass_erase_command)
1300 {
1301  if (CMD_ARGC < 1)
1303 
1304  struct flash_bank *bank;
1305  int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1306  if (retval != ERROR_OK)
1307  return retval;
1308 
1310  command_print(CMD, "stellaris mass erase complete");
1311  else
1312  command_print(CMD, "stellaris mass erase failed");
1313 
1314  return ERROR_OK;
1315 }
1316 
1326 COMMAND_HANDLER(stellaris_handle_recover_command)
1327 {
1328  struct flash_bank *bank;
1329  struct arm *arm;
1330  int retval;
1331 
1332  if (CMD_ARGC != 0)
1334 
1336  if (!bank)
1337  return ERROR_FAIL;
1338 
1339  /* REVISIT ... it may be worth sanity checking that the AP is
1340  * inactive before we start. ARM documents that switching a DP's
1341  * mode while it's active can cause fault modes that need a power
1342  * cycle to recover.
1343  */
1344 
1345  Jim_Eval_Named(CMD_CTX->interp, "catch { hla_command \"debug unlock\" }", NULL, 0);
1346  if (!strcmp(Jim_GetString(Jim_GetResult(CMD_CTX->interp), NULL), "0")) {
1347  retval = ERROR_OK;
1348  goto user_action;
1349  }
1350 
1351  /* assert SRST */
1353  LOG_ERROR("Can't recover Stellaris flash without SRST");
1354  return ERROR_FAIL;
1355  }
1357 
1358  arm = target_to_arm(bank->target);
1359  for (int i = 0; i < 5; i++) {
1360  retval = dap_to_swd(arm->dap);
1361  if (retval != ERROR_OK)
1362  goto done;
1363 
1364  retval = dap_to_jtag(arm->dap);
1365  if (retval != ERROR_OK)
1366  goto done;
1367  }
1368 
1369  /* de-assert SRST */
1371  retval = jtag_execute_queue();
1372 
1373  /* wait 400+ msec ... OK, "1+ second" is simpler */
1374  usleep(1000);
1375 
1376 user_action:
1377  /* USER INTERVENTION required for the power cycle
1378  * Restarting OpenOCD is likely needed because of mode switching.
1379  */
1380  LOG_INFO("USER ACTION: "
1381  "power cycle Stellaris chip, then restart OpenOCD.");
1382 
1383 done:
1384  return retval;
1385 }
1386 
1387 static const struct command_registration stellaris_exec_command_handlers[] = {
1388  {
1389  .name = "mass_erase",
1390  .usage = "<bank>",
1391  .handler = stellaris_handle_mass_erase_command,
1392  .mode = COMMAND_EXEC,
1393  .help = "erase entire device",
1394  },
1395  {
1396  .name = "recover",
1397  .handler = stellaris_handle_recover_command,
1398  .mode = COMMAND_EXEC,
1399  .usage = "",
1400  .help = "recover (and erase) locked device",
1401  },
1403 };
1404 static const struct command_registration stellaris_command_handlers[] = {
1405  {
1406  .name = "stellaris",
1407  .mode = COMMAND_EXEC,
1408  .help = "Stellaris flash command group",
1409  .usage = "",
1411  },
1413 };
1414 
1415 const struct flash_driver stellaris_flash = {
1416  .name = "stellaris",
1417  .commands = stellaris_command_handlers,
1418  .flash_bank_command = stellaris_flash_bank_command,
1419  .erase = stellaris_erase,
1420  .protect = stellaris_protect,
1421  .write = stellaris_write,
1422  .read = default_flash_read,
1423  .probe = stellaris_probe,
1424  .auto_probe = stellaris_probe,
1425  .erase_check = default_flash_blank_check,
1426  .protect_check = stellaris_protect_check,
1427  .info = get_stellaris_info,
1428  .free_driver_priv = default_flash_free_driver_priv,
1429 };
void init_reg_param(struct reg_param *param, char *reg_name, uint32_t size, enum param_direction direction)
Definition: algorithm.c:29
void destroy_reg_param(struct reg_param *param)
Definition: algorithm.c:37
@ PARAM_OUT
Definition: algorithm.h:16
@ ARM_MODE_THREAD
Definition: arm.h:93
static struct arm * target_to_arm(const struct target *target)
Convert target handle to generic ARM target state handle.
Definition: arm.h:260
int dap_to_jtag(struct adiv5_dap *dap)
Put the debug link into JTAG mode, if the target supports it.
Definition: arm_adi_v5.c:969
int dap_to_swd(struct adiv5_dap *dap)
Put the debug link into SWD mode, if the target supports it.
Definition: arm_adi_v5.c:951
This defines formats and data structures used to talk to ADIv5 entities.
#define ARMV7M_COMMON_MAGIC
Definition: armv7m.h:220
static void buf_set_u32(uint8_t *_buffer, unsigned first, unsigned num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
Definition: binarybuffer.h:31
void command_print_sameline(struct command_invocation *cmd, const char *format,...)
Definition: command.c:420
void command_print(struct command_invocation *cmd, const char *format,...)
Definition: command.c:443
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
Definition: command.h:141
#define CALL_COMMAND_HANDLER(name, extra ...)
Use this to macro to call a command helper (or a nested handler).
Definition: command.h:118
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:402
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:151
#define CMD_CTX
Use this macro to access the context of the command being handled, rather than accessing the variable...
Definition: command.h:146
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:253
@ COMMAND_EXEC
Definition: command.h:40
uint8_t bank
Definition: esirisc.c:135
#define ERROR_FLASH_SECTOR_INVALID
Definition: flash/common.h:29
#define ERROR_FLASH_BANK_NOT_PROBED
Definition: flash/common.h:35
#define ERROR_FLASH_OPERATION_FAILED
Definition: flash/common.h:30
#define ERROR_FLASH_DST_BREAKS_ALIGNMENT
Definition: flash/common.h:32
#define ERROR_FLASH_DST_OUT_OF_BANK
Definition: flash/common.h:31
int default_flash_blank_check(struct flash_bank *bank)
Provides default erased-bank check handling.
struct flash_bank * get_flash_bank_by_num_noprobe(unsigned int num)
Returns the flash bank like get_flash_bank_by_num(), without probing.
int default_flash_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
Provides default read implementation for flash memory.
void default_flash_free_driver_priv(struct flash_bank *bank)
Deallocates bank->driver_priv.
int jtag_execute_queue(void)
For software FIFO implementations, the queued commands can be executed during this call or earlier.
Definition: jtag/core.c:1037
int adapter_deassert_reset(void)
Definition: jtag/core.c:1900
enum reset_types jtag_get_reset_config(void)
Definition: jtag/core.c:1734
int adapter_assert_reset(void)
Definition: jtag/core.c:1880
@ RESET_HAS_SRST
Definition: jtag.h:219
#define LOG_WARNING(expr ...)
Definition: log.h:129
#define ERROR_FAIL
Definition: log.h:170
#define LOG_ERROR(expr ...)
Definition: log.h:132
#define LOG_INFO(expr ...)
Definition: log.h:126
#define LOG_DEBUG(expr ...)
Definition: log.h:109
#define ERROR_OK
Definition: log.h:164
struct rtt_source source
Definition: rtt/rtt.c:23
static const struct command_registration stellaris_exec_command_handlers[]
Definition: stellaris.c:1387
#define RCC2
Definition: stellaris.c:40
COMMAND_HANDLER(stellaris_handle_mass_erase_command)
Definition: stellaris.c:1299
#define DID0
Definition: stellaris.c:29
const char * partname
Definition: stellaris.c:118
#define USECRL
Definition: stellaris.c:51
#define FLASH_FSIZE
Definition: stellaris.c:60
#define AMISC
Definition: stellaris.c:63
static void stellaris_read_clock_info(struct flash_bank *bank)
Read clock configuration and set stellaris_info->usec_clocks.
Definition: stellaris.c:567
#define DID0_VER(did0)
Definition: stellaris.c:25
static int get_stellaris_info(struct flash_bank *bank, struct command_invocation *cmd)
Definition: stellaris.c:472
#define DID1
Definition: stellaris.c:30
static const struct command_registration stellaris_command_handlers[]
Definition: stellaris.c:1404
static int stellaris_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
Definition: stellaris.c:1101
static const struct @13 stellaris_parts[]
static int stellaris_protect_check(struct flash_bank *bank)
Definition: stellaris.c:780
static void stellaris_set_flash_timing(struct flash_bank *bank)
Definition: stellaris.c:519
#define DC1
Definition: stellaris.c:32
static int stellaris_probe(struct flash_bank *bank)
Definition: stellaris.c:1214
#define RCC
Definition: stellaris.c:38
static int stellaris_mass_erase(struct flash_bank *bank)
Definition: stellaris.c:1249
#define PLLCFG
Definition: stellaris.c:39
#define FLASH_FMC
Definition: stellaris.c:56
#define FMC_COMT
Definition: stellaris.c:71
#define FLASH_CIM
Definition: stellaris.c:58
static const unsigned rcc_xtal[32]
Definition: stellaris.c:533
#define AMASK
Definition: stellaris.c:66
#define FMC_WRITE
Definition: stellaris.c:74
static int stellaris_protect(struct flash_bank *bank, int set, unsigned int first, unsigned int last)
Definition: stellaris.c:884
#define FMC_MERASE
Definition: stellaris.c:72
#define FLASH_SSIZE
Definition: stellaris.c:61
#define FLASH_CRIS
Definition: stellaris.c:57
static int stellaris_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
Definition: stellaris.c:828
#define FMPPE0
Definition: stellaris.c:49
#define FMC_WRKEY
Definition: stellaris.c:70
const struct flash_driver stellaris_flash
Definition: stellaris.c:1415
static const uint8_t stellaris_write_code[]
Definition: stellaris.c:983
static const char *const stellaris_classname[]
Definition: stellaris.c:429
#define PMISC
Definition: stellaris.c:64
FLASH_BANK_COMMAND_HANDLER(stellaris_flash_bank_command)
Definition: stellaris.c:449
#define FMPPE
Definition: stellaris.c:45
uint8_t partno
Definition: stellaris.c:117
#define FLASH_FMA
Definition: stellaris.c:54
#define DC0
Definition: stellaris.c:31
#define SCB_BASE
Definition: stellaris.c:28
static int stellaris_write_block(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t wcount)
Definition: stellaris.c:1019
#define FLASH_FMD
Definition: stellaris.c:55
#define FLASH_MISC
Definition: stellaris.c:59
#define FMC_ERASE
Definition: stellaris.c:73
static int stellaris_read_part_info(struct flash_bank *bank)
Definition: stellaris.c:650
Represents a generic ARM core, with standard application registers.
Definition: arm.h:174
struct adiv5_dap * dap
For targets conforming to ARM Debug Interface v5, this handle references the Debug Access Port (DAP) ...
Definition: arm.h:256
unsigned int common_magic
Definition: armv7m.h:295
enum arm_mode core_mode
Definition: armv7m.h:297
When run_command is called, a new instance will be created on the stack, filled with the proper value...
Definition: command.h:76
const char * name
Definition: command.h:235
Provides details of a flash bank, available either on-chip or through a major interface.
Definition: nor/core.h:75
Provides the implementation-independent structure that defines all of the callbacks required by OpenO...
Definition: nor/driver.h:39
const char * name
Gives a human-readable name of this flash driver, This field is used to select and initialize the dri...
Definition: nor/driver.h:44
Describes the geometry and status of a single flash sector within a flash bank.
Definition: nor/core.h:28
const char * target_name
Definition: stellaris.c:94
const char * mck_desc
Definition: stellaris.c:110
uint32_t num_pages
Definition: stellaris.c:99
uint8_t target_class
Definition: stellaris.c:95
const char * iosc_desc
Definition: stellaris.c:109
Definition: target.h:116
enum target_state state
Definition: target.h:157
target_addr_t address
Definition: target.h:86
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
Definition: target.c:2342
int target_alloc_working_area(struct target *target, uint32_t size, struct working_area **area)
Definition: target.c:2060
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
Definition: target.c:2641
int target_free_working_area(struct target *target, struct working_area *area)
Free a working area.
Definition: target.c:2118
int target_alloc_working_area_try(struct target *target, uint32_t size, struct working_area **area)
Definition: target.c:1966
int target_run_flash_async_algorithm(struct target *target, const uint8_t *buffer, uint32_t count, int block_size, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, uint32_t buffer_start, uint32_t buffer_size, uint32_t entry_point, uint32_t exit_point, void *arch_info)
Streams data to a circular buffer on target intended for consumption by code running asynchronously o...
Definition: target.c:930
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
Definition: target.c:2550
#define ERROR_TARGET_NOT_HALTED
Definition: target.h:790
static const char * target_name(const struct target *target)
Returns the instance-specific name of the specified target.
Definition: target.h:233
@ TARGET_HALTED
Definition: target.h:56
#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE
Definition: target.h:794
#define NULL
Definition: usb.h:16
uint8_t status[4]
Definition: vdebug.c:17
uint8_t cmd
Definition: vdebug.c:1
uint8_t offset[4]
Definition: vdebug.c:9
uint8_t count[4]
Definition: vdebug.c:22