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