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