flash/nor: add support for TI MSP432 devices
[fw/openocd] / src / flash / nor / msp432.c
1 /***************************************************************************
2  *   Copyright (C) 2018 by Texas Instruments, Inc.                         *
3  *                                                                         *
4  *   This program is free software; you can redistribute it and/or modify  *
5  *   it under the terms of the GNU General Public License as published by  *
6  *   the Free Software Foundation; either version 2 of the License, or     *
7  *   (at your option) any later version.                                   *
8  *                                                                         *
9  *   This program is distributed in the hope that it will be useful,       *
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12  *   GNU General Public License for more details.                          *
13  *                                                                         *
14  *   You should have received a copy of the GNU General Public License     *
15  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
16  ***************************************************************************/
17
18 #ifdef HAVE_CONFIG_H
19 #include "config.h"
20 #endif
21
22 #include "imp.h"
23 #include "msp432.h"
24 #include <helper/binarybuffer.h>
25 #include <helper/time_support.h>
26 #include <target/algorithm.h>
27 #include <target/armv7m.h>
28 #include <target/image.h>
29
30 /* MSP432P4 hardware registers */
31 #define P4_FLASH_MAIN_SIZE_REG 0xE0043020
32 #define P4_FLASH_INFO_SIZE_REG 0xE0043024
33 #define P4_DEVICE_ID_REG       0x0020100C
34 #define P4_HARDWARE_REV_REG    0x00201010
35
36 /* MSP432E4 hardware registers */
37 #define E4_DID0_REG 0x400FE000
38 #define E4_DID1_REG 0x400FE004
39
40 #define FLASH_TIMEOUT 8000
41
42 #define SUPPORT_MESSAGE \
43         "Your pre-production MSP432P401x silicon is not fully supported\n" \
44         "You can find more information at www.ti.com/product/MSP432P401R"
45
46 struct msp432_bank {
47         uint32_t device_id;
48         uint32_t hardware_rev;
49         int family_type;
50         int device_type;
51         uint32_t sector_length;
52         bool probed[2];
53         bool unlock_bsl;
54         struct working_area *working_area;
55         struct armv7m_algorithm armv7m_info;
56 };
57
58 static int msp432_auto_probe(struct flash_bank *bank);
59
60 static int msp432_device_type(uint32_t family_type, uint32_t device_id,
61         uint32_t hardware_rev)
62 {
63         int device_type = MSP432_NO_TYPE;
64
65         if (MSP432E4 == family_type) {
66                 /* MSP432E4 device family */
67
68                 if (device_id == 0x180C0002) {
69                         if (hardware_rev == 0x102DC06E) {
70                                 /* The 01Y variant */
71                                 device_type = MSP432E401Y;
72                         } else if (hardware_rev == 0x1032E076) {
73                                 /* The 11Y variant */
74                                 device_type = MSP432E411Y;
75                         } else {
76                                 /* Reasonable guess that this is a new variant */
77                                 device_type = MSP432E4X_GUESS;
78                         }
79                 } else {
80                         /* Wild guess that this is an MSP432E4 */
81                         device_type = MSP432E4X_GUESS;
82                 }
83         } else {
84                 /* MSP432P4 device family */
85
86                 /* Examine the device ID and hardware revision to get the device type */
87                 switch (device_id) {
88                         case 0xA000:
89                         case 0xA001:
90                         case 0xA002:
91                         case 0xA003:
92                         case 0xA004:
93                         case 0xA005:
94                                 /* Device is definitely MSP432P401x, check hardware revision */
95                                 if (hardware_rev == 0x41 || hardware_rev == 0x42) {
96                                         /* Rev A or B of the silicon has been deprecated */
97                                         device_type = MSP432P401X_DEPR;
98                                 } else if (hardware_rev >= 0x43 && hardware_rev <= 0x49) {
99                                         /* Current and future revisions of the MSP432P401x device */
100                                         device_type = MSP432P401X;
101                                 } else {
102                                         /* Unknown or unanticipated hardware revision */
103                                         device_type = MSP432P401X_GUESS;
104                                 }
105                                 break;
106                         case 0xA010:
107                         case 0xA012:
108                         case 0xA016:
109                         case 0xA019:
110                         case 0xA01F:
111                         case 0xA020:
112                         case 0xA022:
113                         case 0xA026:
114                         case 0xA029:
115                         case 0xA02F:
116                                 /* Device is definitely MSP432P411x, check hardware revision */
117                                 if (hardware_rev >= 0x41 && hardware_rev <= 0x49) {
118                                         /* Current and future revisions of the MSP432P411x device */
119                                         device_type = MSP432P411X;
120                                 } else {
121                                         /* Unknown or unanticipated hardware revision */
122                                         device_type = MSP432P411X_GUESS;
123                                 }
124                                 break;
125                         case 0xFFFF:
126                                 /* Device is very early silicon that has been deprecated */
127                                 device_type = MSP432P401X_DEPR;
128                                 break;
129                         default:
130                                 if (device_id < 0xA010) {
131                                         /* Wild guess that this is an MSP432P401x */
132                                         device_type = MSP432P401X_GUESS;
133                                 } else {
134                                         /* Reasonable guess that this is a new variant */
135                                         device_type = MSP432P411X_GUESS;
136                                 }
137                                 break;
138                 }
139         }
140
141         return device_type;
142 }
143
144 static const char *msp432_return_text(uint32_t return_code)
145 {
146         switch (return_code) {
147                 case FLASH_BUSY:
148                         return "FLASH_BUSY";
149                 case FLASH_SUCCESS:
150                         return "FLASH_SUCCESS";
151                 case FLASH_ERROR:
152                         return "FLASH_ERROR";
153                 case FLASH_TIMEOUT_ERROR:
154                         return "FLASH_TIMEOUT_ERROR";
155                 case FLASH_VERIFY_ERROR:
156                         return "FLASH_VERIFY_WRONG";
157                 case FLASH_WRONG_COMMAND:
158                         return "FLASH_WRONG_COMMAND";
159                 case FLASH_POWER_ERROR:
160                         return "FLASH_POWER_ERROR";
161                 default:
162                         return "UNDEFINED_RETURN_CODE";
163         }
164 }
165
166 static void msp432_init_params(struct msp432_algo_params *algo_params)
167 {
168         buf_set_u32(algo_params->flash_command, 0, 32, FLASH_NO_COMMAND);
169         buf_set_u32(algo_params->return_code, 0, 32, 0);
170         buf_set_u32(algo_params->_reserved0, 0, 32, 0);
171         buf_set_u32(algo_params->address, 0, 32, 0);
172         buf_set_u32(algo_params->length, 0, 32, 0);
173         buf_set_u32(algo_params->buffer1_status, 0, 32, BUFFER_INACTIVE);
174         buf_set_u32(algo_params->buffer2_status, 0, 32, BUFFER_INACTIVE);
175         buf_set_u32(algo_params->erase_param, 0, 32, FLASH_ERASE_MAIN);
176         buf_set_u32(algo_params->unlock_bsl, 0, 32, FLASH_LOCK_BSL);
177 }
178
179 static int msp432_exec_cmd(struct target *target, struct msp432_algo_params
180                         *algo_params, uint32_t command)
181 {
182         int retval;
183
184         /* Make sure the given params do not include the command */
185         buf_set_u32(algo_params->flash_command, 0, 32, FLASH_NO_COMMAND);
186         buf_set_u32(algo_params->return_code, 0, 32, 0);
187         buf_set_u32(algo_params->buffer1_status, 0, 32, BUFFER_INACTIVE);
188         buf_set_u32(algo_params->buffer2_status, 0, 32, BUFFER_INACTIVE);
189
190         /* Write out parameters to target memory */
191         retval = target_write_buffer(target, ALGO_PARAMS_BASE_ADDR,
192                                 sizeof(struct msp432_algo_params), (uint8_t *)algo_params);
193         if (ERROR_OK != retval)
194                 return retval;
195
196         /* Write out command to target memory */
197         retval = target_write_buffer(target, ALGO_FLASH_COMMAND_ADDR,
198                                 sizeof(command), (uint8_t *)&command);
199
200         return retval;
201 }
202
203 static int msp432_wait_return_code(struct target *target)
204 {
205         uint32_t return_code = 0;
206         long long start_ms;
207         long long elapsed_ms;
208
209         int retval = ERROR_OK;
210
211         start_ms = timeval_ms();
212         while ((0 == return_code) || (FLASH_BUSY == return_code)) {
213                 retval = target_read_buffer(target, ALGO_RETURN_CODE_ADDR,
214                                         sizeof(return_code), (uint8_t *)&return_code);
215                 if (ERROR_OK != retval)
216                         return retval;
217
218                 elapsed_ms = timeval_ms() - start_ms;
219                 if (elapsed_ms > 500)
220                         keep_alive();
221                 if (elapsed_ms > FLASH_TIMEOUT)
222                         break;
223         };
224
225         if (FLASH_SUCCESS != return_code) {
226                 LOG_ERROR("msp432: Flash operation failed: %s",
227                         msp432_return_text(return_code));
228                 return ERROR_FAIL;
229         }
230
231         return ERROR_OK;
232 }
233
234 static int msp432_wait_inactive(struct target *target, uint32_t buffer)
235 {
236         uint32_t status_code = BUFFER_ACTIVE;
237         uint32_t status_addr;
238         long long start_ms;
239         long long elapsed_ms;
240
241         int retval;
242
243         switch (buffer) {
244                 case 1: /* Buffer 1 */
245                         status_addr = ALGO_BUFFER1_STATUS_ADDR;
246                         break;
247                 case 2: /* Buffer 2 */
248                         status_addr = ALGO_BUFFER2_STATUS_ADDR;
249                         break;
250                 default:
251                         return ERROR_FAIL;
252         }
253
254         start_ms = timeval_ms();
255         while (BUFFER_INACTIVE != status_code) {
256                 retval = target_read_buffer(target, status_addr, sizeof(status_code),
257                                         (uint8_t *)&status_code);
258                 if (ERROR_OK != retval)
259                         return retval;
260
261                 elapsed_ms = timeval_ms() - start_ms;
262                 if (elapsed_ms > 500)
263                         keep_alive();
264                 if (elapsed_ms > FLASH_TIMEOUT)
265                         break;
266         };
267
268         if (BUFFER_INACTIVE != status_code) {
269                 LOG_ERROR(
270                         "msp432: Flash operation failed: buffer not written to flash");
271                 return ERROR_FAIL;
272         }
273
274         return ERROR_OK;
275 }
276
277 static int msp432_init(struct flash_bank *bank)
278 {
279         struct target *target = bank->target;
280         struct msp432_bank *msp432_bank = bank->driver_priv;
281         struct msp432_algo_params algo_params;
282         struct reg_param reg_params[1];
283
284         const uint8_t *loader_code;
285         uint32_t loader_size;
286         uint32_t algo_entry_addr;
287         int retval;
288
289         /* Make sure we've probed the flash to get the device and size */
290         retval = msp432_auto_probe(bank);
291         if (ERROR_OK != retval)
292                 return retval;
293
294         /* Choose appropriate flash helper algorithm */
295         switch (msp432_bank->device_type) {
296                 case MSP432P401X:
297                 case MSP432P401X_DEPR:
298                 case MSP432P401X_GUESS:
299                 default:
300                         loader_code = msp432p401x_algo;
301                         loader_size = sizeof(msp432p401x_algo);
302                         algo_entry_addr = P4_ALGO_ENTRY_ADDR;
303                         break;
304                 case MSP432P411X:
305                 case MSP432P411X_GUESS:
306                         loader_code = msp432p411x_algo;
307                         loader_size = sizeof(msp432p411x_algo);
308                         algo_entry_addr = P4_ALGO_ENTRY_ADDR;
309                         break;
310                 case MSP432E401Y:
311                 case MSP432E411Y:
312                 case MSP432E4X_GUESS:
313                         loader_code = msp432e4x_algo;
314                         loader_size = sizeof(msp432e4x_algo);
315                         algo_entry_addr = E4_ALGO_ENTRY_ADDR;
316                         break;
317         }
318
319         /* Issue warnings if this is a device we may not be able to flash */
320         if (MSP432P401X_GUESS == msp432_bank->device_type ||
321                 MSP432P411X_GUESS == msp432_bank->device_type) {
322                 /* Explicit device type check failed. Report this. */
323                 LOG_WARNING(
324                         "msp432: Unrecognized MSP432P4 Device ID and Hardware "
325                         "Rev (%04X, %02X)", msp432_bank->device_id,
326                         msp432_bank->hardware_rev);
327         } else if (MSP432P401X_DEPR == msp432_bank->device_type) {
328                 LOG_WARNING(
329                         "msp432: MSP432P401x pre-production device (deprecated "
330                         "silicon)\n" SUPPORT_MESSAGE);
331         } else if (MSP432E4X_GUESS == msp432_bank->device_type) {
332                 /* Explicit device type check failed. Report this. */
333                 LOG_WARNING(
334                         "msp432: Unrecognized MSP432E4 DID0 and DID1 values "
335                         "(%08X, %08X)", msp432_bank->device_id,
336                         msp432_bank->hardware_rev);
337         }
338
339         /* Check for working area to use for flash helper algorithm */
340         if (NULL != msp432_bank->working_area)
341                 target_free_working_area(target, msp432_bank->working_area);
342         retval = target_alloc_working_area(target, ALGO_WORKING_SIZE,
343                                 &msp432_bank->working_area);
344         if (ERROR_OK != retval)
345                 return retval;
346
347         /* Confirm the defined working address is the area we need to use */
348         if (ALGO_BASE_ADDR != msp432_bank->working_area->address)
349                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
350
351         /* Write flash helper algorithm into target memory */
352         retval = target_write_buffer(target, ALGO_BASE_ADDR, loader_size,
353                                 loader_code);
354         if (ERROR_OK != retval)
355                 return retval;
356
357         /* Initialize the ARMv7 specific info to run the algorithm */
358         msp432_bank->armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
359         msp432_bank->armv7m_info.core_mode = ARM_MODE_THREAD;
360
361         /* Initialize algorithm parameters to default values */
362         msp432_init_params(&algo_params);
363
364         /* Write out parameters to target memory */
365         retval = target_write_buffer(target, ALGO_PARAMS_BASE_ADDR,
366                                 sizeof(algo_params), (uint8_t *)&algo_params);
367         if (ERROR_OK != retval)
368                 return retval;
369
370         /* Initialize stack pointer for flash helper algorithm */
371         init_reg_param(&reg_params[0], "sp", 32, PARAM_OUT);
372         buf_set_u32(reg_params[0].value, 0, 32, ALGO_STACK_POINTER_ADDR);
373
374         /* Begin executing the flash helper algorithm */
375         retval = target_start_algorithm(target, 0, 0, 1, reg_params,
376                                 algo_entry_addr, 0, &msp432_bank->armv7m_info);
377         destroy_reg_param(&reg_params[0]);
378         if (ERROR_OK != retval) {
379                 LOG_ERROR("msp432: Failed to start flash helper algorithm");
380                 return retval;
381         }
382
383         /*
384          * At this point, the algorithm is running on the target and
385          * ready to receive commands and data to flash the target
386          */
387
388         /* Issue the init command to the flash helper algorithm */
389         retval = msp432_exec_cmd(target, &algo_params, FLASH_INIT);
390         if (ERROR_OK != retval)
391                 return retval;
392
393         retval = msp432_wait_return_code(target);
394
395         return retval;
396 }
397
398 static int msp432_quit(struct flash_bank *bank)
399 {
400         struct target *target = bank->target;
401         struct msp432_bank *msp432_bank = bank->driver_priv;
402         struct msp432_algo_params algo_params;
403
404         int retval;
405
406         /* Initialize algorithm parameters to default values */
407         msp432_init_params(&algo_params);
408
409         /* Issue the exit command to the flash helper algorithm */
410         retval = msp432_exec_cmd(target, &algo_params, FLASH_EXIT);
411         if (ERROR_OK != retval)
412                 return retval;
413
414         (void)msp432_wait_return_code(target);
415
416         /* Regardless of the return code, attempt to halt the target */
417         (void)target_halt(target);
418
419         /* Now confirm target halted and clean up from flash helper algorithm */
420         retval = target_wait_algorithm(target, 0, NULL, 0, NULL, 0, FLASH_TIMEOUT,
421                                 &msp432_bank->armv7m_info);
422
423         target_free_working_area(target, msp432_bank->working_area);
424         msp432_bank->working_area = NULL;
425
426         return retval;
427 }
428
429 static int msp432_mass_erase(struct flash_bank *bank, bool all)
430 {
431         struct target *target = bank->target;
432         struct msp432_bank *msp432_bank = bank->driver_priv;
433         struct msp432_algo_params algo_params;
434
435         int retval;
436
437         if (TARGET_HALTED != target->state) {
438                 LOG_ERROR("Target not halted");
439                 return ERROR_TARGET_NOT_HALTED;
440         }
441
442         retval = msp432_init(bank);
443         if (ERROR_OK != retval)
444                 return retval;
445
446         /* Initialize algorithm parameters to default values */
447         msp432_init_params(&algo_params);
448         if (all) {
449                 buf_set_u32(algo_params.erase_param, 0, 32,
450                         FLASH_ERASE_MAIN | FLASH_ERASE_INFO);
451                 if (msp432_bank->unlock_bsl)
452                         buf_set_u32(algo_params.unlock_bsl, 0, 32, FLASH_UNLOCK_BSL);
453         }
454
455         /* Issue the mass erase command to the flash helper algorithm */
456         retval = msp432_exec_cmd(target, &algo_params, FLASH_MASS_ERASE);
457         if (ERROR_OK != retval) {
458                 (void)msp432_quit(bank);
459                 return retval;
460         }
461
462         retval = msp432_wait_return_code(target);
463         if (ERROR_OK != retval) {
464                 (void)msp432_quit(bank);
465                 return retval;
466         }
467
468         retval = msp432_quit(bank);
469         if (ERROR_OK != retval)
470                 return retval;
471
472         return retval;
473 }
474
475 COMMAND_HANDLER(msp432_mass_erase_command)
476 {
477         struct flash_bank *bank;
478         struct msp432_bank *msp432_bank;
479         bool all;
480         int retval;
481
482         if (0 == CMD_ARGC) {
483                 all = false;
484         } else if (1 == CMD_ARGC) {
485                 /* Check argument for how much to erase */
486                 if (0 == strcmp(CMD_ARGV[0], "main"))
487                         all = false;
488                 else if (0 == strcmp(CMD_ARGV[0], "all"))
489                         all = true;
490                 else
491                         return ERROR_COMMAND_SYNTAX_ERROR;
492         } else {
493                 return ERROR_COMMAND_SYNTAX_ERROR;
494         }
495
496         retval = get_flash_bank_by_num(0, &bank);
497         if (ERROR_OK != retval)
498                 return retval;
499
500         msp432_bank = bank->driver_priv;
501
502         if (MSP432E4 == msp432_bank->family_type) {
503                 /* MSP432E4 does not have main vs info regions, ignore "all" */
504                 all = false;
505         }
506
507         retval = msp432_mass_erase(bank, all);
508         if (ERROR_OK != retval)
509                 return retval;
510
511         if (MSP432E4 == msp432_bank->family_type) {
512                 /* MSP432E4 does not have main vs info regions */
513                 LOG_INFO("msp432: Mass erase of flash is complete");
514         } else {
515                 LOG_INFO("msp432: Mass erase of %s is complete",
516                         all ? "main + info flash" : "main flash");
517         }
518
519         return ERROR_OK;
520 }
521
522 COMMAND_HANDLER(msp432_bsl_command)
523 {
524         struct flash_bank *bank;
525         struct msp432_bank *msp432_bank;
526         int retval;
527
528         if (1 < CMD_ARGC)
529                 return ERROR_COMMAND_SYNTAX_ERROR;
530
531         retval = get_flash_bank_by_num(0, &bank);
532         if (ERROR_OK != retval)
533                 return retval;
534
535         msp432_bank = bank->driver_priv;
536
537         if (MSP432E4 == msp432_bank->family_type) {
538                 LOG_WARNING("msp432: MSP432E4 does not have a BSL region");
539                 return ERROR_OK;
540         }
541
542         if (1 == CMD_ARGC) {
543                 if (0 == strcmp(CMD_ARGV[0], "lock"))
544                         msp432_bank->unlock_bsl = false;
545                 else if (0 == strcmp(CMD_ARGV[0], "unlock"))
546                         msp432_bank->unlock_bsl = true;
547                 else
548                         return ERROR_COMMAND_SYNTAX_ERROR;
549         }
550
551         LOG_INFO("msp432: BSL flash region is currently %slocked",
552                 msp432_bank->unlock_bsl ? "un" : "");
553
554         return ERROR_OK;
555 }
556
557 FLASH_BANK_COMMAND_HANDLER(msp432_flash_bank_command)
558 {
559         struct msp432_bank *msp432_bank;
560
561         if (CMD_ARGC < 6)
562                 return ERROR_COMMAND_SYNTAX_ERROR;
563
564         msp432_bank = malloc(sizeof(struct msp432_bank));
565         if (NULL == msp432_bank)
566                 return ERROR_FAIL;
567
568         /* Initialize private flash information */
569         msp432_bank->device_id = 0;
570         msp432_bank->hardware_rev = 0;
571         msp432_bank->family_type = MSP432_NO_FAMILY;
572         msp432_bank->device_type = MSP432_NO_TYPE;
573         msp432_bank->sector_length = 0x1000;
574         msp432_bank->probed[0] = false;
575         msp432_bank->probed[1] = false;
576         msp432_bank->unlock_bsl = false;
577         msp432_bank->working_area = NULL;
578
579         /* Finish initialization of bank 0 (main flash) */
580         bank->driver_priv = msp432_bank;
581         bank->next = NULL;
582
583         return ERROR_OK;
584 }
585
586 static int msp432_erase(struct flash_bank *bank, int first, int last)
587 {
588         struct target *target = bank->target;
589         struct msp432_bank *msp432_bank = bank->driver_priv;
590         struct msp432_algo_params algo_params;
591
592         int retval;
593
594         if (TARGET_HALTED != target->state) {
595                 LOG_ERROR("Target not halted");
596                 return ERROR_TARGET_NOT_HALTED;
597         }
598
599         /* Do a mass erase if user requested all sectors of main flash */
600         if ((0 == bank->bank_number) && (first == 0) &&
601                 (last == (bank->num_sectors - 1))) {
602                 /* Request mass erase of main flash */
603                 return msp432_mass_erase(bank, false);
604         }
605
606         retval = msp432_init(bank);
607         if (ERROR_OK != retval)
608                 return retval;
609
610         /* Initialize algorithm parameters to default values */
611         msp432_init_params(&algo_params);
612
613         /* Adjust params if this is the info bank */
614         if (1 == bank->bank_number) {
615                 buf_set_u32(algo_params.erase_param, 0, 32, FLASH_ERASE_INFO);
616                 /* And flag if BSL is unlocked */
617                 if (msp432_bank->unlock_bsl)
618                         buf_set_u32(algo_params.unlock_bsl, 0, 32, FLASH_UNLOCK_BSL);
619         }
620
621         /* Erase requested sectors one by one */
622         for (int i = first; i <= last; i++) {
623
624                 /* Skip TVL (read-only) sector of the info bank */
625                 if (1 == bank->bank_number && 1 == i)
626                         continue;
627
628                 /* Skip BSL sectors of info bank if locked */
629                 if (1 == bank->bank_number && (2 == i || 3 == i) &&
630                         !msp432_bank->unlock_bsl)
631                         continue;
632
633                 /* Convert sector number to starting address of sector */
634                 buf_set_u32(algo_params.address, 0, 32, bank->base +
635                         (i * msp432_bank->sector_length));
636
637                 /* Issue the sector erase command to the flash helper algorithm */
638                 retval = msp432_exec_cmd(target, &algo_params, FLASH_SECTOR_ERASE);
639                 if (ERROR_OK != retval) {
640                         (void)msp432_quit(bank);
641                         return retval;
642                 }
643
644                 retval = msp432_wait_return_code(target);
645                 if (ERROR_OK != retval) {
646                         (void)msp432_quit(bank);
647                         return retval;
648                 }
649         }
650
651         retval = msp432_quit(bank);
652         if (ERROR_OK != retval)
653                 return retval;
654
655         return retval;
656 }
657
658 static int msp432_protect(struct flash_bank *bank, int set, int first,
659         int last)
660 {
661         return ERROR_OK;
662 }
663
664 static int msp432_write(struct flash_bank *bank, const uint8_t *buffer,
665         uint32_t offset, uint32_t count)
666 {
667         struct target *target = bank->target;
668         struct msp432_bank *msp432_bank = bank->driver_priv;
669         struct msp432_algo_params algo_params;
670         uint32_t size;
671         uint32_t data_ready = BUFFER_DATA_READY;
672         long long start_ms;
673         long long elapsed_ms;
674
675         int retval;
676
677         if (TARGET_HALTED != target->state) {
678                 LOG_ERROR("Target not halted");
679                 return ERROR_TARGET_NOT_HALTED;
680         }
681
682         /*
683          * Block attempts to write to read-only sectors of flash
684          * The TVL region in sector 1 of the info flash is always read-only
685          * The BSL region in sectors 2 and 3 of the info flash may be unlocked
686          * The helper algorithm will hang on attempts to write to TVL
687          */
688         if (1 == bank->bank_number) {
689                 /* Set read-only start to TVL sector */
690                 uint32_t start = 0x1000;
691                 /* Set read-only end after BSL region if locked */
692                 uint32_t end = (msp432_bank->unlock_bsl) ? 0x2000 : 0x4000;
693                 /* Check if request includes anything in read-only sectors */
694                 if ((offset + count - 1) < start || offset >= end) {
695                         /* The request includes no bytes in read-only sectors */
696                         /* Fall out and process the request normally */
697                 } else {
698                         /* Send a request for anything before read-only sectors */
699                         if (offset < start) {
700                                 uint32_t start_count = MIN(start - offset, count);
701                                 retval = msp432_write(bank, buffer, offset, start_count);
702                                 if (ERROR_OK != retval)
703                                         return retval;
704                         }
705                         /* Send a request for anything after read-only sectors */
706                         if ((offset + count - 1) >= end) {
707                                 uint32_t skip = end - offset;
708                                 count -= skip;
709                                 offset += skip;
710                                 buffer += skip;
711                                 return msp432_write(bank, buffer, offset, count);
712                         } else {
713                                 /* Request is entirely in read-only sectors */
714                                 return ERROR_OK;
715                         }
716                 }
717         }
718
719         retval = msp432_init(bank);
720         if (ERROR_OK != retval)
721                 return retval;
722
723         /* Initialize algorithm parameters to default values */
724         msp432_init_params(&algo_params);
725
726         /* Set up parameters for requested flash write operation */
727         buf_set_u32(algo_params.address, 0, 32, bank->base + offset);
728         buf_set_u32(algo_params.length, 0, 32, count);
729
730         /* Check if this is the info bank */
731         if (1 == bank->bank_number) {
732                 /* And flag if BSL is unlocked */
733                 if (msp432_bank->unlock_bsl)
734                         buf_set_u32(algo_params.unlock_bsl, 0, 32, FLASH_UNLOCK_BSL);
735         }
736
737         /* Set up flash helper algorithm to continuous flash mode */
738         retval = msp432_exec_cmd(target, &algo_params, FLASH_CONTINUOUS);
739         if (ERROR_OK != retval) {
740                 (void)msp432_quit(bank);
741                 return retval;
742         }
743
744         /* Write requested data, one buffer at a time */
745         start_ms = timeval_ms();
746         while (count > 0) {
747
748                 if (count > ALGO_BUFFER_SIZE)
749                         size = ALGO_BUFFER_SIZE;
750                 else
751                         size = count;
752
753                 /* Put next block of data to flash into buffer */
754                 retval = target_write_buffer(target, ALGO_BUFFER1_ADDR, size, buffer);
755                 if (ERROR_OK != retval) {
756                         LOG_ERROR("Unable to write data to target memory");
757                         (void)msp432_quit(bank);
758                         return ERROR_FLASH_OPERATION_FAILED;
759                 }
760
761                 /* Signal the flash helper algorithm that data is ready to flash */
762                 retval = target_write_buffer(target, ALGO_BUFFER1_STATUS_ADDR,
763                                         sizeof(data_ready), (uint8_t *)&data_ready);
764                 if (ERROR_OK != retval) {
765                         (void)msp432_quit(bank);
766                         return ERROR_FLASH_OPERATION_FAILED;
767                 }
768
769                 retval = msp432_wait_inactive(target, 1);
770                 if (ERROR_OK != retval) {
771                         (void)msp432_quit(bank);
772                         return retval;
773                 }
774
775                 count -= size;
776                 buffer += size;
777
778                 elapsed_ms = timeval_ms() - start_ms;
779                 if (elapsed_ms > 500)
780                         keep_alive();
781         }
782
783         /* Confirm that the flash helper algorithm is finished */
784         retval = msp432_wait_return_code(target);
785         if (ERROR_OK != retval) {
786                 (void)msp432_quit(bank);
787                 return retval;
788         }
789
790         retval = msp432_quit(bank);
791         if (ERROR_OK != retval)
792                 return retval;
793
794         return retval;
795 }
796
797 static int msp432_probe(struct flash_bank *bank)
798 {
799         struct target *target = bank->target;
800         struct msp432_bank *msp432_bank = bank->driver_priv;
801
802         char *name;
803
804         uint32_t device_id;
805         uint32_t hardware_rev;
806
807         uint32_t base;
808         uint32_t sector_length;
809         uint32_t size;
810         int num_sectors;
811         int bank_id;
812
813         int retval;
814
815         bank_id = bank->bank_number;
816
817         /* Read the flash size register to determine this is a P4 or not */
818         /* MSP432P4s will return the size of flash.  MSP432E4s will return zero */
819         retval = target_read_u32(target, P4_FLASH_MAIN_SIZE_REG, &size);
820         if (ERROR_OK != retval)
821                 return retval;
822
823         if (0 == size) {
824                 /* This is likely an MSP432E4 */
825                 msp432_bank->family_type = MSP432E4;
826
827                 retval = target_read_u32(target, E4_DID0_REG, &device_id);
828                 if (ERROR_OK != retval)
829                         return retval;
830
831                 msp432_bank->device_id = device_id;
832
833                 retval = target_read_u32(target, E4_DID1_REG, &hardware_rev);
834                 if (ERROR_OK != retval)
835                         return retval;
836
837                 msp432_bank->hardware_rev = hardware_rev;
838         } else {
839                 /* This is likely an MSP432P4 */
840                 msp432_bank->family_type = MSP432P4;
841
842                 retval = target_read_u32(target, P4_DEVICE_ID_REG, &device_id);
843                 if (ERROR_OK != retval)
844                         return retval;
845
846                 msp432_bank->device_id = device_id & 0xFFFF;
847
848                 retval = target_read_u32(target, P4_HARDWARE_REV_REG, &hardware_rev);
849                 if (ERROR_OK != retval)
850                         return retval;
851
852                 msp432_bank->hardware_rev = hardware_rev & 0xFF;
853         }
854
855         msp432_bank->device_type = msp432_device_type(msp432_bank->family_type,
856                 msp432_bank->device_id, msp432_bank->hardware_rev);
857
858         /* If not already allocated, create the info bank for MSP432P4 */
859         /* We could not determine it was needed until device was probed */
860         if (MSP432P4 == msp432_bank->family_type) {
861                 /* If we've been given bank 1, then this was already done */
862                 if (0 == bank_id) {
863                         /* And only allocate it if it doesn't exist yet */
864                         if (NULL == bank->next) {
865                                 struct flash_bank *info_bank;
866                                 info_bank = malloc(sizeof(struct flash_bank));
867                                 if (NULL == info_bank)
868                                         return ERROR_FAIL;
869
870                                 name = malloc(strlen(bank->name)+1);
871                                 if (NULL == name) {
872                                         free(info_bank);
873                                         return ERROR_FAIL;
874                                 }
875                                 strcpy(name, bank->name);
876
877                                 /* Initialize bank 1 (info region) */
878                                 info_bank->name = name;
879                                 info_bank->target = bank->target;
880                                 info_bank->driver = bank->driver;
881                                 info_bank->driver_priv = bank->driver_priv;
882                                 info_bank->bank_number = 1;
883                                 info_bank->base = 0x00200000;
884                                 info_bank->size = 0;
885                                 info_bank->chip_width = 0;
886                                 info_bank->bus_width = 0;
887                                 info_bank->erased_value = 0xff;
888                                 info_bank->default_padded_value = 0xff;
889                                 info_bank->write_start_alignment = 0;
890                                 info_bank->write_end_alignment = 0;
891                                 info_bank->minimal_write_gap = FLASH_WRITE_GAP_SECTOR;
892                                 info_bank->num_sectors = 0;
893                                 info_bank->sectors = NULL;
894                                 info_bank->num_prot_blocks = 0;
895                                 info_bank->prot_blocks = NULL;
896                                 info_bank->next = NULL;
897
898                                 /* Enable the new bank */
899                                 bank->next = info_bank;
900                         }
901                 }
902         }
903
904         if (MSP432P4 == msp432_bank->family_type) {
905                 /* Set up MSP432P4 specific flash parameters */
906                 if (0 == bank_id) {
907                         retval = target_read_u32(target, P4_FLASH_MAIN_SIZE_REG, &size);
908                         if (ERROR_OK != retval)
909                                 return retval;
910
911                         base = P4_FLASH_MAIN_BASE;
912                         sector_length = P4_SECTOR_LENGTH;
913                         num_sectors = size / sector_length;
914                 } else if (1 == bank_id) {
915                         if (msp432_bank->device_type == MSP432P411X ||
916                                 msp432_bank->device_type == MSP432P411X_GUESS) {
917                                 /* MSP432P411x has an info size register, use that for size */
918                                 retval = target_read_u32(target, P4_FLASH_INFO_SIZE_REG, &size);
919                                 if (ERROR_OK != retval)
920                                         return retval;
921                         } else {
922                                 /* All other MSP432P401x devices have fixed info region size */
923                                 size = 0x4000; /* 16 KB info region */
924                         }
925                         base = P4_FLASH_INFO_BASE;
926                         sector_length = P4_SECTOR_LENGTH;
927                         num_sectors = size / sector_length;
928                 } else {
929                         /* Invalid bank number somehow */
930                         return ERROR_FAIL;
931                 }
932         } else {
933                 /* Set up MSP432E4 specific flash parameters */
934                 base = E4_FLASH_BASE;
935                 size = E4_FLASH_SIZE;
936                 sector_length = E4_SECTOR_LENGTH;
937                 num_sectors = size / sector_length;
938         }
939
940         if (NULL != bank->sectors) {
941                 free(bank->sectors);
942                 bank->sectors = NULL;
943         }
944
945         bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);
946         if (NULL == bank->sectors)
947                 return ERROR_FAIL;
948
949         bank->base = base;
950         bank->size = size;
951         bank->write_start_alignment = 0;
952         bank->write_end_alignment = 0;
953         bank->num_sectors = num_sectors;
954         msp432_bank->sector_length = sector_length;
955
956         for (int i = 0; i < num_sectors; i++) {
957                 bank->sectors[i].offset = i * sector_length;
958                 bank->sectors[i].size = sector_length;
959                 bank->sectors[i].is_erased = -1;
960                 bank->sectors[i].is_protected = 0;
961         }
962
963         /* We've successfully determined the stats on this flash bank */
964         msp432_bank->probed[bank_id] = true;
965
966         /* If we fall through to here, then all went well */
967
968         return ERROR_OK;
969 }
970
971 static int msp432_auto_probe(struct flash_bank *bank)
972 {
973         struct msp432_bank *msp432_bank = bank->driver_priv;
974
975         int retval = ERROR_OK;
976
977         if (bank->bank_number < 0 || bank->bank_number > 1) {
978                 /* Invalid bank number somehow */
979                 return ERROR_FAIL;
980         }
981
982         if (!msp432_bank->probed[bank->bank_number])
983                 retval = msp432_probe(bank);
984
985         return retval;
986 }
987
988 static int msp432_protect_check(struct flash_bank *bank)
989 {
990         return ERROR_OK;
991 }
992
993 static int msp432_info(struct flash_bank *bank, char *buf, int buf_size)
994 {
995         struct msp432_bank *msp432_bank = bank->driver_priv;
996         int printed = 0;
997
998         switch (msp432_bank->device_type) {
999                 case MSP432P401X_DEPR:
1000                         if (0xFFFF == msp432_bank->device_id) {
1001                                 /* Very early pre-production silicon currently deprecated */
1002                                 printed = snprintf(buf, buf_size,
1003                                         "MSP432P401x pre-production device (deprecated silicon)\n"
1004                                         SUPPORT_MESSAGE);
1005                         } else {
1006                                 /* Revision A or B silicon, also deprecated */
1007                                 printed = snprintf(buf, buf_size,
1008                                         "MSP432P401x Device Rev %c (deprecated silicon)\n"
1009                                         SUPPORT_MESSAGE, (char)msp432_bank->hardware_rev);
1010                         }
1011                         break;
1012                 case MSP432P401X:
1013                         printed = snprintf(buf, buf_size,
1014                                 "MSP432P401x Device Rev %c\n",
1015                                 (char)msp432_bank->hardware_rev);
1016                         break;
1017                 case MSP432P411X:
1018                         printed = snprintf(buf, buf_size,
1019                                 "MSP432P411x Device Rev %c\n",
1020                                 (char)msp432_bank->hardware_rev);
1021                         break;
1022                 case MSP432E401Y:
1023                         printed = snprintf(buf, buf_size, "MSP432E401Y Device\n");
1024                         break;
1025                 case MSP432E411Y:
1026                         printed = snprintf(buf, buf_size, "MSP432E411Y Device\n");
1027                         break;
1028                 case MSP432E4X_GUESS:
1029                         printed = snprintf(buf, buf_size,
1030                                 "Unrecognized MSP432E4 DID0 and DID1 IDs (%08X, %08X)",
1031                                 msp432_bank->device_id, msp432_bank->hardware_rev);
1032                         break;
1033                 case MSP432P401X_GUESS:
1034                 case MSP432P411X_GUESS:
1035                 default:
1036                         printed = snprintf(buf, buf_size,
1037                                 "Unrecognized MSP432P4 Device ID and Hardware Rev (%04X, %02X)",
1038                                 msp432_bank->device_id, msp432_bank->hardware_rev);
1039                         break;
1040         }
1041
1042         buf_size -= printed;
1043
1044         if (0 > buf_size)
1045                 return ERROR_BUF_TOO_SMALL;
1046
1047         return ERROR_OK;
1048 }
1049
1050 static void msp432_flash_free_driver_priv(struct flash_bank *bank)
1051 {
1052         /* A single private struct is shared between main and info banks */
1053         /* Only free it on the call for main bank (#0) */
1054         if ((0 == bank->bank_number) && (NULL != bank->driver_priv))
1055                 free(bank->driver_priv);
1056         /* Forget about the private struct on both main and info banks */
1057         bank->driver_priv = NULL;
1058 }
1059
1060 static const struct command_registration msp432_exec_command_handlers[] = {
1061         {
1062                 .name = "mass_erase",
1063                 .handler = msp432_mass_erase_command,
1064                 .mode = COMMAND_EXEC,
1065                 .help = "Erase entire flash memory on device.",
1066                 .usage = "['main' | 'all']",
1067         },
1068         {
1069                 .name = "bsl",
1070                 .handler = msp432_bsl_command,
1071                 .mode = COMMAND_EXEC,
1072                 .help = "Allow BSL to be erased or written by flash commands.",
1073                 .usage = "['unlock' | 'lock']",
1074         },
1075         COMMAND_REGISTRATION_DONE
1076 };
1077
1078 static const struct command_registration msp432_command_handlers[] = {
1079         {
1080                 .name = "msp432",
1081                 .mode = COMMAND_EXEC,
1082                 .help = "MSP432 flash command group",
1083                 .usage = "",
1084                 .chain = msp432_exec_command_handlers,
1085         },
1086         COMMAND_REGISTRATION_DONE
1087 };
1088
1089 struct flash_driver msp432_flash = {
1090         .name = "msp432",
1091         .commands = msp432_command_handlers,
1092         .flash_bank_command = msp432_flash_bank_command,
1093         .erase = msp432_erase,
1094         .protect = msp432_protect,
1095         .write = msp432_write,
1096         .read = default_flash_read,
1097         .probe = msp432_probe,
1098         .auto_probe = msp432_auto_probe,
1099         .erase_check = default_flash_blank_check,
1100         .protect_check = msp432_protect_check,
1101         .info = msp432_info,
1102         .free_driver_priv = msp432_flash_free_driver_priv,
1103 };