OpenOCD
mspm0.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2023-2025 Texas Instruments Incorporated - https://www.ti.com/
5  *
6  * NOR flash driver for MSPM0L and MSPM0G class of uC from Texas Instruments.
7  *
8  * See:
9  * https://www.ti.com/microcontrollers-mcus-processors/arm-based-microcontrollers/arm-cortex-m0-mcus/overview.html
10  ***************************************************************************/
11 
12 #ifdef HAVE_CONFIG_H
13 #include "config.h"
14 #endif
15 
16 #include "imp.h"
17 #include <helper/bits.h>
18 #include <helper/time_support.h>
19 
20 /* MSPM0 Region memory map */
21 #define MSPM0_FLASH_BASE_NONMAIN 0x41C00000
22 #define MSPM0_FLASH_END_NONMAIN 0x41C00400
23 #define MSPM0_FLASH_BASE_MAIN 0x0
24 #define MSPM0_FLASH_BASE_DATA 0x41D00000
25 
26 /* MSPM0 FACTORYREGION registers */
27 #define MSPM0_FACTORYREGION 0x41C40000
28 #define MSPM0_TRACEID (MSPM0_FACTORYREGION + 0x000)
29 #define MSPM0_DID (MSPM0_FACTORYREGION + 0x004)
30 #define MSPM0_USERID (MSPM0_FACTORYREGION + 0x008)
31 #define MSPM0_SRAMFLASH (MSPM0_FACTORYREGION + 0x018)
32 
33 /* MSPM0 FCTL registers */
34 #define FLASH_CONTROL_BASE 0x400CD000
35 #define FCTL_REG_DESC (FLASH_CONTROL_BASE + 0x10FC)
36 #define FCTL_REG_CMDEXEC (FLASH_CONTROL_BASE + 0x1100)
37 #define FCTL_REG_CMDTYPE (FLASH_CONTROL_BASE + 0x1104)
38 #define FCTL_REG_CMDADDR (FLASH_CONTROL_BASE + 0x1120)
39 #define FCTL_REG_CMDBYTEN (FLASH_CONTROL_BASE + 0x1124)
40 #define FCTL_REG_CMDDATA0 (FLASH_CONTROL_BASE + 0x1130)
41 #define FCTL_REG_CMDWEPROTA (FLASH_CONTROL_BASE + 0x11D0)
42 #define FCTL_REG_CMDWEPROTB (FLASH_CONTROL_BASE + 0x11D4)
43 #define FCTL_REG_CMDWEPROTNM (FLASH_CONTROL_BASE + 0x1210)
44 #define FCTL_REG_STATCMD (FLASH_CONTROL_BASE + 0x13D0)
45 
46 /* FCTL_STATCMD[CMDDONE] Bits */
47 #define FCTL_STATCMD_CMDDONE_MASK 0x00000001
48 #define FCTL_STATCMD_CMDDONE_STATDONE 0x00000001
49 
50 /* FCTL_STATCMD[CMDPASS] Bits */
51 #define FCTL_STATCMD_CMDPASS_MASK 0x00000002
52 #define FCTL_STATCMD_CMDPASS_STATPASS 0x00000002
53 
54 /*
55  * FCTL_CMDEXEC Bits
56  * FCTL_CMDEXEC[VAL] Bits
57  */
58 #define FCTL_CMDEXEC_VAL_EXECUTE 0x00000001
59 
60 /* FCTL_CMDTYPE[COMMAND] Bits */
61 #define FCTL_CMDTYPE_COMMAND_PROGRAM 0x00000001
62 #define FCTL_CMDTYPE_COMMAND_ERASE 0x00000002
63 
64 /* FCTL_CMDTYPE[SIZE] Bits */
65 #define FCTL_CMDTYPE_SIZE_ONEWORD 0x00000000
66 #define FCTL_CMDTYPE_SIZE_SECTOR 0x00000040
67 
68 /* FCTL_FEATURE_VER_B minimum */
69 #define FCTL_FEATURE_VER_B 0xA
70 
71 #define MSPM0_MAX_PROTREGS 3
72 
73 #define MSPM0_FLASH_TIMEOUT_MS 8000
74 #define ERR_STRING_MAX 255
75 
76 /* SYSCTL BASE */
77 #define SYSCTL_BASE 0x400AF000
78 #define SYSCTL_SECCFG_SECSTATUS (SYSCTL_BASE + 0x00003048)
79 
80 /*
81  * SYSCTL SOCLOCK MCLKCFG register (offset 0x1104 from SYSCTL_BASE).
82  * Used for the FLASH_ERR_01 workaround: accessing FACTORYREGION while MCLK
83  * is sourced from HSCLK (SYSPLL/HFXT, implying MCLK > 32 MHz) with flash
84  * wait-state 2 active causes a hard fault on MSPM0G devices. The flash
85  * controller enforces its wait-state timing for all AHB masters, including
86  * the DAP AHB-AP used by OpenOCD. Temporarily switching MCLK to SYSOSC
87  * (≤ 32 MHz on all MSPM0 variants) before reading FACTORYREGION avoids this.
88  */
89 #define SYSCTL_MCLKCFG (SYSCTL_BASE + 0x00001104)
90 #define SYSCTL_MCLKCFG_USEHSCLK BIT(16)
91 #define SYSCTL_MCLKCFG_FLASHWAIT_MASK GENMASK(11, 8)
92 #define SYSCTL_MCLKCFG_FLASHWAIT_2 (2U << 8)
93 
94 /* TI manufacturer ID */
95 #define TI_MANUFACTURER_ID 0x17
96 
97 /* Defines for probe status */
98 #define MSPM0_NO_ID_FOUND 0
99 #define MSPM0_DEV_ID_FOUND 1
100 #define MSPM0_DEV_PART_ID_FOUND 2
101 
103  /* chip id register */
104  uint32_t did;
105  /* Device Unique ID register */
106  uint32_t traceid;
107  unsigned char version;
108 
109  const char *name;
110 
111  /* Decoded flash information */
112  unsigned int data_flash_size_kb;
113  unsigned int main_flash_size_kb;
114  unsigned int main_flash_num_banks;
115  unsigned int sector_size;
116  /* Decoded SRAM information */
117  unsigned int sram_size_kb;
118 
119  /* Flash word size: 64 bit = 8, 128bit = 16 bytes */
120  unsigned char flash_word_size_bytes;
121 
122  /* Protection register stuff */
123  unsigned int protect_reg_base;
124  unsigned int protect_reg_count;
125 
126  /* Flashctl version: A - CMDWEPROTA/B, B- CMDWEPROTB */
127  unsigned char flash_version;
128 };
129 
131  const char *part_name;
132  unsigned short part;
133  unsigned char variant;
134 };
135 
137  const char *family_name;
138  unsigned short part_num;
139  unsigned char part_count;
140  const struct mspm0_part_info *part_info;
141 };
142 
143 /* https://www.ti.com/lit/ds/symlink/mspm0l1346.pdf Table 8-13 and so on */
144 static const struct mspm0_part_info mspm0l_parts[] = {
145  /* MSPM0L110x */
146  { "MSPM0L1105TDGS20R", 0x51DB, 0x16 },
147  { "MSPM0L1105TDGS28R", 0x51DB, 0x83 },
148  { "MSPM0L1105TDYYR", 0x51DB, 0x54 },
149  { "MSPM0L1105TRGER", 0x51DB, 0x86 },
150  { "MSPM0L1105TRHBR", 0x51DB, 0x68 },
151  { "MSPM0L1106TDGS20R", 0x5552, 0x4B },
152  { "MSPM0L1106TDGS28R", 0x5552, 0x98 },
153  { "MSPM0L1106TDYYR", 0x5552, 0x9D },
154  { "MSPM0L1106TRGER", 0x5552, 0x90 },
155  { "MSPM0L1106TRHBR", 0x5552, 0x53 },
156  /* MSPM0L130x (covers MSPM0L134x) */
157  { "MSPM0L1303SRGER", 0xef0, 0x17 },
158  { "MSPM0L1303TRGER", 0xef0, 0xe2 },
159  { "MSPM0L1304QDGS20R", 0xd717, 0x91 },
160  { "MSPM0L1304QDGS28R", 0xd717, 0xb6 },
161  { "MSPM0L1304QDYYR", 0xd717, 0xa0 },
162  { "MSPM0L1304QRHBR", 0xd717, 0xa9 },
163  { "MSPM0L1304SDGS20R", 0xd717, 0xfa },
164  { "MSPM0L1304SDGS28R", 0xd717, 0x73 },
165  { "MSPM0L1304SDYYR", 0xd717, 0xb7 },
166  { "MSPM0L1304SRGER", 0xd717, 0x26 },
167  { "MSPM0L1304SRHBR", 0xd717, 0xe4 },
168  { "MSPM0L1304TDGS20R", 0xd717, 0x33 },
169  { "MSPM0L1304TDGS28R", 0xd717, 0xa8 },
170  { "MSPM0L1304TDYYR", 0xd717, 0xf9 },
171  { "MSPM0L1304TRGER", 0xd717, 0xb7 },
172  { "MSPM0L1304TRHBR", 0xd717, 0x5a },
173  { "MSPM0L1305QDGS20R", 0x4d03, 0xb7 },
174  { "MSPM0L1305QDGS28R", 0x4d03, 0x74 },
175  { "MSPM0L1305QDYYR", 0x4d03, 0xec },
176  { "MSPM0L1305QRHBR", 0x4d03, 0x78 },
177  { "MSPM0L1305SDGS20R", 0x4d03, 0xc7 },
178  { "MSPM0L1305SDGS28R", 0x4d03, 0x64 },
179  { "MSPM0L1305SDYYR", 0x4d03, 0x91 },
180  { "MSPM0L1305SRGER", 0x4d03, 0x73 },
181  { "MSPM0L1305SRHBR", 0x4d03, 0x2d },
182  { "MSPM0L1305TDGS20R", 0x4d03, 0xa0 },
183  { "MSPM0L1305TDGS28R", 0x4d03, 0xfb },
184  { "MSPM0L1305TDYYR", 0x4d03, 0xde },
185  { "MSPM0L1305TRGER", 0x4d03, 0xea },
186  { "MSPM0L1305TRHBR", 0x4d03, 0x85 },
187  { "MSPM0L1306QDGS20R", 0xbb70, 0x59 },
188  { "MSPM0L1306QDGS28R", 0xbb70, 0xf7 },
189  { "MSPM0L1306QDYYR", 0xbb70, 0x9f },
190  { "MSPM0L1306QRHBR", 0xbb70, 0xc2 },
191  { "MSPM0L1306SDGS20R", 0xbb70, 0xf4 },
192  { "MSPM0L1306SDGS28R", 0xbb70, 0x5 },
193  { "MSPM0L1306SDYYR", 0xbb70, 0xe },
194  { "MSPM0L1306SRGER", 0xbb70, 0x7f },
195  { "MSPM0L1306SRHBR", 0xbb70, 0x3c },
196  { "MSPM0L1306TDGS20R", 0xbb70, 0xa },
197  { "MSPM0L1306TDGS28R", 0xbb70, 0x63 },
198  { "MSPM0L1306TDYYR", 0xbb70, 0x35 },
199  { "MSPM0L1306TRGER", 0xbb70, 0xaa },
200  { "MSPM0L1306TRHBR", 0xbb70, 0x52 },
201  { "MSPM0L1343TDGS20R", 0xb231, 0x2e },
202  { "MSPM0L1344TDGS20R", 0x40b0, 0xd0 },
203  { "MSPM0L1345TDGS28R", 0x98b4, 0x74 },
204  { "MSPM0L1346TDGS28R", 0xf2b5, 0xef },
205 };
206 
207 /* https://www.ti.com/lit/ds/symlink/mspm0g3506.pdf Table 8-22 */
208 static const struct mspm0_part_info mspm0g_parts_bb88[] = {
209  /* MSPM0G110x */
210  { "MSPM0G1105TPTR", 0x8934, 0xD },
211  { "MSPM0G1105TRGZR", 0x8934, 0xFE },
212  { "MSPM0G1106TPMR", 0x477B, 0xD4 },
213  { "MSPM0G1106TPTR", 0x477B, 0x71 },
214  { "MSPM0G1106TRGZR", 0x477B, 0xBB },
215  { "MSPM0G1106TRHBR", 0x477B, 0x01 },
216  { "MSPM0G1106TYCJR", 0x477B, 0x09 },
217  { "MSPM0G1107TDGS28R", 0x807B, 0x82 },
218  { "MSPM0G1107TPMR", 0x807B, 0xB3 },
219  { "MSPM0G1107TPTR", 0x807B, 0x32 },
220  { "MSPM0G1107TRGER", 0x807B, 0x79 },
221  { "MSPM0G1107TRGZR", 0x807B, 0x20 },
222  { "MSPM0G1107TRHBR", 0x807B, 0xBC },
223  { "MSPM0G1107TYCJR", 0x807B, 0x7A },
224  /* MSPM0G150x */
225  { "MSPM0G1505SDGS28R", 0x13C4, 0x73 },
226  { "MSPM0G1505SPMR", 0x13C4, 0x53 },
227  { "MSPM0G1505SPTR", 0x13C4, 0x3E },
228  { "MSPM0G1505SRGER", 0x13C4, 0x47 },
229  { "MSPM0G1505SRGZR", 0x13C4, 0x34 },
230  { "MSPM0G1505SRHBR", 0x13C4, 0x30 },
231  { "MSPM0G1506SDGS28R", 0x5AE0, 0x3A },
232  { "MSPM0G1506SPMR", 0x5AE0, 0xF6 },
233  { "MSPM0G1506SRGER", 0x5AE0, 0x67 },
234  { "MSPM0G1506SRGZR", 0x5AE0, 0x75 },
235  { "MSPM0G1506SRHBR", 0x5AE0, 0x57 },
236  { "MSPM0G1506SRPTR", 0x5AE0, 0x36 },
237  { "MSPM0G1506SYCJR", 0x5AE0, 0x9E },
238  { "MSPM0G1507SDGS28R", 0x2655, 0x6D },
239  { "MSPM0G1507SPMR", 0x2655, 0x97 },
240  { "MSPM0G1507SPTR", 0x2655, 0x2E },
241  { "MSPM0G1507SRGER", 0x2655, 0x83 },
242  { "MSPM0G1507SRGZR", 0x2655, 0xD3 },
243  { "MSPM0G1507SRHBR", 0x2655, 0x4D },
244  { "MSPM0G1507SYCJR", 0x2655, 0x65 },
245  /* MSPM0G310x */
246  { "MSPM0G3105SDGS20R", 0x4749, 0x21 },
247  { "MSPM0G3105SDGS28R", 0x4749, 0xDD },
248  { "MSPM0G3105SRHBR", 0x4749, 0xBE },
249  { "MSPM0G3106SDGS20R", 0x54C7, 0xD2 },
250  { "MSPM0G3106SDGS28R", 0x54C7, 0xB9 },
251  { "MSPM0G3106SRHBR", 0x54C7, 0x67 },
252  { "MSPM0G3107SDGS20R", 0xAB39, 0x5C },
253  { "MSPM0G3107SDGS28R", 0xAB39, 0xCC },
254  { "MSPM0G3107SRHBR", 0xAB39, 0xB7 },
255  /* MSPM0G350x */
256  { "MSPM0G3505SDGS28R", 0xc504, 0x8e },
257  { "MSPM0G3505SPMR", 0xc504, 0x1d },
258  { "MSPM0G3505SPTR", 0xc504, 0x93 },
259  { "MSPM0G3505SRGZR", 0xc504, 0xc7 },
260  { "MSPM0G3505SRHBR", 0xc504, 0xe7 },
261  { "MSPM0G3506SDGS28R", 0x151f, 0x8 },
262  { "MSPM0G3506SPMR", 0x151f, 0xd4 },
263  { "MSPM0G3506SPTR", 0x151f, 0x39 },
264  { "MSPM0G3506SRGZR", 0x151f, 0xfe },
265  { "MSPM0G3506SRHBR", 0x151f, 0xb5 },
266  { "MSPM0G3507SDGS28R", 0xae2d, 0xca },
267  { "MSPM0G3507SPMR", 0xae2d, 0xc7 },
268  { "MSPM0G3507SPTR", 0xae2d, 0x3f },
269  { "MSPM0G3507SRGZR", 0xae2d, 0xf7 },
270  { "MSPM0G3507SRHBR", 0xae2d, 0x4c },
271  /* MSPM0G310x-Q1 */
272  { "M0G3105QDGS20RQ1", 0x1349, 0xFB},
273  { "M0G3105QDGS28RQ1", 0x1349, 0x1B},
274  { "M0G3105QDGS32RQ1", 0x1349, 0x08},
275  { "M0G3105QPMRQ1", 0x1349, 0xD0},
276  { "M0G3105QPTRQ1", 0x1349, 0xEF},
277  { "M0G3105QRGZRQ1", 0x1349, 0x70},
278  { "M0G3105QRHBRQ1", 0x1349, 0x01},
279  { "M0G3106QDGS20RQ1", 0x94AD, 0x6F},
280  { "M0G3106QDGS28RQ1", 0x94AD, 0x03},
281  { "M0G3106QDGS32RQ1", 0x94AD, 0x8D},
282  { "M0G3106QPMRQ1", 0x54C7, 0x08},
283  { "M0G3106QPTRQ1", 0x54C7, 0x3F},
284  { "M0G3106QRGZRQ1", 0x94AD, 0xE6},
285  { "M0G3106QRHBRQ1", 0x94AD, 0x20},
286  { "M0G3107QDGS20RQ1", 0x4e2f, 0xfd},
287  { "M0G3107QDGS28RQ1", 0x4e2f, 0x67},
288  { "M0G3107QDGS28RQ1", 0x4e2f, 0xd5},
289  { "M0G3107QPMRQ1", 0x4e2f, 0x51 },
290  { "M0G3107QPTRQ1", 0x4e2f, 0xc7},
291  { "M0G3107QRGZRQ1", 0x4e2f, 0x8a },
292  { "M0G3107QRHBRQ1", 0x4e2f, 0x9a},
293  /* MSPM0G350x-Q1 */
294  { "M0G3505QDGS28RQ1", 0x704E, 0x4C },
295  { "M0G3505QDGS32RQ1", 0x704E, 0x7F },
296  { "M0G3505QPMRQ1", 0x704E, 0x7B },
297  { "M0G3505QPTRQ1", 0x704E, 0x9C },
298  { "M0G3505QRGZRQ1", 0x704E, 0xC9 },
299  { "M0G3505QRHBRQ1", 0x704E, 0x26 },
300  { "M0G3506QDGS28RQ1", 0xEE12, 0x71 },
301  { "M0G3506QDGS32RQ1", 0xEE12, 0x6C },
302  { "M0G3506QPMRQ1", 0xEE12, 0x7B },
303  { "M0G3506QPTRQ1", 0xEE12, 0x5A },
304  { "M0G3506QRGZRQ1", 0xEE12, 0xD2 },
305  { "M0G3506QRHBRQ1", 0xEE12, 0xFC },
306  { "M0G3507QDGS28RQ1", 0x34E0, 0xEA },
307  { "M0G3507QDGS32RQ1", 0x34E0, 0xF6 },
308  { "M0G3507QPMRQ1", 0x34E0, 0x26 },
309  { "M0G3507QRGZRQ1", 0x34E0, 0xC5 },
310  { "M0G3507QRHBRQ1", 0x34E0, 0xAC },
311  { "M0G3507QSPTRQ1", 0x34E0, 0xE3 },
312 };
313 
314 /* https://www.ti.com/lit/gpn/mspm0g1518 Table 8-21 and so on */
315 static const struct mspm0_part_info mspm0g_parts_bba9[] = {
316  /* MSPM0Gx51x */
317  { "MSPM0G1518SPMR", 0x2120, 0x13 },
318  { "MSPM0G1518SPNR", 0x2120, 0x16 },
319  { "MSPM0G1518SPTR", 0x2120, 0x12 },
320  { "MSPM0G1518SPZR", 0x2120, 0x18 },
321  { "MSPM0G1518SRGZR", 0x2120, 0x11 },
322  { "MSPM0G1518SRHBR", 0x2120, 0x10 },
323  { "MSPM0G1518SZAWR", 0x2120, 0x19 },
324  { "MSPM0G1519SPMR", 0x2407, 0x13 },
325  { "MSPM0G1519SPNR", 0x2407, 0x16 },
326  { "MSPM0G1519SPTR", 0x2407, 0x12 },
327  { "MSPM0G1519SPZR", 0x2407, 0x18 },
328  { "MSPM0G1519SRGZR", 0x2407, 0x11 },
329  { "MSPM0G1519SRHBR", 0x2407, 0x10 },
330  { "MSPM0G1519SZAWR", 0x2407, 0x19 },
331  { "MSPM0G3518SPMR", 0x1205, 0x13 },
332  { "MSPM0G3518SPNR", 0x1205, 0x15 },
333  { "MSPM0G3518SPTR", 0x1205, 0x12 },
334  { "MSPM0G3518SPZR", 0x1205, 0x16 },
335  { "MSPM0G3518SRGZR", 0x1205, 0x11 },
336  { "MSPM0G3518SRHBR", 0x1205, 0x10 },
337  { "MSPM0G3518SZAWR", 0x1205, 0x19 },
338  { "MSPM0G3519SPMR", 0x1508, 0x13 },
339  { "MSPM0G3519SPNR", 0x1508, 0x15 },
340  { "MSPM0G3519SPTR", 0x1508, 0x12 },
341  { "MSPM0G3519SPZR", 0x1508, 0x16 },
342  { "MSPM0G3519SRGZR", 0x1508, 0x11 },
343  { "MSPM0G3519SRHBR", 0x1508, 0x10 },
344  { "MSPM0G3519SZAWR", 0x1508, 0x19 },
345  /* MSPM0G351x-Q1 */
346  { "M0G3518QPMRQ1", 0x4009, 0x13 },
347  { "M0G3518QPNRQ1", 0x4009, 0x14 },
348  { "M0G3518QPTRQ1", 0x4009, 0x12 },
349  { "M0G3518QPZRQ1", 0x4009, 0x15 },
350  { "M0G3518QRGZRQ1", 0x4009, 0x11 },
351  { "M0G3518QRHBRQ1", 0x4009, 0x10 },
352  { "M0G3519QPMRQ1", 0x3512, 0x13 },
353  { "M0G3519AQPMRQ1", 0x3512, 0x16 },
354  { "M0G3519QPNRQ1", 0x3512, 0x14 },
355  { "M0G3519QPTRQ1", 0x3512, 0x12 },
356  { "M0G3519QPZRQ1", 0x3512, 0x15 },
357  { "M0G3519QRGZRQ1", 0x3512, 0x11 },
358  { "M0G3519QRHBRQ1", 0x3512, 0x10 },
359  /* MSPM0G352x-Q1 */
360  { "M0G3529QPMRQ1", 0xF8D1, 0x13 },
361 };
362 
363 /* https://www.ti.com/lit/gpn/mspm0g5187 Table 8-24*/
364 static const struct mspm0_part_info mspm0g_parts_bbbc[] = {
365  /* MSPM0G5187 */
366  { "MSPM0G5187S28YCJR", 0x5610, 0x18 },
367  { "MSPM0G5187SDGS20R", 0x5610, 0x16 },
368  { "MSPM0G5187SPMR", 0x5610, 0x10 },
369  { "MSPM0G5187SPTR", 0x5610, 0x11 },
370  { "MSPM0G5187SRHBR", 0x5610, 0x13 },
371  { "MSPM0G5187SRGER", 0x5610, 0x14 },
372  { "MSPM0G5187SRGZR", 0x5610, 0x12 },
373  { "MSPM0G5187SRUYR", 0x5610, 0x17 },
374 };
375 
376 /* https://www.ti.com/lit/gpn/mspm0c1104 Table 8-12 and so on */
377 static const struct mspm0_part_info mspm0c_parts[] = {
378  { "MSPS003F4SPW20R", 0x57b3, 0x70},
379  { "MSPM0C1104SDGS20R", 0x57b3, 0x71},
380  { "MSPM0C1104SRUKR", 0x57b3, 0x73},
381  { "MSPM0C1104SDYYR", 0x57b3, 0x75},
382  { "MSPM0C1104SDDFR", 0x57b3, 0x77},
383  { "MSPM0C1104SDSGR", 0x57b3, 0x79},
384 };
385 
386 /* https://www.ti.com/lit/gpn/MSPM0L2228 Table 8-16 and so on */
387 static const struct mspm0_part_info mspm0lx22x_parts[] = {
388  { "MSPM0L1227SRGER", 0x7C32, 0xF1},
389  { "MSPM0L1227SPTR", 0x7C32, 0xC9},
390  { "MSPM0L1227SPMR", 0x7C32, 0x1C},
391  { "MSPM0L1227SPNAR", 0x7C32, 0x91},
392  { "MSPM0L1227SPNR", 0x7C32, 0x39},
393  { "MSPM0L1228SRGER", 0x33F7, 0x13},
394  { "MSPM0L1228SRHBR", 0x33F7, 0x3A},
395  { "MSPM0L1228SRGZR", 0x33F7, 0xBC},
396  { "MSPM0L1228SPTR", 0x33F7, 0xF8},
397  { "MSPM0L1228SPMR", 0x33F7, 0xCE},
398  { "MSPM0L1228SPNAR", 0x33F7, 0x59},
399  { "MSPM0L1228SPNR", 0x33F7, 0x7},
400  { "MSPM0L2227SRGZR", 0x5E8F, 0x90},
401  { "MSPM0L2227SPTR", 0x5E8F, 0xA},
402  { "MSPM0L2227SPMR", 0x5E8F, 0x6D},
403  { "MSPM0L2227SPNAR", 0x5E8F, 0x24},
404  { "MSPM0L2227SPNR", 0x5E8F, 0x68},
405  { "MSPM0L2228SRGZR", 0x2C38, 0xB8},
406  { "MSPM0L2228SPTR", 0x2C38, 0x25},
407  { "MSPM0L2228SPMR", 0x2C38, 0x6E},
408  { "MSPM0L2228SPNAR", 0x2C38, 0x63},
409  { "MSPM0L2228SPNR", 0x2C38, 0x3C},
410 };
411 
412 static const struct mspm0_family_info mspm0_finf[] = {
413  { "MSPM0L", 0xbb82, ARRAY_SIZE(mspm0l_parts), mspm0l_parts },
414  { "MSPM0Lx22x", 0xbb9f, ARRAY_SIZE(mspm0lx22x_parts), mspm0lx22x_parts },
415  { "MSPM0G", 0xbb88, ARRAY_SIZE(mspm0g_parts_bb88), mspm0g_parts_bb88 },
416  { "MSPM0G", 0xbba9, ARRAY_SIZE(mspm0g_parts_bba9), mspm0g_parts_bba9 },
417  { "MSPM0G", 0xbbbc, ARRAY_SIZE(mspm0g_parts_bbbc), mspm0g_parts_bbbc },
418  { "MSPM0C", 0xbba1, ARRAY_SIZE(mspm0c_parts), mspm0c_parts },
419 };
420 
421 /*
422  * OpenOCD command interface
423  */
424 
425 /*
426  * flash_bank mspm0 <base> <size> 0 0 <target#>
427  */
428 FLASH_BANK_COMMAND_HANDLER(mspm0_flash_bank_command)
429 {
430  struct mspm0_flash_bank *mspm0_info;
431 
432  switch (bank->base) {
436  break;
437  default:
438  LOG_ERROR("Invalid bank address " TARGET_ADDR_FMT, bank->base);
439  return ERROR_FAIL;
440  }
441 
442  mspm0_info = calloc(1, sizeof(struct mspm0_flash_bank));
443  if (!mspm0_info) {
444  LOG_ERROR("%s: Out of memory for mspm0_info!", __func__);
445  return ERROR_FAIL;
446  }
447 
448  bank->driver_priv = mspm0_info;
449 
450  mspm0_info->sector_size = 0x400;
451 
452  return ERROR_OK;
453 }
454 
455 /*
456  * Chip identification and status
457  */
459 {
460  struct mspm0_flash_bank *mspm0_info = bank->driver_priv;
461 
462  if (mspm0_info->did == 0)
464 
466  "\nTI MSPM0 information: Chip is "
467  "%s rev %d Device Unique ID: 0x%" PRIu32 "\n",
468  mspm0_info->name, mspm0_info->version,
469  mspm0_info->traceid);
471  "main flash: %uKiB in %u bank(s), sram: %uKiB, data flash: %uKiB",
472  mspm0_info->main_flash_size_kb,
473  mspm0_info->main_flash_num_banks, mspm0_info->sram_size_kb,
474  mspm0_info->data_flash_size_kb);
475 
476  return ERROR_OK;
477 }
478 
479 /* Extract a bitfield helper */
480 static unsigned int mspm0_extract_val(unsigned int var, unsigned char hi, unsigned char lo)
481 {
482  return (var & GENMASK(hi, lo)) >> lo;
483 }
484 
486 {
487  struct mspm0_flash_bank *mspm0_info = bank->driver_priv;
488  struct target *target = bank->target;
489  const struct mspm0_family_info *minfo = NULL;
490 
491  /*
492  * FLASH_ERR_01 workaround: on MSPM0G devices the flash controller
493  * rejects any bus-master access to FACTORYREGION when MCLK is sourced
494  * from HSCLK (SYSPLL/HFXT) and flash wait-state 2 is active
495  * (required for MCLK > 32 MHz). This applies to DAP AHB-AP reads too,
496  * not just CPU accesses. If both conditions are true, temporarily
497  * switch MCLK back to SYSOSC (≤ 32 MHz on every MSPM0 variant) for the
498  * FACTORYREGION reads and restore afterwards. The SYSCTL_MCLKCFG write
499  * does not take place on L/C parts: USEHSCLK is never set there because
500  * those cores do not exceed 32 MHz.
501  */
502  uint32_t saved_mclkcfg = 0;
503  bool mclk_switched = false;
504  uint32_t mclkcfg;
505  int retval = target_read_u32(target, SYSCTL_MCLKCFG, &mclkcfg);
506  if (retval != ERROR_OK) {
507  LOG_ERROR("Failed to read SYSCTL_MCLKCFG to check FLASH_ERR_01");
508  return retval;
509  }
510 
511  if ((mclkcfg & SYSCTL_MCLKCFG_USEHSCLK) &&
513  saved_mclkcfg = mclkcfg;
515  mclkcfg & ~SYSCTL_MCLKCFG_USEHSCLK);
516  if (retval == ERROR_OK) {
517  mclk_switched = true;
518  /*
519  * Read back MCLKCFG to flush the write, then add an
520  * explicit delay to allow the MCLK source mux to fully
521  * settle on SYSOSC before the flash controller timing is
522  * used for FACTORYREGION accesses.
523  */
524  uint32_t dummy;
526  if (retval != ERROR_OK) {
527  LOG_ERROR("MSPM0: FLASH_ERR_01 workaround: "
528  "readback flush failed");
529  goto restore_mclk;
530  }
531  alive_sleep(1);
532  LOG_DEBUG("MSPM0: FLASH_ERR_01 workaround ACTIVE: "
533  "Lowering MCLK before FACTORYREGION read");
534  } else {
535  LOG_ERROR("MSPM0: FLASH_ERR_01 workaround: "
536  "could not lower MCLK before FACTORYREGION read");
537  }
538  }
539 
540  /* Read and parse chip identification and flash version register */
541  uint32_t did;
542  retval = target_read_u32(target, MSPM0_DID, &did);
543  if (retval != ERROR_OK) {
544  LOG_ERROR("Failed to read device ID");
545  goto restore_mclk;
546  }
547  retval = target_read_u32(target, MSPM0_TRACEID, &mspm0_info->traceid);
548  if (retval != ERROR_OK) {
549  LOG_ERROR("Failed to read trace ID");
550  goto restore_mclk;
551  }
552  uint32_t userid;
553  retval = target_read_u32(target, MSPM0_USERID, &userid);
554  if (retval != ERROR_OK) {
555  LOG_ERROR("Failed to read user ID");
556  goto restore_mclk;
557  }
558  uint32_t flashram;
559  retval = target_read_u32(target, MSPM0_SRAMFLASH, &flashram);
560  if (retval != ERROR_OK) {
561  LOG_ERROR("Failed to read sramflash register");
562  goto restore_mclk;
563  }
564 
565 restore_mclk:
566  if (mclk_switched) {
567  int retval2 = target_write_u32(target, SYSCTL_MCLKCFG, saved_mclkcfg);
568  if (retval2 != ERROR_OK) {
569  LOG_ERROR("MSPM0: FLASH_ERR_01 workaround: "
570  "could not restore MCLK after FACTORYREGION read");
571  return retval2;
572  }
573  LOG_DEBUG("MSPM0: FLASH_ERR_01 workaround: "
574  "restored MCLK after FACTORYREGION read");
575  }
576  if (retval != ERROR_OK)
577  return retval;
578 
579  uint32_t flashdesc;
580  retval = target_read_u32(target, FCTL_REG_DESC, &flashdesc);
581  if (retval != ERROR_OK) {
582  LOG_ERROR("Failed to read flashctl description register");
583  return retval;
584  }
585 
586  unsigned char version = mspm0_extract_val(did, 31, 28);
587  unsigned short pnum = mspm0_extract_val(did, 27, 12);
588  unsigned char variant = mspm0_extract_val(userid, 23, 16);
589  unsigned short part = mspm0_extract_val(userid, 15, 0);
590  unsigned short manufacturer = mspm0_extract_val(did, 11, 1);
591 
592  /*
593  * Valid DIE and manufacturer ID?
594  * Check the ALWAYS_1 bit to be 1 and manufacturer to be 0x17. All MSPM0
595  * devices within the Device ID field of the factory constants will
596  * always read 0x17 as it is TI's JEDEC bank and company code. If 1
597  * and 0x17 is not read from their respective registers then it truly
598  * is not a MSPM0 device so we will return an error instead of
599  * going any further.
600  */
601  if (!(did & BIT(0)) || !(manufacturer & TI_MANUFACTURER_ID)) {
602  LOG_WARNING("Unknown Device ID[0x%" PRIx32 "], cannot identify target",
603  did);
604  LOG_DEBUG("did 0x%" PRIx32 ", traceid 0x%" PRIx32 ", userid 0x%" PRIx32
605  ", flashram 0x%" PRIx32, did, mspm0_info->traceid, userid,
606  flashram);
608  }
609 
610  /* Initialize master index selector and probe status*/
611  unsigned char minfo_idx = 0xff;
612  unsigned char probe_status = MSPM0_NO_ID_FOUND;
613 
614  /* Check if we at least know the family of devices */
615  for (unsigned int i = 0; i < ARRAY_SIZE(mspm0_finf); i++) {
616  if (mspm0_finf[i].part_num == pnum) {
617  minfo_idx = i;
618  minfo = &mspm0_finf[i];
619  probe_status = MSPM0_DEV_ID_FOUND;
620  break;
621  }
622  }
623 
624  /* Initialize part index selector*/
625  unsigned char pinfo_idx = 0xff;
626 
627  /*
628  * If we can identify the part number then we will attempt to identify
629  * the specific chip. Otherwise, if we do not know the part number then
630  * it would be useless to identify the specific chip.
631  */
632  if (probe_status == MSPM0_DEV_ID_FOUND) {
633  /* Can we specifically identify the chip */
634  for (unsigned int i = 0; i < minfo->part_count; i++) {
635  if (minfo->part_info[i].part == part
636  && minfo->part_info[i].variant == variant) {
637  pinfo_idx = i;
638  probe_status = MSPM0_DEV_PART_ID_FOUND;
639  break;
640  }
641  }
642  }
643 
644  /*
645  * We will check the status of our probe within this switch-case statement
646  * using these three scenarios.
647  *
648  * 1) Device, part, and variant ID is unknown.
649  * 2) Device ID is known but the part/variant ID is unknown.
650  * 3) Device ID and part/variant ID is known
651  *
652  * For scenario 1, we allow the user to continue because if the
653  * manufacturer matches TI's JEDEC value and ALWAYS_1 from the device ID
654  * field is correct then the assumption the user is using an MSPM0 device
655  * can be made.
656  */
657  switch (probe_status) {
658  case MSPM0_NO_ID_FOUND:
659  mspm0_info->name = "mspm0x";
660  LOG_INFO("Unidentified PART[0x%x]/variant[0x%x"
661  "], unknown DeviceID[0x%x"
662  "]. Attempting to proceed as %s.", part, variant, pnum,
663  mspm0_info->name);
664  break;
665  case MSPM0_DEV_ID_FOUND:
666  mspm0_info->name = mspm0_finf[minfo_idx].family_name;
667  LOG_INFO("Unidentified PART[0x%x]/variant[0x%x"
668  "], known DeviceID[0x%x"
669  "]. Attempting to proceed as %s.", part, variant, pnum,
670  mspm0_info->name);
671  break;
673  default:
674  mspm0_info->name = mspm0_finf[minfo_idx].part_info[pinfo_idx].part_name;
675  LOG_DEBUG("Part: %s detected", mspm0_info->name);
676  break;
677  }
678 
679  mspm0_info->did = did;
680  mspm0_info->version = version;
681  mspm0_info->data_flash_size_kb = mspm0_extract_val(flashram, 31, 26);
682  mspm0_info->main_flash_size_kb = mspm0_extract_val(flashram, 11, 0);
683  mspm0_info->main_flash_num_banks = mspm0_extract_val(flashram, 13, 12) + 1;
684  mspm0_info->sram_size_kb = mspm0_extract_val(flashram, 25, 16);
685  mspm0_info->flash_version = mspm0_extract_val(flashdesc, 15, 12);
686 
687  /*
688  * Hardcode flash_word_size unless we find some other pattern
689  * See section 7.7 (Foot note mentions the flash word size).
690  * almost all values seem to be 8 bytes, but if there are variance,
691  * then we should update mspm0_part_info structure with this info.
692  */
693  mspm0_info->flash_word_size_bytes = 8;
694 
695  LOG_DEBUG("Detected: main flash: %uKb in %u banks, sram: %uKb, data flash: %uKb",
696  mspm0_info->main_flash_size_kb, mspm0_info->main_flash_num_banks,
697  mspm0_info->sram_size_kb, mspm0_info->data_flash_size_kb);
698 
699  return ERROR_OK;
700 }
701 
702 /*
703  * Decode error values
704  */
705 static const struct {
706  const unsigned char bit_offset;
707  const char *fail_string;
709  { 2, "CMDINPROGRESS" },
710  { 4, "FAILWEPROT" },
711  { 5, "FAILVERIFY" },
712  { 6, "FAILILLADDR" },
713  { 7, "FAILMODE" },
714  { 12, "FAILMISC" },
715 };
716 
717 static const char *mspm0_fctl_translate_ret_err(unsigned int return_code)
718 {
719  for (unsigned int i = 0; i < ARRAY_SIZE(mspm0_fctl_fail_decode_strings); i++) {
720  if (return_code & BIT(mspm0_fctl_fail_decode_strings[i].bit_offset))
722  }
723 
724  /* If unknown error notify the user*/
725  return "FAILUNKNOWN";
726 }
727 
728 static int mspm0_fctl_get_sector_reg(struct flash_bank *bank, unsigned int addr,
729  unsigned int *reg, unsigned int *sector_mask)
730 {
731  struct mspm0_flash_bank *mspm0_info = bank->driver_priv;
732  struct target *target = bank->target;
733  int ret = ERROR_OK;
734  unsigned int sector_num = (addr >> 10);
735  unsigned int sector_in_bank = sector_num;
736  unsigned int phys_sector_num = sector_num;
737  uint32_t sysctl_sec_status;
738  unsigned int exec_upper_bank;
739 
740  /*
741  * If the device has dual banks we will need to check if it is configured
742  * to execute from the upper bank. In the scenario that we are executing
743  * from upper bank then we will need to protect it using CMDWEPROTA rather
744  * than CMDWEPROTB. We also need to take into account what sector
745  * we're using when going between banks.
746  */
747  if (mspm0_info->main_flash_num_banks > 1 &&
748  bank->base == MSPM0_FLASH_BASE_MAIN) {
749  ret = target_read_u32(target, SYSCTL_SECCFG_SECSTATUS, &sysctl_sec_status);
750  if (ret != ERROR_OK)
751  return ret;
752  exec_upper_bank = mspm0_extract_val(sysctl_sec_status, 12, 12);
753  if (exec_upper_bank) {
754  if (sector_num > (mspm0_info->main_flash_size_kb / 2)) {
755  phys_sector_num =
756  sector_num - (mspm0_info->main_flash_size_kb / 2);
757  } else {
758  phys_sector_num =
759  sector_num + (mspm0_info->main_flash_size_kb / 2);
760  }
761  }
762  sector_in_bank =
763  sector_num % (mspm0_info->main_flash_size_kb /
764  mspm0_info->main_flash_num_banks);
765  }
766 
767  /*
768  * NOTE: MSPM0 devices of version A will use CMDWEPROTA and CMDWEPROTB
769  * for MAIN flash. CMDWEPROTC is included in the TRM/DATASHEET but for
770  * all practical purposes, it is considered reserved. If the flash
771  * version on the device is version B, then we will only use
772  * CMDWEPROTB for MAIN and DATA flash if the device has it.
773  */
774  switch (bank->base) {
777  if (mspm0_info->flash_version < FCTL_FEATURE_VER_B) {
778  /* Use CMDWEPROTA */
779  if (phys_sector_num < 32) {
780  *sector_mask = BIT(phys_sector_num);
782  }
783 
784  /* Use CMDWEPROTB */
785  if (phys_sector_num >= 32 && sector_in_bank < 256) {
786  /* Dual bank system */
787  if (mspm0_info->main_flash_num_banks > 1)
788  *sector_mask = BIT(sector_in_bank / 8);
789  else /* Single bank system */
790  *sector_mask = BIT((sector_in_bank - 32) / 8);
792  }
793  } else {
794  *sector_mask = BIT((sector_in_bank / 8) % 32);
796  }
797  break;
799  *sector_mask = BIT(sector_num % 32);
801  break;
802  default:
803  /*
804  * Not expected to reach here due to check in mspm0_address_check()
805  * but adding it as another layer of safety.
806  */
808  break;
809  }
810 
811  if (ret != ERROR_OK)
812  LOG_ERROR("Unable to map sector protect reg for address 0x%08x", addr);
813 
814  return ret;
815 }
816 
817 static int mspm0_address_check(struct flash_bank *bank, unsigned int addr)
818 {
819  struct mspm0_flash_bank *mspm0_info = bank->driver_priv;
820  unsigned int flash_main_size = mspm0_info->main_flash_size_kb * 1024;
821  unsigned int flash_data_size = mspm0_info->data_flash_size_kb * 1024;
822  int ret = ERROR_FLASH_SECTOR_INVALID;
823 
824  /*
825  * Before unprotecting any memory lets make sure that the address and
826  * bank given is a known bank and whether or not the address falls under
827  * the proper bank.
828  */
829  switch (bank->base) {
831  if (addr <= (MSPM0_FLASH_BASE_MAIN + flash_main_size))
832  ret = ERROR_OK;
833  break;
836  ret = ERROR_OK;
837  break;
839  if (addr >= MSPM0_FLASH_BASE_DATA &&
840  addr <= (MSPM0_FLASH_BASE_DATA + flash_data_size))
841  ret = ERROR_OK;
842  break;
843  default:
845  break;
846  }
847 
848  return ret;
849 }
850 
851 static int mspm0_fctl_unprotect_sector(struct flash_bank *bank, unsigned int addr)
852 {
853  struct target *target = bank->target;
854  unsigned int reg = 0x0;
855  uint32_t sector_mask = 0x0;
856  int ret;
857 
858  ret = mspm0_address_check(bank, addr);
859  switch (ret) {
861  LOG_ERROR("Unable to map sector protect reg for address 0x%08x", addr);
862  break;
864  LOG_ERROR("Unable to determine which bank to use 0x%08x", addr);
865  break;
866  default:
867  mspm0_fctl_get_sector_reg(bank, addr, &reg, &sector_mask);
868  ret = target_write_u32(target, reg, ~sector_mask);
869  break;
870  }
871 
872  return ret;
873 }
874 
876  uint32_t addr,
877  uint32_t cmd,
878  uint32_t byte_en)
879 {
880  struct target *target = bank->target;
881 
882  /*
883  * Configure the flash operation within the CMDTYPE register, byte_en
884  * bits if needed, and then set the address where the flash operation
885  * will execute.
886  */
888  if (retval != ERROR_OK)
889  return retval;
890  if (byte_en != 0) {
891  retval = target_write_u32(target, FCTL_REG_CMDBYTEN, byte_en);
892  if (retval != ERROR_OK)
893  return retval;
894  }
895 
897 }
898 
900 {
901  struct target *target = bank->target;
902  uint32_t return_code = 0;
903  int64_t start_ms;
904  int64_t elapsed_ms;
905 
906  start_ms = timeval_ms();
907  while ((return_code & FCTL_STATCMD_CMDDONE_MASK) != FCTL_STATCMD_CMDDONE_STATDONE) {
908  int retval = target_read_u32(target, FCTL_REG_STATCMD, &return_code);
909  if (retval != ERROR_OK)
910  return retval;
911 
912  elapsed_ms = timeval_ms() - start_ms;
913  if (elapsed_ms > MSPM0_FLASH_TIMEOUT_MS)
914  break;
915 
916  keep_alive();
917  }
918 
920  LOG_ERROR("Flash command failed: %s", mspm0_fctl_translate_ret_err(return_code));
921  return ERROR_FAIL;
922  }
923 
924  return ERROR_OK;
925 }
926 
927 static int mspm0_fctl_sector_erase(struct flash_bank *bank, uint32_t addr)
928 {
929  struct target *target = bank->target;
930 
931  /*
932  * TRM Says:
933  * Note that the CMDWEPROTx registers are reset to a protected state
934  * at the end of all program and erase operations. These registers
935  * must be re-configured by software before a new operation is
936  * initiated.
937  *
938  * This means that as we start erasing sector by sector, the protection
939  * registers are reset and need to be unprotected *again* for the next
940  * erase operation. Unfortunately, this means that we cannot do a unitary
941  * unprotect operation independent of flash erase operation
942  */
943  int retval = mspm0_fctl_unprotect_sector(bank, addr);
944  if (retval != ERROR_OK) {
945  LOG_ERROR("Unprotecting sector of memory at address 0x%08" PRIx32
946  " failed", addr);
947  return retval;
948  }
949 
950  /* Actual erase operation */
951  retval = mspm0_fctl_cfg_command(bank, addr,
953  if (retval != ERROR_OK)
954  return retval;
956  if (retval != ERROR_OK)
957  return retval;
958 
960 }
961 
963 {
964  struct mspm0_flash_bank *mspm0_info = bank->driver_priv;
965 
966  if (mspm0_info->did == 0)
968 
969  /*
970  * TRM Says:
971  * Note that the CMDWEPROTx registers are reset to a protected state
972  * at the end of all program and erase operations. These registers
973  * must be re-configured by software before a new operation is
974  * initiated.
975  *
976  * This means that when any flash operation is performed at a block level,
977  * the block is locked back again. This prevents usage where we can set a
978  * protection level once at the flash level and then do erase / write
979  * operation without touching the protection register (since it is
980  * reset by hardware automatically). In effect, we cannot use the hardware
981  * defined protection scheme in openOCD.
982  *
983  * To deal with this protection scheme, the CMDWEPROTx register that
984  * correlates to the sector is modified at the time of operation and as far
985  * openOCD is concerned, the flash operates as completely un-protected
986  * flash.
987  */
988  for (unsigned int i = 0; i < bank->num_sectors; i++)
989  bank->sectors[i].is_protected = 0;
990 
991  return ERROR_OK;
992 }
993 
994 static int mspm0_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
995 {
996  struct target *target = bank->target;
997  struct mspm0_flash_bank *mspm0_info = bank->driver_priv;
998  int retval = ERROR_OK;
999  uint32_t protect_reg_cache[MSPM0_MAX_PROTREGS];
1000 
1001  if (bank->target->state != TARGET_HALTED) {
1002  LOG_ERROR("Please halt target for erasing flash");
1003  return ERROR_TARGET_NOT_HALTED;
1004  }
1005 
1006  if (mspm0_info->did == 0)
1008 
1009  /* Pick a copy of the current protection config for later restoration */
1010  for (unsigned int i = 0; i < mspm0_info->protect_reg_count; i++) {
1011  retval = target_read_u32(target,
1012  mspm0_info->protect_reg_base + (i * 4),
1013  &protect_reg_cache[i]);
1014  if (retval != ERROR_OK) {
1015  LOG_ERROR("Failed saving flashctl protection status");
1016  return retval;
1017  }
1018  }
1019 
1020  switch (bank->base) {
1021  case MSPM0_FLASH_BASE_MAIN:
1022  for (unsigned int csa = first; csa <= last; csa++) {
1023  unsigned int addr = csa * mspm0_info->sector_size;
1024  retval = mspm0_fctl_sector_erase(bank, addr);
1025  if (retval != ERROR_OK)
1026  LOG_ERROR("Sector erase on MAIN failed at address 0x%08x "
1027  "(sector: %u)", addr, csa);
1028  }
1029  break;
1032  if (retval != ERROR_OK)
1033  LOG_ERROR("Sector erase on NONMAIN failed");
1034  break;
1035  case MSPM0_FLASH_BASE_DATA:
1036  for (unsigned int csa = first; csa <= last; csa++) {
1037  unsigned int addr = (MSPM0_FLASH_BASE_DATA +
1038  (csa * mspm0_info->sector_size));
1039  retval = mspm0_fctl_sector_erase(bank, addr);
1040  if (retval != ERROR_OK)
1041  LOG_ERROR("Sector erase on DATA bank failed at address 0x%08x "
1042  "(sector: %u)", addr, csa);
1043  }
1044  break;
1045  default:
1046  LOG_ERROR("Invalid memory region access");
1047  retval = ERROR_FLASH_BANK_INVALID;
1048  break;
1049  }
1050 
1051  /* If there were any issues in our checks, return the error */
1052  if (retval != ERROR_OK)
1053  return retval;
1054 
1055  /*
1056  * TRM Says:
1057  * Note that the CMDWEPROTx registers are reset to a protected state
1058  * at the end of all program and erase operations. These registers
1059  * must be re-configured by software before a new operation is
1060  * initiated
1061  * Let us just Dump the protection registers back to the system.
1062  * That way we retain the protection status as requested by the user
1063  */
1064  for (unsigned int i = 0; i < mspm0_info->protect_reg_count; i++) {
1065  retval = target_write_u32(target, mspm0_info->protect_reg_base + (i * 4),
1066  protect_reg_cache[i]);
1067  if (retval != ERROR_OK) {
1068  LOG_ERROR("Failed re-applying protection status of flashctl");
1069  return retval;
1070  }
1071  }
1072 
1073  return retval;
1074 }
1075 
1076 static int mspm0_write(struct flash_bank *bank, const unsigned char *buffer,
1077  unsigned int offset, unsigned int count)
1078 {
1079  struct target *target = bank->target;
1080  struct mspm0_flash_bank *mspm0_info = bank->driver_priv;
1081  uint32_t protect_reg_cache[MSPM0_MAX_PROTREGS];
1082  int retval;
1083 
1084  /*
1085  * XXX: TRM Says:
1086  * The number of program operations applied to a given word line must be
1087  * monitored to ensure that the maximum word line program limit before
1088  * erase is not violated.
1089  *
1090  * There is no reasonable way we can maintain that state in OpenOCD. So,
1091  * Let the manufacturing path figure this out.
1092  */
1093 
1094  if (bank->target->state != TARGET_HALTED) {
1095  LOG_ERROR("Please halt target for programming flash");
1096  return ERROR_TARGET_NOT_HALTED;
1097  }
1098 
1099  if (mspm0_info->did == 0)
1101 
1102  /*
1103  * Pick a copy of the current protection config for later restoration
1104  * We need to restore these regs after every write, so instead of trying
1105  * to figure things out on the fly, we just context save and restore
1106  */
1107  for (unsigned int i = 0; i < mspm0_info->protect_reg_count; i++) {
1108  retval = target_read_u32(target,
1109  mspm0_info->protect_reg_base + (i * 4),
1110  &protect_reg_cache[i]);
1111  if (retval != ERROR_OK) {
1112  LOG_ERROR("Failed saving flashctl protection status");
1113  return retval;
1114  }
1115  }
1116 
1117  /* Add proper memory offset for bank being written to */
1118  unsigned int addr = bank->base + offset;
1119 
1120  while (count) {
1121  unsigned int num_bytes_to_write;
1122  uint32_t bytes_en;
1123 
1124  /*
1125  * If count is not 64 bit aligned, we will do byte wise op to keep things simple
1126  * Usually this might mean we need to additional write ops towards
1127  * trailing edge, but that is a tiny penalty for image downloads.
1128  * NOTE: we are going to assume the device does not support multi-word
1129  * programming - there does not seem to be discoverability!
1130  */
1131  if (count < mspm0_info->flash_word_size_bytes)
1132  num_bytes_to_write = count;
1133  else
1134  num_bytes_to_write = mspm0_info->flash_word_size_bytes;
1135 
1136  /* Data bytes to write */
1137  bytes_en = (1 << num_bytes_to_write) - 1;
1138  /* ECC chunks to write */
1139  switch (mspm0_info->flash_word_size_bytes) {
1140  case 8:
1141  bytes_en |= BIT(8);
1142  break;
1143  case 16:
1144  bytes_en |= BIT(16);
1145  bytes_en |= (num_bytes_to_write > 8) ? BIT(17) : 0;
1146  break;
1147  default:
1148  LOG_ERROR("Invalid flash_word_size_bytes %d",
1149  mspm0_info->flash_word_size_bytes);
1150  return ERROR_FAIL;
1151  }
1152 
1153  retval = mspm0_fctl_cfg_command(bank, addr,
1155  bytes_en);
1156  if (retval != ERROR_OK)
1157  return retval;
1158 
1160  if (retval != ERROR_OK)
1161  return retval;
1162 
1163  retval = target_write_buffer(target, FCTL_REG_CMDDATA0, num_bytes_to_write, buffer);
1164  if (retval != ERROR_OK)
1165  return retval;
1166 
1167  addr += num_bytes_to_write;
1168  buffer += num_bytes_to_write;
1169  count -= num_bytes_to_write;
1170 
1172  if (retval != ERROR_OK)
1173  return retval;
1174 
1175  retval = mspm0_fctl_wait_cmd_ok(bank);
1176  if (retval != ERROR_OK)
1177  return retval;
1178  }
1179 
1180  /*
1181  * TRM Says:
1182  * Note that the CMDWEPROTx registers are reset to a protected state
1183  * at the end of all program and erase operations. These registers
1184  * must be re-configured by software before a new operation is
1185  * initiated
1186  * Let us just Dump the protection registers back to the system.
1187  * That way we retain the protection status as requested by the user
1188  */
1189  for (unsigned int i = 0; i < mspm0_info->protect_reg_count; i++) {
1190  retval = target_write_u32(target,
1191  mspm0_info->protect_reg_base + (i * 4),
1192  protect_reg_cache[i]);
1193  if (retval != ERROR_OK) {
1194  LOG_ERROR("Failed re-applying protection status of flashctl");
1195  return retval;
1196  }
1197  }
1198 
1199  return ERROR_OK;
1200 }
1201 
1202 static int mspm0_probe(struct flash_bank *bank)
1203 {
1204  struct mspm0_flash_bank *mspm0_info = bank->driver_priv;
1205 
1206  /*
1207  * If this is a mspm0 chip, it has flash; probe() is just
1208  * to figure out how much is present. Only do it once.
1209  */
1210  if (mspm0_info->did != 0)
1211  return ERROR_OK;
1212 
1213  /*
1214  * mspm0_read_part_info() already handled error checking and
1215  * reporting. Note that it doesn't write, so we don't care about
1216  * whether the target is halted or not.
1217  */
1218  int retval = mspm0_read_part_info(bank);
1219  if (retval != ERROR_OK)
1220  return retval;
1221 
1222  if (bank->sectors) {
1223  free(bank->sectors);
1224  bank->sectors = NULL;
1225  }
1226 
1227  bank->write_start_alignment = 4;
1228  bank->write_end_alignment = 4;
1229 
1230  switch (bank->base) {
1232  bank->size = 1024;
1233  bank->num_sectors = 0x1;
1234  mspm0_info->protect_reg_base = FCTL_REG_CMDWEPROTNM;
1235  mspm0_info->protect_reg_count = 1;
1236  break;
1237  case MSPM0_FLASH_BASE_MAIN:
1238  if (!mspm0_info->main_flash_size_kb) {
1239  /*
1240  * FACTORYREGION was unreadable when this bank was probed
1241  * (e.g. device not yet halted, MCLK still at HSCLK on
1242  * first examine). Clear did so the next auto_probe call
1243  * re-runs mspm0_read_part_info with the target in a known
1244  * state.
1245  */
1246  LOG_WARNING("MSPM0: main flash size is 0 — "
1247  "FACTORYREGION data incomplete, scheduling re-probe");
1248  mspm0_info->did = 0;
1250  }
1251  bank->size = (mspm0_info->main_flash_size_kb * 1024);
1252  bank->num_sectors = bank->size / mspm0_info->sector_size;
1253  /*
1254  * If the feature version bit read from the FCTL_REG_DESC is
1255  * greater than or equal to 0xA then it means that the device
1256  * will exclusively use CMDWEPROTB ONLY for MAIN memory protection
1257  */
1258  if (mspm0_info->flash_version >= FCTL_FEATURE_VER_B) {
1259  mspm0_info->protect_reg_base = FCTL_REG_CMDWEPROTB;
1260  mspm0_info->protect_reg_count = 1;
1261  } else {
1262  mspm0_info->protect_reg_base = FCTL_REG_CMDWEPROTA;
1263  mspm0_info->protect_reg_count = 3;
1264  }
1265  break;
1266  case MSPM0_FLASH_BASE_DATA:
1267  if (!mspm0_info->data_flash_size_kb) {
1268  LOG_INFO("Data region NOT available!");
1269  bank->size = 0x0;
1270  bank->num_sectors = 0x0;
1271  return ERROR_OK;
1272  }
1273  /*
1274  * Any MSPM0 device containing data bank will have a flashctl
1275  * feature version of 0xA or higher. Since data bank is treated
1276  * like MAIN memory, it will also exclusively use CMDWEPROTB for
1277  * protection.
1278  */
1279  bank->size = (mspm0_info->data_flash_size_kb * 1024);
1280  bank->num_sectors = bank->size / mspm0_info->sector_size;
1281  mspm0_info->protect_reg_base = FCTL_REG_CMDWEPROTB;
1282  mspm0_info->protect_reg_count = 1;
1283  break;
1284  default:
1285  LOG_ERROR("Invalid bank address " TARGET_ADDR_FMT,
1286  bank->base);
1287  return ERROR_FAIL;
1288  }
1289 
1290  bank->sectors = calloc(bank->num_sectors, sizeof(struct flash_sector));
1291  if (!bank->sectors) {
1292  LOG_ERROR("Out of memory for sectors!");
1293  return ERROR_FAIL;
1294  }
1295  for (unsigned int i = 0; i < bank->num_sectors; i++) {
1296  bank->sectors[i].offset = i * mspm0_info->sector_size;
1297  bank->sectors[i].size = mspm0_info->sector_size;
1298  bank->sectors[i].is_erased = -1;
1299  }
1300 
1301  return ERROR_OK;
1302 }
1303 
1304 const struct flash_driver mspm0_flash = {
1305  .name = "mspm0",
1306  .flash_bank_command = mspm0_flash_bank_command,
1307  .erase = mspm0_erase,
1308  .protect = NULL,
1309  .write = mspm0_write,
1310  .read = default_flash_read,
1311  .probe = mspm0_probe,
1312  .auto_probe = mspm0_probe,
1313  .erase_check = default_flash_blank_check,
1314  .protect_check = mspm0_protect_check,
1315  .info = get_mspm0_info,
1316  .free_driver_priv = default_flash_free_driver_priv,
1317 };
#define GENMASK(h, l)
Definition: bits.h:24
void command_print_sameline(struct command_invocation *cmd, const char *format,...)
Definition: command.c:378
uint64_t buffer
Pointer to data buffer to send over SPI.
Definition: dw-spi-helper.h:0
uint8_t bank
Definition: esirisc.c:135
#define ERROR_FLASH_BANK_INVALID
Definition: flash/common.h:28
#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_OUT_OF_BANK
Definition: flash/common.h:31
int default_flash_blank_check(struct flash_bank *bank)
Provides default erased-bank check handling.
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.
void alive_sleep(uint64_t ms)
Definition: log.c:478
void keep_alive(void)
Definition: log.c:437
#define LOG_WARNING(expr ...)
Definition: log.h:144
#define ERROR_FAIL
Definition: log.h:188
#define LOG_ERROR(expr ...)
Definition: log.h:147
#define LOG_INFO(expr ...)
Definition: log.h:141
#define LOG_DEBUG(expr ...)
Definition: log.h:124
#define ERROR_OK
Definition: log.h:182
#define FCTL_CMDEXEC_VAL_EXECUTE
Definition: mspm0.c:58
static int mspm0_fctl_wait_cmd_ok(struct flash_bank *bank)
Definition: mspm0.c:899
#define MSPM0_DEV_PART_ID_FOUND
Definition: mspm0.c:100
static const struct mspm0_part_info mspm0g_parts_bb88[]
Definition: mspm0.c:208
#define FCTL_CMDTYPE_SIZE_SECTOR
Definition: mspm0.c:66
#define FCTL_REG_STATCMD
Definition: mspm0.c:44
#define MSPM0_FLASH_TIMEOUT_MS
Definition: mspm0.c:73
#define FCTL_STATCMD_CMDDONE_MASK
Definition: mspm0.c:47
static const char * mspm0_fctl_translate_ret_err(unsigned int return_code)
Definition: mspm0.c:717
#define MSPM0_DID
Definition: mspm0.c:29
#define MSPM0_FLASH_BASE_MAIN
Definition: mspm0.c:23
#define FCTL_REG_CMDTYPE
Definition: mspm0.c:37
#define SYSCTL_MCLKCFG_USEHSCLK
Definition: mspm0.c:90
static int get_mspm0_info(struct flash_bank *bank, struct command_invocation *cmd)
Definition: mspm0.c:458
static int mspm0_write(struct flash_bank *bank, const unsigned char *buffer, unsigned int offset, unsigned int count)
Definition: mspm0.c:1076
static const struct mspm0_part_info mspm0lx22x_parts[]
Definition: mspm0.c:387
const struct flash_driver mspm0_flash
Definition: mspm0.c:1304
static unsigned int mspm0_extract_val(unsigned int var, unsigned char hi, unsigned char lo)
Definition: mspm0.c:480
#define FCTL_REG_DESC
Definition: mspm0.c:35
#define MSPM0_MAX_PROTREGS
Definition: mspm0.c:71
#define FCTL_REG_CMDBYTEN
Definition: mspm0.c:39
#define MSPM0_USERID
Definition: mspm0.c:30
#define FCTL_STATCMD_CMDPASS_MASK
Definition: mspm0.c:51
static int mspm0_fctl_get_sector_reg(struct flash_bank *bank, unsigned int addr, unsigned int *reg, unsigned int *sector_mask)
Definition: mspm0.c:728
static const struct mspm0_family_info mspm0_finf[]
Definition: mspm0.c:412
#define MSPM0_FLASH_END_NONMAIN
Definition: mspm0.c:22
static const struct mspm0_part_info mspm0l_parts[]
Definition: mspm0.c:144
const unsigned char bit_offset
Definition: mspm0.c:706
static int mspm0_fctl_unprotect_sector(struct flash_bank *bank, unsigned int addr)
Definition: mspm0.c:851
#define SYSCTL_MCLKCFG_FLASHWAIT_MASK
Definition: mspm0.c:91
#define MSPM0_TRACEID
Definition: mspm0.c:28
static int mspm0_fctl_cfg_command(struct flash_bank *bank, uint32_t addr, uint32_t cmd, uint32_t byte_en)
Definition: mspm0.c:875
static int mspm0_protect_check(struct flash_bank *bank)
Definition: mspm0.c:962
#define FCTL_REG_CMDADDR
Definition: mspm0.c:38
static const struct mspm0_part_info mspm0g_parts_bba9[]
Definition: mspm0.c:315
#define FCTL_REG_CMDWEPROTB
Definition: mspm0.c:42
#define FCTL_CMDTYPE_COMMAND_ERASE
Definition: mspm0.c:62
#define FCTL_REG_CMDEXEC
Definition: mspm0.c:36
FLASH_BANK_COMMAND_HANDLER(mspm0_flash_bank_command)
Definition: mspm0.c:428
#define SYSCTL_MCLKCFG_FLASHWAIT_2
Definition: mspm0.c:92
static const struct mspm0_part_info mspm0c_parts[]
Definition: mspm0.c:377
#define MSPM0_NO_ID_FOUND
Definition: mspm0.c:98
#define TI_MANUFACTURER_ID
Definition: mspm0.c:95
#define MSPM0_FLASH_BASE_DATA
Definition: mspm0.c:24
const char * fail_string
Definition: mspm0.c:707
#define FCTL_FEATURE_VER_B
Definition: mspm0.c:69
static const struct mspm0_part_info mspm0g_parts_bbbc[]
Definition: mspm0.c:364
#define FCTL_STATCMD_CMDPASS_STATPASS
Definition: mspm0.c:52
#define FCTL_STATCMD_CMDDONE_STATDONE
Definition: mspm0.c:48
static const struct @12 mspm0_fctl_fail_decode_strings[]
static int mspm0_probe(struct flash_bank *bank)
Definition: mspm0.c:1202
#define SYSCTL_MCLKCFG
Definition: mspm0.c:89
#define MSPM0_SRAMFLASH
Definition: mspm0.c:31
#define FCTL_REG_CMDWEPROTA
Definition: mspm0.c:41
#define MSPM0_FLASH_BASE_NONMAIN
Definition: mspm0.c:21
#define MSPM0_DEV_ID_FOUND
Definition: mspm0.c:99
static int mspm0_read_part_info(struct flash_bank *bank)
Definition: mspm0.c:485
#define SYSCTL_SECCFG_SECSTATUS
Definition: mspm0.c:78
#define FCTL_CMDTYPE_SIZE_ONEWORD
Definition: mspm0.c:65
static int mspm0_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
Definition: mspm0.c:994
static int mspm0_address_check(struct flash_bank *bank, unsigned int addr)
Definition: mspm0.c:817
#define FCTL_CMDTYPE_COMMAND_PROGRAM
Definition: mspm0.c:61
#define FCTL_REG_CMDWEPROTNM
Definition: mspm0.c:43
static int mspm0_fctl_sector_erase(struct flash_bank *bank, uint32_t addr)
Definition: mspm0.c:927
#define FCTL_REG_CMDDATA0
Definition: mspm0.c:40
target_addr_t addr
Start address to search for the control block.
Definition: rtt/rtt.c:28
#define BIT(nr)
Definition: stm32l4x.h:18
When run_command is called, a new instance will be created on the stack, filled with the proper value...
Definition: command.h:76
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 * family_name
Definition: mspm0.c:137
unsigned short part_num
Definition: mspm0.c:138
const struct mspm0_part_info * part_info
Definition: mspm0.c:140
unsigned char part_count
Definition: mspm0.c:139
unsigned int main_flash_num_banks
Definition: mspm0.c:114
unsigned int protect_reg_base
Definition: mspm0.c:123
unsigned int data_flash_size_kb
Definition: mspm0.c:112
uint32_t traceid
Definition: mspm0.c:106
unsigned int protect_reg_count
Definition: mspm0.c:124
unsigned int main_flash_size_kb
Definition: mspm0.c:113
uint32_t did
Definition: mspm0.c:104
unsigned char flash_version
Definition: mspm0.c:127
unsigned int sram_size_kb
Definition: mspm0.c:117
unsigned int sector_size
Definition: mspm0.c:115
unsigned char version
Definition: mspm0.c:107
const char * name
Definition: mspm0.c:109
unsigned char flash_word_size_bytes
Definition: mspm0.c:120
unsigned char variant
Definition: mspm0.c:133
unsigned short part
Definition: mspm0.c:132
const char * part_name
Definition: mspm0.c:131
Definition: register.h:111
Definition: target.h:119
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
Definition: target.c:2405
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
Definition: target.c:2671
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
Definition: target.c:2597
#define ERROR_TARGET_NOT_HALTED
Definition: target.h:817
@ TARGET_HALTED
Definition: target.h:58
int64_t timeval_ms(void)
#define TARGET_ADDR_FMT
Definition: types.h:286
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.
Definition: types.h:57
#define NULL
Definition: usb.h:16
uint8_t cmd
Definition: vdebug.c:1
uint8_t offset[4]
Definition: vdebug.c:9
uint8_t dummy[96]
Definition: vdebug.c:23
uint8_t count[4]
Definition: vdebug.c:22