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 /* TI manufacturer ID */
81 #define TI_MANUFACTURER_ID 0x17
82 
83 /* Defines for probe status */
84 #define MSPM0_NO_ID_FOUND 0
85 #define MSPM0_DEV_ID_FOUND 1
86 #define MSPM0_DEV_PART_ID_FOUND 2
87 
89  /* chip id register */
90  uint32_t did;
91  /* Device Unique ID register */
92  uint32_t traceid;
93  unsigned char version;
94 
95  const char *name;
96 
97  /* Decoded flash information */
98  unsigned int data_flash_size_kb;
99  unsigned int main_flash_size_kb;
100  unsigned int main_flash_num_banks;
101  unsigned int sector_size;
102  /* Decoded SRAM information */
103  unsigned int sram_size_kb;
104 
105  /* Flash word size: 64 bit = 8, 128bit = 16 bytes */
106  unsigned char flash_word_size_bytes;
107 
108  /* Protection register stuff */
109  unsigned int protect_reg_base;
110  unsigned int protect_reg_count;
111 
112  /* Flashctl version: A - CMDWEPROTA/B, B- CMDWEPROTB */
113  unsigned char flash_version;
114 };
115 
117  const char *part_name;
118  unsigned short part;
119  unsigned char variant;
120 };
121 
123  const char *family_name;
124  unsigned short part_num;
125  unsigned char part_count;
126  const struct mspm0_part_info *part_info;
127 };
128 
129 /* https://www.ti.com/lit/ds/symlink/mspm0l1346.pdf Table 8-13 and so on */
130 static const struct mspm0_part_info mspm0l_parts[] = {
131  { "MSPM0L1105TDGS20R", 0x51DB, 0x16 },
132  { "MSPM0L1105TDGS28R", 0x51DB, 0x83 },
133  { "MSPM0L1105TDYYR", 0x51DB, 0x54 },
134  { "MSPM0L1105TRGER", 0x51DB, 0x86 },
135  { "MSPM0L1105TRHBR", 0x51DB, 0x68 },
136  { "MSPM0L1106TDGS20R", 0x5552, 0x4B },
137  { "MSPM0L1106TDGS28R", 0x5552, 0x98 },
138  { "MSPM0L1106TDYYR", 0x5552, 0x9D },
139  { "MSPM0L1106TRGER", 0x5552, 0x90 },
140  { "MSPM0L1106TRHBR", 0x5552, 0x53 },
141  { "MSPM0L1303SRGER", 0xef0, 0x17 },
142  { "MSPM0L1303TRGER", 0xef0, 0xe2 },
143  { "MSPM0L1304QDGS20R", 0xd717, 0x91 },
144  { "MSPM0L1304QDGS28R", 0xd717, 0xb6 },
145  { "MSPM0L1304QDYYR", 0xd717, 0xa0 },
146  { "MSPM0L1304QRHBR", 0xd717, 0xa9 },
147  { "MSPM0L1304SDGS20R", 0xd717, 0xfa },
148  { "MSPM0L1304SDGS28R", 0xd717, 0x73 },
149  { "MSPM0L1304SDYYR", 0xd717, 0xb7 },
150  { "MSPM0L1304SRGER", 0xd717, 0x26 },
151  { "MSPM0L1304SRHBR", 0xd717, 0xe4 },
152  { "MSPM0L1304TDGS20R", 0xd717, 0x33 },
153  { "MSPM0L1304TDGS28R", 0xd717, 0xa8 },
154  { "MSPM0L1304TDYYR", 0xd717, 0xf9 },
155  { "MSPM0L1304TRGER", 0xd717, 0xb7 },
156  { "MSPM0L1304TRHBR", 0xd717, 0x5a },
157  { "MSPM0L1305QDGS20R", 0x4d03, 0xb7 },
158  { "MSPM0L1305QDGS28R", 0x4d03, 0x74 },
159  { "MSPM0L1305QDYYR", 0x4d03, 0xec },
160  { "MSPM0L1305QRHBR", 0x4d03, 0x78 },
161  { "MSPM0L1305SDGS20R", 0x4d03, 0xc7 },
162  { "MSPM0L1305SDGS28R", 0x4d03, 0x64 },
163  { "MSPM0L1305SDYYR", 0x4d03, 0x91 },
164  { "MSPM0L1305SRGER", 0x4d03, 0x73 },
165  { "MSPM0L1305SRHBR", 0x4d03, 0x2d },
166  { "MSPM0L1305TDGS20R", 0x4d03, 0xa0 },
167  { "MSPM0L1305TDGS28R", 0x4d03, 0xfb },
168  { "MSPM0L1305TDYYR", 0x4d03, 0xde },
169  { "MSPM0L1305TRGER", 0x4d03, 0xea },
170  { "MSPM0L1305TRHBR", 0x4d03, 0x85 },
171  { "MSPM0L1306QDGS20R", 0xbb70, 0x59 },
172  { "MSPM0L1306QDGS28R", 0xbb70, 0xf7 },
173  { "MSPM0L1306QDYYR", 0xbb70, 0x9f },
174  { "MSPM0L1306QRHBR", 0xbb70, 0xc2 },
175  { "MSPM0L1306SDGS20R", 0xbb70, 0xf4 },
176  { "MSPM0L1306SDGS28R", 0xbb70, 0x5 },
177  { "MSPM0L1306SDYYR", 0xbb70, 0xe },
178  { "MSPM0L1306SRGER", 0xbb70, 0x7f },
179  { "MSPM0L1306SRHBR", 0xbb70, 0x3c },
180  { "MSPM0L1306TDGS20R", 0xbb70, 0xa },
181  { "MSPM0L1306TDGS28R", 0xbb70, 0x63 },
182  { "MSPM0L1306TDYYR", 0xbb70, 0x35 },
183  { "MSPM0L1306TRGER", 0xbb70, 0xaa },
184  { "MSPM0L1306TRHBR", 0xbb70, 0x52 },
185  { "MSPM0L1343TDGS20R", 0xb231, 0x2e },
186  { "MSPM0L1344TDGS20R", 0x40b0, 0xd0 },
187  { "MSPM0L1345TDGS28R", 0x98b4, 0x74 },
188  { "MSPM0L1346TDGS28R", 0xf2b5, 0xef },
189 };
190 
191 /* https://www.ti.com/lit/ds/symlink/mspm0g3506.pdf Table 8-20 */
192 static const struct mspm0_part_info mspm0g_parts[] = {
193  { "MSPM0G1105TPTR", 0x8934, 0xD },
194  { "MSPM0G1105TRGZR", 0x8934, 0xFE },
195  { "MSPM0G1106TPMR", 0x477B, 0xD4 },
196  { "MSPM0G1106TPTR", 0x477B, 0x71 },
197  { "MSPM0G1106TRGZR", 0x477B, 0xBB },
198  { "MSPM0G1106TRHBR", 0x477B, 0x0 },
199  { "MSPM0G1107TDGS28R", 0x807B, 0x82 },
200  { "MSPM0G1107TPMR", 0x807B, 0xB3 },
201  { "MSPM0G1107TPTR", 0x807B, 0x32 },
202  { "MSPM0G1107TRGER", 0x807B, 0x79 },
203  { "MSPM0G1107TRGZR", 0x807B, 0x20 },
204  { "MSPM0G1107TRHBR", 0x807B, 0xBC },
205  { "MSPM0G1505SDGS28R", 0x13C4, 0x73 },
206  { "MSPM0G1505SPMR", 0x13C4, 0x53 },
207  { "MSPM0G1505SPTR", 0x13C4, 0x3E },
208  { "MSPM0G1505SRGER", 0x13C4, 0x47 },
209  { "MSPM0G1505SRGZR", 0x13C4, 0x34 },
210  { "MSPM0G1505SRHBR", 0x13C4, 0x30 },
211  { "MSPM0G1506SDGS28R", 0x5AE0, 0x3A },
212  { "MSPM0G1506SPMR", 0x5AE0, 0xF6 },
213  { "MSPM0G1506SRGER", 0x5AE0, 0x67 },
214  { "MSPM0G1506SRGZR", 0x5AE0, 0x75 },
215  { "MSPM0G1506SRHBR", 0x5AE0, 0x57 },
216  { "MSPM0G1507SDGS28R", 0x2655, 0x6D },
217  { "MSPM0G1507SPMR", 0x2655, 0x97 },
218  { "MSPM0G1507SRGER", 0x2655, 0x83 },
219  { "MSPM0G1507SRGZR", 0x2655, 0xD3 },
220  { "MSPM0G1507SRHBR", 0x2655, 0x4D },
221  { "MSPM0G3105SDGS20R", 0x4749, 0x21 },
222  { "MSPM0G3105SDGS28R", 0x4749, 0xDD },
223  { "MSPM0G3105SRHBR", 0x4749, 0xBE },
224  { "MSPM0G3106SDGS20R", 0x54C7, 0xD2 },
225  { "MSPM0G3106SDGS28R", 0x54C7, 0xB9 },
226  { "MSPM0G3106SRHBR", 0x54C7, 0x67 },
227  { "MSPM0G3107SDGS20R", 0xAB39, 0x5C },
228  { "MSPM0G3107SDGS28R", 0xAB39, 0xCC },
229  { "MSPM0G3107SRHBR", 0xAB39, 0xB7 },
230  { "MSPM0G3505SDGS28R", 0xc504, 0x8e },
231  { "MSPM0G3505SPMR", 0xc504, 0x1d },
232  { "MSPM0G3505SPTR", 0xc504, 0x93 },
233  { "MSPM0G3505SRGZR", 0xc504, 0xc7 },
234  { "MSPM0G3505SRHBR", 0xc504, 0xe7 },
235  { "MSPM0G3505TDGS28R", 0xc504, 0xdf },
236  { "MSPM0G3506SDGS28R", 0x151f, 0x8 },
237  { "MSPM0G3506SPMR", 0x151f, 0xd4 },
238  { "MSPM0G3506SPTR", 0x151f, 0x39 },
239  { "MSPM0G3506SRGZR", 0x151f, 0xfe },
240  { "MSPM0G3506SRHBR", 0x151f, 0xb5 },
241  { "MSPM0G3507SDGS28R", 0xae2d, 0xca },
242  { "MSPM0G3507SPMR", 0xae2d, 0xc7 },
243  { "MSPM0G3507SPTR", 0xae2d, 0x3f },
244  { "MSPM0G3507SRGZR", 0xae2d, 0xf7 },
245  { "MSPM0G3507SRHBR", 0xae2d, 0x4c },
246  { "M0G3107QPMRQ1", 0x4e2f, 0x51 },
247  { "M0G3107QPTRQ1", 0x4e2f, 0xc7},
248  { "M0G3107QRGZRQ1", 0x4e2f, 0x8a },
249  { "M0G3107QRHBRQ1", 0x4e2f, 0x9a},
250  { "M0G3107QDGS28RQ1", 0x4e2f, 0xd5},
251  { "M0G3107QDGS28RQ1", 0x4e2f, 0x67},
252  { "M0G3107QDGS20RQ1", 0x4e2f, 0xfd},
253  { "M0G3106QPMRQ1", 0x54C7, 0x08},
254  { "M0G3105QDGS32RQ1", 0x1349, 0x08},
255  { "M0G3106QPTRQ1", 0x54C7, 0x3F},
256  { "M0G3105QDGS28RQ1", 0x1349, 0x1B},
257  { "M0G3106QRGZRQ1", 0x94AD, 0xE6},
258  { "M0G3105QDGS20RQ1", 0x1349, 0xFB},
259  { "M0G3106QRHBRQ1", 0x94AD, 0x20},
260  { "M0G3106QDGS32RQ1", 0x94AD, 0x8D},
261  { "M0G3106QDGS28RQ1", 0x94AD, 0x03},
262  { "M0G3106QDGS20RQ1", 0x94AD, 0x6F},
263  { "M0G3105QPMRQ1", 0x1349, 0xD0},
264  { "M0G3105QPTRQ1", 0x1349, 0xEF},
265  { "M0G3105QRGZRQ1", 0x1349, 0x70},
266  { "M0G3105QRHBRQ1", 0x1349, 0x01},
267 };
268 
269 /* https://www.ti.com/lit/gpn/mspm0c1104 Table 8-12 and so on */
270 static const struct mspm0_part_info mspm0c_parts[] = {
271  { "MSPS003F4SPW20R", 0x57b3, 0x70},
272  { "MSPM0C1104SDGS20R", 0x57b3, 0x71},
273  { "MSPM0C1104SRUKR", 0x57b3, 0x73},
274  { "MSPM0C1104SDYYR", 0x57b3, 0x75},
275  { "MSPM0C1104SDDFR", 0x57b3, 0x77},
276  { "MSPM0C1104SDSGR", 0x57b3, 0x79},
277 };
278 
279 /* https://www.ti.com/lit/gpn/MSPM0L2228 Table 8-16 and so on */
280 static const struct mspm0_part_info mspm0lx22x_parts[] = {
281  { "MSPM0L1227SRGER", 0x7C32, 0xF1},
282  { "MSPM0L1227SPTR", 0x7C32, 0xC9},
283  { "MSPM0L1227SPMR", 0x7C32, 0x1C},
284  { "MSPM0L1227SPNAR", 0x7C32, 0x91},
285  { "MSPM0L1227SPNR", 0x7C32, 0x39},
286  { "MSPM0L1228SRGER", 0x33F7, 0x13},
287  { "MSPM0L1228SRHBR", 0x33F7, 0x3A},
288  { "MSPM0L1228SRGZR", 0x33F7, 0xBC},
289  { "MSPM0L1228SPTR", 0x33F7, 0xF8},
290  { "MSPM0L1228SPMR", 0x33F7, 0xCE},
291  { "MSPM0L1228SPNAR", 0x33F7, 0x59},
292  { "MSPM0L1228SPNR", 0x33F7, 0x7},
293  { "MSPM0L2227SRGZR", 0x5E8F, 0x90},
294  { "MSPM0L2227SPTR", 0x5E8F, 0xA},
295  { "MSPM0L2227SPMR", 0x5E8F, 0x6D},
296  { "MSPM0L2227SPNAR", 0x5E8F, 0x24},
297  { "MSPM0L2227SPNR", 0x5E8F, 0x68},
298  { "MSPM0L2228SRGZR", 0x2C38, 0xB8},
299  { "MSPM0L2228SPTR", 0x2C38, 0x25},
300  { "MSPM0L2228SPMR", 0x2C38, 0x6E},
301  { "MSPM0L2228SPNAR", 0x2C38, 0x63},
302  { "MSPM0L2228SPNR", 0x2C38, 0x3C},
303 };
304 
305 static const struct mspm0_family_info mspm0_finf[] = {
306  { "MSPM0L", 0xbb82, ARRAY_SIZE(mspm0l_parts), mspm0l_parts },
307  { "MSPM0Lx22x", 0xbb9f, ARRAY_SIZE(mspm0lx22x_parts), mspm0lx22x_parts },
308  { "MSPM0G", 0xbb88, ARRAY_SIZE(mspm0g_parts), mspm0g_parts },
309  { "MSPM0C", 0xbba1, ARRAY_SIZE(mspm0c_parts), mspm0c_parts },
310 };
311 
312 /*
313  * OpenOCD command interface
314  */
315 
316 /*
317  * flash_bank mspm0 <base> <size> 0 0 <target#>
318  */
319 FLASH_BANK_COMMAND_HANDLER(mspm0_flash_bank_command)
320 {
321  struct mspm0_flash_bank *mspm0_info;
322 
323  switch (bank->base) {
327  break;
328  default:
329  LOG_ERROR("Invalid bank address " TARGET_ADDR_FMT, bank->base);
330  return ERROR_FAIL;
331  }
332 
333  mspm0_info = calloc(1, sizeof(struct mspm0_flash_bank));
334  if (!mspm0_info) {
335  LOG_ERROR("%s: Out of memory for mspm0_info!", __func__);
336  return ERROR_FAIL;
337  }
338 
339  bank->driver_priv = mspm0_info;
340 
341  mspm0_info->sector_size = 0x400;
342 
343  return ERROR_OK;
344 }
345 
346 /*
347  * Chip identification and status
348  */
350 {
351  struct mspm0_flash_bank *mspm0_info = bank->driver_priv;
352 
353  if (mspm0_info->did == 0)
355 
357  "\nTI MSPM0 information: Chip is "
358  "%s rev %d Device Unique ID: 0x%" PRIu32 "\n",
359  mspm0_info->name, mspm0_info->version,
360  mspm0_info->traceid);
362  "main flash: %uKiB in %u bank(s), sram: %uKiB, data flash: %uKiB",
363  mspm0_info->main_flash_size_kb,
364  mspm0_info->main_flash_num_banks, mspm0_info->sram_size_kb,
365  mspm0_info->data_flash_size_kb);
366 
367  return ERROR_OK;
368 }
369 
370 /* Extract a bitfield helper */
371 static unsigned int mspm0_extract_val(unsigned int var, unsigned char hi, unsigned char lo)
372 {
373  return (var & GENMASK(hi, lo)) >> lo;
374 }
375 
377 {
378  struct mspm0_flash_bank *mspm0_info = bank->driver_priv;
379  struct target *target = bank->target;
380  const struct mspm0_family_info *minfo = NULL;
381 
382  /* Read and parse chip identification and flash version register */
383  uint32_t did;
384  int retval = target_read_u32(target, MSPM0_DID, &did);
385  if (retval != ERROR_OK) {
386  LOG_ERROR("Failed to read device ID");
387  return retval;
388  }
389  retval = target_read_u32(target, MSPM0_TRACEID, &mspm0_info->traceid);
390  if (retval != ERROR_OK) {
391  LOG_ERROR("Failed to read trace ID");
392  return retval;
393  }
394  uint32_t userid;
395  retval = target_read_u32(target, MSPM0_USERID, &userid);
396  if (retval != ERROR_OK) {
397  LOG_ERROR("Failed to read user ID");
398  return retval;
399  }
400  uint32_t flashram;
401  retval = target_read_u32(target, MSPM0_SRAMFLASH, &flashram);
402  if (retval != ERROR_OK) {
403  LOG_ERROR("Failed to read sramflash register");
404  return retval;
405  }
406  uint32_t flashdesc;
407  retval = target_read_u32(target, FCTL_REG_DESC, &flashdesc);
408  if (retval != ERROR_OK) {
409  LOG_ERROR("Failed to read flashctl description register");
410  return retval;
411  }
412 
413  unsigned char version = mspm0_extract_val(did, 31, 28);
414  unsigned short pnum = mspm0_extract_val(did, 27, 12);
415  unsigned char variant = mspm0_extract_val(userid, 23, 16);
416  unsigned short part = mspm0_extract_val(userid, 15, 0);
417  unsigned short manufacturer = mspm0_extract_val(did, 11, 1);
418 
419  /*
420  * Valid DIE and manufacturer ID?
421  * Check the ALWAYS_1 bit to be 1 and manufacturer to be 0x17. All MSPM0
422  * devices within the Device ID field of the factory constants will
423  * always read 0x17 as it is TI's JEDEC bank and company code. If 1
424  * and 0x17 is not read from their respective registers then it truly
425  * is not a MSPM0 device so we will return an error instead of
426  * going any further.
427  */
428  if (!(did & BIT(0)) || !(manufacturer & TI_MANUFACTURER_ID)) {
429  LOG_WARNING("Unknown Device ID[0x%" PRIx32 "], cannot identify target",
430  did);
431  LOG_DEBUG("did 0x%" PRIx32 ", traceid 0x%" PRIx32 ", userid 0x%" PRIx32
432  ", flashram 0x%" PRIx32 "", did, mspm0_info->traceid, userid,
433  flashram);
435  }
436 
437  /* Initialize master index selector and probe status*/
438  unsigned char minfo_idx = 0xff;
439  unsigned char probe_status = MSPM0_NO_ID_FOUND;
440 
441  /* Check if we at least know the family of devices */
442  for (unsigned int i = 0; i < ARRAY_SIZE(mspm0_finf); i++) {
443  if (mspm0_finf[i].part_num == pnum) {
444  minfo_idx = i;
445  minfo = &mspm0_finf[i];
446  probe_status = MSPM0_DEV_ID_FOUND;
447  break;
448  }
449  }
450 
451  /* Initialize part index selector*/
452  unsigned char pinfo_idx = 0xff;
453 
454  /*
455  * If we can identify the part number then we will attempt to identify
456  * the specific chip. Otherwise, if we do not know the part number then
457  * it would be useless to identify the specific chip.
458  */
459  if (probe_status == MSPM0_DEV_ID_FOUND) {
460  /* Can we specifically identify the chip */
461  for (unsigned int i = 0; i < minfo->part_count; i++) {
462  if (minfo->part_info[i].part == part
463  && minfo->part_info[i].variant == variant) {
464  pinfo_idx = i;
465  probe_status = MSPM0_DEV_PART_ID_FOUND;
466  break;
467  }
468  }
469  }
470 
471  /*
472  * We will check the status of our probe within this switch-case statement
473  * using these three scenarios.
474  *
475  * 1) Device, part, and variant ID is unknown.
476  * 2) Device ID is known but the part/variant ID is unknown.
477  * 3) Device ID and part/variant ID is known
478  *
479  * For scenario 1, we allow the user to continue because if the
480  * manufacturer matches TI's JEDEC value and ALWAYS_1 from the device ID
481  * field is correct then the assumption the user is using an MSPM0 device
482  * can be made.
483  */
484  switch (probe_status) {
485  case MSPM0_NO_ID_FOUND:
486  mspm0_info->name = "mspm0x";
487  LOG_INFO("Unidentified PART[0x%x]/variant[0x%x"
488  "], unknown DeviceID[0x%x"
489  "]. Attempting to proceed as %s.", part, variant, pnum,
490  mspm0_info->name);
491  break;
492  case MSPM0_DEV_ID_FOUND:
493  mspm0_info->name = mspm0_finf[minfo_idx].family_name;
494  LOG_INFO("Unidentified PART[0x%x]/variant[0x%x"
495  "], known DeviceID[0x%x"
496  "]. Attempting to proceed as %s.", part, variant, pnum,
497  mspm0_info->name);
498  break;
500  default:
501  mspm0_info->name = mspm0_finf[minfo_idx].part_info[pinfo_idx].part_name;
502  LOG_DEBUG("Part: %s detected", mspm0_info->name);
503  break;
504  }
505 
506  mspm0_info->did = did;
507  mspm0_info->version = version;
508  mspm0_info->data_flash_size_kb = mspm0_extract_val(flashram, 31, 26);
509  mspm0_info->main_flash_size_kb = mspm0_extract_val(flashram, 11, 0);
510  mspm0_info->main_flash_num_banks = mspm0_extract_val(flashram, 13, 12) + 1;
511  mspm0_info->sram_size_kb = mspm0_extract_val(flashram, 25, 16);
512  mspm0_info->flash_version = mspm0_extract_val(flashdesc, 15, 12);
513 
514  /*
515  * Hardcode flash_word_size unless we find some other pattern
516  * See section 7.7 (Foot note mentions the flash word size).
517  * almost all values seem to be 8 bytes, but if there are variance,
518  * then we should update mspm0_part_info structure with this info.
519  */
520  mspm0_info->flash_word_size_bytes = 8;
521 
522  LOG_DEBUG("Detected: main flash: %uKb in %u banks, sram: %uKb, data flash: %uKb",
523  mspm0_info->main_flash_size_kb, mspm0_info->main_flash_num_banks,
524  mspm0_info->sram_size_kb, mspm0_info->data_flash_size_kb);
525 
526  return ERROR_OK;
527 }
528 
529 /*
530  * Decode error values
531  */
532 static const struct {
533  const unsigned char bit_offset;
534  const char *fail_string;
536  { 2, "CMDINPROGRESS" },
537  { 4, "FAILWEPROT" },
538  { 5, "FAILVERIFY" },
539  { 6, "FAILILLADDR" },
540  { 7, "FAILMODE" },
541  { 12, "FAILMISC" },
542 };
543 
544 static const char *mspm0_fctl_translate_ret_err(unsigned int return_code)
545 {
546  for (unsigned int i = 0; i < ARRAY_SIZE(mspm0_fctl_fail_decode_strings); i++) {
547  if (return_code & BIT(mspm0_fctl_fail_decode_strings[i].bit_offset))
549  }
550 
551  /* If unknown error notify the user*/
552  return "FAILUNKNOWN";
553 }
554 
555 static int mspm0_fctl_get_sector_reg(struct flash_bank *bank, unsigned int addr,
556  unsigned int *reg, unsigned int *sector_mask)
557 {
558  struct mspm0_flash_bank *mspm0_info = bank->driver_priv;
559  struct target *target = bank->target;
560  int ret = ERROR_OK;
561  unsigned int sector_num = (addr >> 10);
562  unsigned int sector_in_bank = sector_num;
563  unsigned int phys_sector_num = sector_num;
564  uint32_t sysctl_sec_status;
565  unsigned int exec_upper_bank;
566 
567  /*
568  * If the device has dual banks we will need to check if it is configured
569  * to execute from the upper bank. In the scenario that we are executing
570  * from upper bank then we will need to protect it using CMDWEPROTA rather
571  * than CMDWEPROTB. We also need to take into account what sector
572  * we're using when going between banks.
573  */
574  if (mspm0_info->main_flash_num_banks > 1 &&
575  bank->base == MSPM0_FLASH_BASE_MAIN) {
576  ret = target_read_u32(target, SYSCTL_SECCFG_SECSTATUS, &sysctl_sec_status);
577  if (ret != ERROR_OK)
578  return ret;
579  exec_upper_bank = mspm0_extract_val(sysctl_sec_status, 12, 12);
580  if (exec_upper_bank) {
581  if (sector_num > (mspm0_info->main_flash_size_kb / 2)) {
582  phys_sector_num =
583  sector_num - (mspm0_info->main_flash_size_kb / 2);
584  } else {
585  phys_sector_num =
586  sector_num + (mspm0_info->main_flash_size_kb / 2);
587  }
588  }
589  sector_in_bank =
590  sector_num % (mspm0_info->main_flash_size_kb /
591  mspm0_info->main_flash_num_banks);
592  }
593 
594  /*
595  * NOTE: MSPM0 devices of version A will use CMDWEPROTA and CMDWEPROTB
596  * for MAIN flash. CMDWEPROTC is included in the TRM/DATASHEET but for
597  * all practical purposes, it is considered reserved. If the flash
598  * version on the device is version B, then we will only use
599  * CMDWEPROTB for MAIN and DATA flash if the device has it.
600  */
601  switch (bank->base) {
604  if (mspm0_info->flash_version < FCTL_FEATURE_VER_B) {
605  /* Use CMDWEPROTA */
606  if (phys_sector_num < 32) {
607  *sector_mask = BIT(phys_sector_num);
609  }
610 
611  /* Use CMDWEPROTB */
612  if (phys_sector_num >= 32 && sector_in_bank < 256) {
613  /* Dual bank system */
614  if (mspm0_info->main_flash_num_banks > 1)
615  *sector_mask = BIT(sector_in_bank / 8);
616  else /* Single bank system */
617  *sector_mask = BIT((sector_in_bank - 32) / 8);
619  }
620  } else {
621  *sector_mask = BIT((sector_in_bank / 8) % 32);
623  }
624  break;
626  *sector_mask = BIT(sector_num % 32);
628  break;
629  default:
630  /*
631  * Not expected to reach here due to check in mspm0_address_check()
632  * but adding it as another layer of safety.
633  */
635  break;
636  }
637 
638  if (ret != ERROR_OK)
639  LOG_ERROR("Unable to map sector protect reg for address 0x%08x", addr);
640 
641  return ret;
642 }
643 
644 static int mspm0_address_check(struct flash_bank *bank, unsigned int addr)
645 {
646  struct mspm0_flash_bank *mspm0_info = bank->driver_priv;
647  unsigned int flash_main_size = mspm0_info->main_flash_size_kb * 1024;
648  unsigned int flash_data_size = mspm0_info->data_flash_size_kb * 1024;
649  int ret = ERROR_FLASH_SECTOR_INVALID;
650 
651  /*
652  * Before unprotecting any memory lets make sure that the address and
653  * bank given is a known bank and whether or not the address falls under
654  * the proper bank.
655  */
656  switch (bank->base) {
658  if (addr <= (MSPM0_FLASH_BASE_MAIN + flash_main_size))
659  ret = ERROR_OK;
660  break;
663  ret = ERROR_OK;
664  break;
666  if (addr >= MSPM0_FLASH_BASE_DATA &&
667  addr <= (MSPM0_FLASH_BASE_DATA + flash_data_size))
668  ret = ERROR_OK;
669  break;
670  default:
672  break;
673  }
674 
675  return ret;
676 }
677 
678 static int mspm0_fctl_unprotect_sector(struct flash_bank *bank, unsigned int addr)
679 {
680  struct target *target = bank->target;
681  unsigned int reg = 0x0;
682  uint32_t sector_mask = 0x0;
683  int ret;
684 
685  ret = mspm0_address_check(bank, addr);
686  switch (ret) {
688  LOG_ERROR("Unable to map sector protect reg for address 0x%08x", addr);
689  break;
691  LOG_ERROR("Unable to determine which bank to use 0x%08x", addr);
692  break;
693  default:
694  mspm0_fctl_get_sector_reg(bank, addr, &reg, &sector_mask);
695  ret = target_write_u32(target, reg, ~sector_mask);
696  break;
697  }
698 
699  return ret;
700 }
701 
703  uint32_t addr,
704  uint32_t cmd,
705  uint32_t byte_en)
706 {
707  struct target *target = bank->target;
708 
709  /*
710  * Configure the flash operation within the CMDTYPE register, byte_en
711  * bits if needed, and then set the address where the flash operation
712  * will execute.
713  */
715  if (retval != ERROR_OK)
716  return retval;
717  if (byte_en != 0) {
718  retval = target_write_u32(target, FCTL_REG_CMDBYTEN, byte_en);
719  if (retval != ERROR_OK)
720  return retval;
721  }
722 
724 }
725 
727 {
728  struct target *target = bank->target;
729  uint32_t return_code = 0;
730  int64_t start_ms;
731  int64_t elapsed_ms;
732 
733  start_ms = timeval_ms();
734  while ((return_code & FCTL_STATCMD_CMDDONE_MASK) != FCTL_STATCMD_CMDDONE_STATDONE) {
735  int retval = target_read_u32(target, FCTL_REG_STATCMD, &return_code);
736  if (retval != ERROR_OK)
737  return retval;
738 
739  elapsed_ms = timeval_ms() - start_ms;
740  if (elapsed_ms > 500)
741  keep_alive();
742  if (elapsed_ms > MSPM0_FLASH_TIMEOUT_MS)
743  break;
744  }
745 
747  LOG_ERROR("Flash command failed: %s", mspm0_fctl_translate_ret_err(return_code));
748  return ERROR_FAIL;
749  }
750 
751  return ERROR_OK;
752 }
753 
754 static int mspm0_fctl_sector_erase(struct flash_bank *bank, uint32_t addr)
755 {
756  struct target *target = bank->target;
757 
758  /*
759  * TRM Says:
760  * Note that the CMDWEPROTx registers are reset to a protected state
761  * at the end of all program and erase operations. These registers
762  * must be re-configured by software before a new operation is
763  * initiated.
764  *
765  * This means that as we start erasing sector by sector, the protection
766  * registers are reset and need to be unprotected *again* for the next
767  * erase operation. Unfortunately, this means that we cannot do a unitary
768  * unprotect operation independent of flash erase operation
769  */
770  int retval = mspm0_fctl_unprotect_sector(bank, addr);
771  if (retval != ERROR_OK) {
772  LOG_ERROR("Unprotecting sector of memory at address 0x%08" PRIx32
773  " failed", addr);
774  return retval;
775  }
776 
777  /* Actual erase operation */
778  retval = mspm0_fctl_cfg_command(bank, addr,
780  if (retval != ERROR_OK)
781  return retval;
783  if (retval != ERROR_OK)
784  return retval;
785 
787 }
788 
790 {
791  struct mspm0_flash_bank *mspm0_info = bank->driver_priv;
792 
793  if (mspm0_info->did == 0)
795 
796  /*
797  * TRM Says:
798  * Note that the CMDWEPROTx registers are reset to a protected state
799  * at the end of all program and erase operations. These registers
800  * must be re-configured by software before a new operation is
801  * initiated.
802  *
803  * This means that when any flash operation is performed at a block level,
804  * the block is locked back again. This prevents usage where we can set a
805  * protection level once at the flash level and then do erase / write
806  * operation without touching the protection register (since it is
807  * reset by hardware automatically). In effect, we cannot use the hardware
808  * defined protection scheme in openOCD.
809  *
810  * To deal with this protection scheme, the CMDWEPROTx register that
811  * correlates to the sector is modified at the time of operation and as far
812  * openOCD is concerned, the flash operates as completely un-protected
813  * flash.
814  */
815  for (unsigned int i = 0; i < bank->num_sectors; i++)
816  bank->sectors[i].is_protected = 0;
817 
818  return ERROR_OK;
819 }
820 
821 static int mspm0_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
822 {
823  struct target *target = bank->target;
824  struct mspm0_flash_bank *mspm0_info = bank->driver_priv;
825  int retval = ERROR_OK;
826  uint32_t protect_reg_cache[MSPM0_MAX_PROTREGS];
827 
828  if (bank->target->state != TARGET_HALTED) {
829  LOG_ERROR("Please halt target for erasing flash");
831  }
832 
833  if (mspm0_info->did == 0)
835 
836  /* Pick a copy of the current protection config for later restoration */
837  for (unsigned int i = 0; i < mspm0_info->protect_reg_count; i++) {
838  retval = target_read_u32(target,
839  mspm0_info->protect_reg_base + (i * 4),
840  &protect_reg_cache[i]);
841  if (retval != ERROR_OK) {
842  LOG_ERROR("Failed saving flashctl protection status");
843  return retval;
844  }
845  }
846 
847  switch (bank->base) {
849  for (unsigned int csa = first; csa <= last; csa++) {
850  unsigned int addr = csa * mspm0_info->sector_size;
851  retval = mspm0_fctl_sector_erase(bank, addr);
852  if (retval != ERROR_OK)
853  LOG_ERROR("Sector erase on MAIN failed at address 0x%08x "
854  "(sector: %u)", addr, csa);
855  }
856  break;
859  if (retval != ERROR_OK)
860  LOG_ERROR("Sector erase on NONMAIN failed");
861  break;
863  for (unsigned int csa = first; csa <= last; csa++) {
864  unsigned int addr = (MSPM0_FLASH_BASE_DATA +
865  (csa * mspm0_info->sector_size));
866  retval = mspm0_fctl_sector_erase(bank, addr);
867  if (retval != ERROR_OK)
868  LOG_ERROR("Sector erase on DATA bank failed at address 0x%08x "
869  "(sector: %u)", addr, csa);
870  }
871  break;
872  default:
873  LOG_ERROR("Invalid memory region access");
874  retval = ERROR_FLASH_BANK_INVALID;
875  break;
876  }
877 
878  /* If there were any issues in our checks, return the error */
879  if (retval != ERROR_OK)
880  return retval;
881 
882  /*
883  * TRM Says:
884  * Note that the CMDWEPROTx registers are reset to a protected state
885  * at the end of all program and erase operations. These registers
886  * must be re-configured by software before a new operation is
887  * initiated
888  * Let us just Dump the protection registers back to the system.
889  * That way we retain the protection status as requested by the user
890  */
891  for (unsigned int i = 0; i < mspm0_info->protect_reg_count; i++) {
892  retval = target_write_u32(target, mspm0_info->protect_reg_base + (i * 4),
893  protect_reg_cache[i]);
894  if (retval != ERROR_OK) {
895  LOG_ERROR("Failed re-applying protection status of flashctl");
896  return retval;
897  }
898  }
899 
900  return retval;
901 }
902 
903 static int mspm0_write(struct flash_bank *bank, const unsigned char *buffer,
904  unsigned int offset, unsigned int count)
905 {
906  struct target *target = bank->target;
907  struct mspm0_flash_bank *mspm0_info = bank->driver_priv;
908  uint32_t protect_reg_cache[MSPM0_MAX_PROTREGS];
909  int retval;
910 
911  /*
912  * XXX: TRM Says:
913  * The number of program operations applied to a given word line must be
914  * monitored to ensure that the maximum word line program limit before
915  * erase is not violated.
916  *
917  * There is no reasonable way we can maintain that state in OpenOCD. So,
918  * Let the manufacturing path figure this out.
919  */
920 
921  if (bank->target->state != TARGET_HALTED) {
922  LOG_ERROR("Please halt target for programming flash");
924  }
925 
926  if (mspm0_info->did == 0)
928 
929  /*
930  * Pick a copy of the current protection config for later restoration
931  * We need to restore these regs after every write, so instead of trying
932  * to figure things out on the fly, we just context save and restore
933  */
934  for (unsigned int i = 0; i < mspm0_info->protect_reg_count; i++) {
935  retval = target_read_u32(target,
936  mspm0_info->protect_reg_base + (i * 4),
937  &protect_reg_cache[i]);
938  if (retval != ERROR_OK) {
939  LOG_ERROR("Failed saving flashctl protection status");
940  return retval;
941  }
942  }
943 
944  /* Add proper memory offset for bank being written to */
945  unsigned int addr = bank->base + offset;
946 
947  while (count) {
948  unsigned int num_bytes_to_write;
949  uint32_t bytes_en;
950 
951  /*
952  * If count is not 64 bit aligned, we will do byte wise op to keep things simple
953  * Usually this might mean we need to additional write ops towards
954  * trailing edge, but that is a tiny penalty for image downloads.
955  * NOTE: we are going to assume the device does not support multi-word
956  * programming - there does not seem to be discoverability!
957  */
958  if (count < mspm0_info->flash_word_size_bytes)
959  num_bytes_to_write = count;
960  else
961  num_bytes_to_write = mspm0_info->flash_word_size_bytes;
962 
963  /* Data bytes to write */
964  bytes_en = (1 << num_bytes_to_write) - 1;
965  /* ECC chunks to write */
966  switch (mspm0_info->flash_word_size_bytes) {
967  case 8:
968  bytes_en |= BIT(8);
969  break;
970  case 16:
971  bytes_en |= BIT(16);
972  bytes_en |= (num_bytes_to_write > 8) ? BIT(17) : 0;
973  break;
974  default:
975  LOG_ERROR("Invalid flash_word_size_bytes %d",
976  mspm0_info->flash_word_size_bytes);
977  return ERROR_FAIL;
978  }
979 
980  retval = mspm0_fctl_cfg_command(bank, addr,
982  bytes_en);
983  if (retval != ERROR_OK)
984  return retval;
985 
987  if (retval != ERROR_OK)
988  return retval;
989 
990  retval = target_write_buffer(target, FCTL_REG_CMDDATA0, num_bytes_to_write, buffer);
991  if (retval != ERROR_OK)
992  return retval;
993 
994  addr += num_bytes_to_write;
995  buffer += num_bytes_to_write;
996  count -= num_bytes_to_write;
997 
999  if (retval != ERROR_OK)
1000  return retval;
1001 
1002  retval = mspm0_fctl_wait_cmd_ok(bank);
1003  if (retval != ERROR_OK)
1004  return retval;
1005  }
1006 
1007  /*
1008  * TRM Says:
1009  * Note that the CMDWEPROTx registers are reset to a protected state
1010  * at the end of all program and erase operations. These registers
1011  * must be re-configured by software before a new operation is
1012  * initiated
1013  * Let us just Dump the protection registers back to the system.
1014  * That way we retain the protection status as requested by the user
1015  */
1016  for (unsigned int i = 0; i < mspm0_info->protect_reg_count; i++) {
1017  retval = target_write_u32(target,
1018  mspm0_info->protect_reg_base + (i * 4),
1019  protect_reg_cache[i]);
1020  if (retval != ERROR_OK) {
1021  LOG_ERROR("Failed re-applying protection status of flashctl");
1022  return retval;
1023  }
1024  }
1025 
1026  return ERROR_OK;
1027 }
1028 
1029 static int mspm0_probe(struct flash_bank *bank)
1030 {
1031  struct mspm0_flash_bank *mspm0_info = bank->driver_priv;
1032 
1033  /*
1034  * If this is a mspm0 chip, it has flash; probe() is just
1035  * to figure out how much is present. Only do it once.
1036  */
1037  if (mspm0_info->did != 0)
1038  return ERROR_OK;
1039 
1040  /*
1041  * mspm0_read_part_info() already handled error checking and
1042  * reporting. Note that it doesn't write, so we don't care about
1043  * whether the target is halted or not.
1044  */
1045  int retval = mspm0_read_part_info(bank);
1046  if (retval != ERROR_OK)
1047  return retval;
1048 
1049  if (bank->sectors) {
1050  free(bank->sectors);
1051  bank->sectors = NULL;
1052  }
1053 
1054  bank->write_start_alignment = 4;
1055  bank->write_end_alignment = 4;
1056 
1057  switch (bank->base) {
1059  bank->size = 1024;
1060  bank->num_sectors = 0x1;
1061  mspm0_info->protect_reg_base = FCTL_REG_CMDWEPROTNM;
1062  mspm0_info->protect_reg_count = 1;
1063  break;
1064  case MSPM0_FLASH_BASE_MAIN:
1065  bank->size = (mspm0_info->main_flash_size_kb * 1024);
1066  bank->num_sectors = bank->size / mspm0_info->sector_size;
1067  /*
1068  * If the feature version bit read from the FCTL_REG_DESC is
1069  * greater than or equal to 0xA then it means that the device
1070  * will exclusively use CMDWEPROTB ONLY for MAIN memory protection
1071  */
1072  if (mspm0_info->flash_version >= FCTL_FEATURE_VER_B) {
1073  mspm0_info->protect_reg_base = FCTL_REG_CMDWEPROTB;
1074  mspm0_info->protect_reg_count = 1;
1075  } else {
1076  mspm0_info->protect_reg_base = FCTL_REG_CMDWEPROTA;
1077  mspm0_info->protect_reg_count = 3;
1078  }
1079  break;
1080  case MSPM0_FLASH_BASE_DATA:
1081  if (!mspm0_info->data_flash_size_kb) {
1082  LOG_INFO("Data region NOT available!");
1083  bank->size = 0x0;
1084  bank->num_sectors = 0x0;
1085  return ERROR_OK;
1086  }
1087  /*
1088  * Any MSPM0 device containing data bank will have a flashctl
1089  * feature version of 0xA or higher. Since data bank is treated
1090  * like MAIN memory, it will also exclusively use CMDWEPROTB for
1091  * protection.
1092  */
1093  bank->size = (mspm0_info->data_flash_size_kb * 1024);
1094  bank->num_sectors = bank->size / mspm0_info->sector_size;
1095  mspm0_info->protect_reg_base = FCTL_REG_CMDWEPROTB;
1096  mspm0_info->protect_reg_count = 1;
1097  break;
1098  default:
1099  LOG_ERROR("Invalid bank address " TARGET_ADDR_FMT,
1100  bank->base);
1101  return ERROR_FAIL;
1102  }
1103 
1104  bank->sectors = calloc(bank->num_sectors, sizeof(struct flash_sector));
1105  if (!bank->sectors) {
1106  LOG_ERROR("Out of memory for sectors!");
1107  return ERROR_FAIL;
1108  }
1109  for (unsigned int i = 0; i < bank->num_sectors; i++) {
1110  bank->sectors[i].offset = i * mspm0_info->sector_size;
1111  bank->sectors[i].size = mspm0_info->sector_size;
1112  bank->sectors[i].is_erased = -1;
1113  }
1114 
1115  return ERROR_OK;
1116 }
1117 
1118 const struct flash_driver mspm0_flash = {
1119  .name = "mspm0",
1120  .flash_bank_command = mspm0_flash_bank_command,
1121  .erase = mspm0_erase,
1122  .protect = NULL,
1123  .write = mspm0_write,
1124  .read = default_flash_read,
1125  .probe = mspm0_probe,
1126  .auto_probe = mspm0_probe,
1127  .erase_check = default_flash_blank_check,
1128  .protect_check = mspm0_protect_check,
1129  .info = get_mspm0_info,
1130  .free_driver_priv = default_flash_free_driver_priv,
1131 };
#define GENMASK(h, l)
Definition: bits.h:24
void command_print_sameline(struct command_invocation *cmd, const char *format,...)
Definition: command.c:420
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 keep_alive(void)
Definition: log.c:426
#define LOG_WARNING(expr ...)
Definition: log.h:130
#define ERROR_FAIL
Definition: log.h:174
#define LOG_ERROR(expr ...)
Definition: log.h:133
#define LOG_INFO(expr ...)
Definition: log.h:127
#define LOG_DEBUG(expr ...)
Definition: log.h:110
#define ERROR_OK
Definition: log.h:168
#define FCTL_CMDEXEC_VAL_EXECUTE
Definition: mspm0.c:58
static int mspm0_fctl_wait_cmd_ok(struct flash_bank *bank)
Definition: mspm0.c:726
#define MSPM0_DEV_PART_ID_FOUND
Definition: mspm0.c:86
#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:544
#define MSPM0_DID
Definition: mspm0.c:29
#define MSPM0_FLASH_BASE_MAIN
Definition: mspm0.c:23
#define FCTL_REG_CMDTYPE
Definition: mspm0.c:37
static int get_mspm0_info(struct flash_bank *bank, struct command_invocation *cmd)
Definition: mspm0.c:349
static int mspm0_write(struct flash_bank *bank, const unsigned char *buffer, unsigned int offset, unsigned int count)
Definition: mspm0.c:903
static const struct mspm0_part_info mspm0lx22x_parts[]
Definition: mspm0.c:280
const struct flash_driver mspm0_flash
Definition: mspm0.c:1118
static unsigned int mspm0_extract_val(unsigned int var, unsigned char hi, unsigned char lo)
Definition: mspm0.c:371
#define FCTL_REG_DESC
Definition: mspm0.c:35
static const struct mspm0_part_info mspm0g_parts[]
Definition: mspm0.c:192
#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:555
static const struct mspm0_family_info mspm0_finf[]
Definition: mspm0.c:305
#define MSPM0_FLASH_END_NONMAIN
Definition: mspm0.c:22
static const struct mspm0_part_info mspm0l_parts[]
Definition: mspm0.c:130
const unsigned char bit_offset
Definition: mspm0.c:533
static int mspm0_fctl_unprotect_sector(struct flash_bank *bank, unsigned int addr)
Definition: mspm0.c:678
#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:702
static int mspm0_protect_check(struct flash_bank *bank)
Definition: mspm0.c:789
#define FCTL_REG_CMDADDR
Definition: mspm0.c:38
#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:319
static const struct mspm0_part_info mspm0c_parts[]
Definition: mspm0.c:270
#define MSPM0_NO_ID_FOUND
Definition: mspm0.c:84
#define TI_MANUFACTURER_ID
Definition: mspm0.c:81
#define MSPM0_FLASH_BASE_DATA
Definition: mspm0.c:24
const char * fail_string
Definition: mspm0.c:534
#define FCTL_FEATURE_VER_B
Definition: mspm0.c:69
#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:1029
#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:85
static int mspm0_read_part_info(struct flash_bank *bank)
Definition: mspm0.c:376
#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:821
static int mspm0_address_check(struct flash_bank *bank, unsigned int addr)
Definition: mspm0.c:644
#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:754
#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:123
unsigned short part_num
Definition: mspm0.c:124
const struct mspm0_part_info * part_info
Definition: mspm0.c:126
unsigned char part_count
Definition: mspm0.c:125
unsigned int main_flash_num_banks
Definition: mspm0.c:100
unsigned int protect_reg_base
Definition: mspm0.c:109
unsigned int data_flash_size_kb
Definition: mspm0.c:98
uint32_t traceid
Definition: mspm0.c:92
unsigned int protect_reg_count
Definition: mspm0.c:110
unsigned int main_flash_size_kb
Definition: mspm0.c:99
uint32_t did
Definition: mspm0.c:90
unsigned char flash_version
Definition: mspm0.c:113
unsigned int sram_size_kb
Definition: mspm0.c:103
unsigned int sector_size
Definition: mspm0.c:101
unsigned char version
Definition: mspm0.c:93
const char * name
Definition: mspm0.c:95
unsigned char flash_word_size_bytes
Definition: mspm0.c:106
unsigned char variant
Definition: mspm0.c:119
unsigned short part
Definition: mspm0.c:118
const char * part_name
Definition: mspm0.c:117
Definition: register.h:111
Definition: target.h:116
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
Definition: target.c:2343
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
Definition: target.c:2642
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
Definition: target.c:2551
#define ERROR_TARGET_NOT_HALTED
Definition: target.h:790
@ TARGET_HALTED
Definition: target.h:56
int64_t timeval_ms(void)
#define TARGET_ADDR_FMT
Definition: types.h:342
#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 count[4]
Definition: vdebug.c:22