jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / 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, NULL, 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 };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)