jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / 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 (family_type == MSP432E4) {
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 (retval != ERROR_OK)
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 ((return_code == 0) || (return_code == FLASH_BUSY)) {
213 retval = target_read_u32(target, ALGO_RETURN_CODE_ADDR, &return_code);
214 if (retval != ERROR_OK)
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 (return_code != FLASH_SUCCESS) {
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 (status_code != BUFFER_INACTIVE) {
255 retval = target_read_u32(target, status_addr, &status_code);
256 if (retval != ERROR_OK)
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 (status_code != BUFFER_INACTIVE) {
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 (retval != ERROR_OK)
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 (msp432_bank->device_type == MSP432P401X_GUESS ||
319 msp432_bank->device_type == MSP432P411X_GUESS) {
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 (msp432_bank->device_type == MSP432P401X_DEPR) {
326 LOG_WARNING(
327 "msp432: MSP432P401x pre-production device (deprecated "
328 "silicon)\n" SUPPORT_MESSAGE);
329 } else if (msp432_bank->device_type == MSP432E4X_GUESS) {
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 target_free_working_area(target, msp432_bank->working_area);
339 msp432_bank->working_area = NULL;
340
341 retval = target_alloc_working_area(target, ALGO_WORKING_SIZE,
342 &msp432_bank->working_area);
343 if (retval != ERROR_OK)
344 return retval;
345
346 /* Confirm the defined working address is the area we need to use */
347 if (msp432_bank->working_area->address != ALGO_BASE_ADDR)
348 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
349
350 /* Write flash helper algorithm into target memory */
351 retval = target_write_buffer(target, ALGO_BASE_ADDR, loader_size,
352 loader_code);
353 if (retval != ERROR_OK)
354 return retval;
355
356 /* Initialize the ARMv7 specific info to run the algorithm */
357 msp432_bank->armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
358 msp432_bank->armv7m_info.core_mode = ARM_MODE_THREAD;
359
360 /* Initialize algorithm parameters to default values */
361 msp432_init_params(&algo_params);
362
363 /* Write out parameters to target memory */
364 retval = target_write_buffer(target, ALGO_PARAMS_BASE_ADDR,
365 sizeof(algo_params), (uint8_t *)&algo_params);
366 if (retval != ERROR_OK)
367 return retval;
368
369 /* Initialize stack pointer for flash helper algorithm */
370 init_reg_param(&reg_params[0], "sp", 32, PARAM_OUT);
371 buf_set_u32(reg_params[0].value, 0, 32, ALGO_STACK_POINTER_ADDR);
372
373 /* Begin executing the flash helper algorithm */
374 retval = target_start_algorithm(target, 0, 0, 1, reg_params,
375 algo_entry_addr, 0, &msp432_bank->armv7m_info);
376 destroy_reg_param(&reg_params[0]);
377 if (retval != ERROR_OK) {
378 LOG_ERROR("msp432: Failed to start flash helper algorithm");
379 return retval;
380 }
381
382 /*
383 * At this point, the algorithm is running on the target and
384 * ready to receive commands and data to flash the target
385 */
386
387 /* Issue the init command to the flash helper algorithm */
388 retval = msp432_exec_cmd(target, &algo_params, FLASH_INIT);
389 if (retval != ERROR_OK)
390 return retval;
391
392 retval = msp432_wait_return_code(target);
393
394 return retval;
395 }
396
397 static int msp432_quit(struct flash_bank *bank)
398 {
399 struct target *target = bank->target;
400 struct msp432_bank *msp432_bank = bank->driver_priv;
401 struct msp432_algo_params algo_params;
402
403 int retval;
404
405 /* Initialize algorithm parameters to default values */
406 msp432_init_params(&algo_params);
407
408 /* Issue the exit command to the flash helper algorithm */
409 retval = msp432_exec_cmd(target, &algo_params, FLASH_EXIT);
410 if (retval != ERROR_OK)
411 return retval;
412
413 (void)msp432_wait_return_code(target);
414
415 /* Regardless of the return code, attempt to halt the target */
416 (void)target_halt(target);
417
418 /* Now confirm target halted and clean up from flash helper algorithm */
419 retval = target_wait_algorithm(target, 0, NULL, 0, NULL, 0, FLASH_TIMEOUT,
420 &msp432_bank->armv7m_info);
421
422 target_free_working_area(target, msp432_bank->working_area);
423 msp432_bank->working_area = NULL;
424
425 return retval;
426 }
427
428 static int msp432_mass_erase(struct flash_bank *bank, bool all)
429 {
430 struct target *target = bank->target;
431 struct msp432_bank *msp432_bank = bank->driver_priv;
432 struct msp432_algo_params algo_params;
433
434 int retval;
435
436 if (target->state != TARGET_HALTED) {
437 LOG_ERROR("Target not halted");
438 return ERROR_TARGET_NOT_HALTED;
439 }
440
441 retval = msp432_init(bank);
442 if (retval != ERROR_OK)
443 return retval;
444
445 /* Initialize algorithm parameters to default values */
446 msp432_init_params(&algo_params);
447 if (all) {
448 buf_set_u32(algo_params.erase_param, 0, 32,
449 FLASH_ERASE_MAIN | FLASH_ERASE_INFO);
450 if (msp432_bank->unlock_bsl)
451 buf_set_u32(algo_params.unlock_bsl, 0, 32, FLASH_UNLOCK_BSL);
452 }
453
454 /* Issue the mass erase command to the flash helper algorithm */
455 retval = msp432_exec_cmd(target, &algo_params, FLASH_MASS_ERASE);
456 if (retval != ERROR_OK) {
457 (void)msp432_quit(bank);
458 return retval;
459 }
460
461 retval = msp432_wait_return_code(target);
462 if (retval != ERROR_OK) {
463 (void)msp432_quit(bank);
464 return retval;
465 }
466
467 retval = msp432_quit(bank);
468 if (retval != ERROR_OK)
469 return retval;
470
471 return retval;
472 }
473
474 COMMAND_HANDLER(msp432_mass_erase_command)
475 {
476 struct flash_bank *bank;
477 struct msp432_bank *msp432_bank;
478 bool all;
479
480 int retval;
481
482 if (1 > CMD_ARGC)
483 return ERROR_COMMAND_SYNTAX_ERROR;
484
485 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
486 if (retval != ERROR_OK)
487 return retval;
488
489 if (1 == CMD_ARGC) {
490 all = false;
491 } else if (2 == CMD_ARGC) {
492 /* Check argument for how much to erase */
493 if (strcmp(CMD_ARGV[1], "main") == 0)
494 all = false;
495 else if (strcmp(CMD_ARGV[1], "all") == 0)
496 all = true;
497 else
498 return ERROR_COMMAND_SYNTAX_ERROR;
499 } else {
500 return ERROR_COMMAND_SYNTAX_ERROR;
501 }
502
503 msp432_bank = bank->driver_priv;
504
505 if (msp432_bank->family_type == MSP432E4) {
506 /* MSP432E4 does not have main vs info regions, ignore "all" */
507 all = false;
508 }
509
510 retval = msp432_mass_erase(bank, all);
511 if (retval != ERROR_OK)
512 return retval;
513
514 if (msp432_bank->family_type == MSP432E4) {
515 /* MSP432E4 does not have main vs info regions */
516 LOG_INFO("msp432: Mass erase of flash is complete");
517 } else {
518 LOG_INFO("msp432: Mass erase of %s is complete",
519 all ? "main + information flash" : "main flash");
520 }
521
522 return ERROR_OK;
523 }
524
525 COMMAND_HANDLER(msp432_bsl_command)
526 {
527 struct flash_bank *bank;
528 struct msp432_bank *msp432_bank;
529
530 int retval;
531
532 if (1 > CMD_ARGC)
533 return ERROR_COMMAND_SYNTAX_ERROR;
534
535 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
536 if (retval != ERROR_OK)
537 return retval;
538
539 msp432_bank = bank->driver_priv;
540
541 if (msp432_bank->family_type == MSP432E4) {
542 LOG_WARNING("msp432: MSP432E4 does not have a BSL region");
543 return ERROR_OK;
544 }
545
546 if (2 == CMD_ARGC) {
547 if (strcmp(CMD_ARGV[1], "lock") == 0)
548 msp432_bank->unlock_bsl = false;
549 else if (strcmp(CMD_ARGV[1], "unlock") == 0)
550 msp432_bank->unlock_bsl = true;
551 else
552 return ERROR_COMMAND_SYNTAX_ERROR;
553 } else if (1 != CMD_ARGC) {
554 /* Extra, unknown argument passed in */
555 return ERROR_COMMAND_SYNTAX_ERROR;
556 }
557
558 LOG_INFO("msp432: BSL flash region is currently %slocked",
559 msp432_bank->unlock_bsl ? "un" : "");
560
561 return ERROR_OK;
562 }
563
564 FLASH_BANK_COMMAND_HANDLER(msp432_flash_bank_command)
565 {
566 struct msp432_bank *msp432_bank;
567
568 if (CMD_ARGC < 6)
569 return ERROR_COMMAND_SYNTAX_ERROR;
570
571 /* Create shared private struct for flash banks */
572 msp432_bank = malloc(sizeof(struct msp432_bank));
573 if (!msp432_bank)
574 return ERROR_FAIL;
575
576 /* Initialize private flash information */
577 msp432_bank->device_id = 0;
578 msp432_bank->hardware_rev = 0;
579 msp432_bank->family_type = MSP432_NO_FAMILY;
580 msp432_bank->device_type = MSP432_NO_TYPE;
581 msp432_bank->sector_length = 0x1000;
582 msp432_bank->probed_main = false;
583 msp432_bank->probed_info = false;
584 msp432_bank->unlock_bsl = false;
585 msp432_bank->working_area = NULL;
586
587 /* Finish up initial settings here */
588 bank->driver_priv = msp432_bank;
589 bank->base = FLASH_BASE;
590
591 return ERROR_OK;
592 }
593
594 static int msp432_erase(struct flash_bank *bank, unsigned int first,
595 unsigned int last)
596 {
597 struct target *target = bank->target;
598 struct msp432_bank *msp432_bank = bank->driver_priv;
599 struct msp432_algo_params algo_params;
600
601 bool is_main = bank->base == FLASH_BASE;
602 bool is_info = bank->base == P4_FLASH_INFO_BASE;
603
604 int retval;
605
606 if (target->state != TARGET_HALTED) {
607 LOG_ERROR("Target not halted");
608 return ERROR_TARGET_NOT_HALTED;
609 }
610
611 /* Do a mass erase if user requested all sectors of main flash */
612 if (is_main && (first == 0) && (last == (bank->num_sectors - 1))) {
613 /* Request mass erase of main flash */
614 return msp432_mass_erase(bank, false);
615 }
616
617 retval = msp432_init(bank);
618 if (retval != ERROR_OK)
619 return retval;
620
621 /* Initialize algorithm parameters to default values */
622 msp432_init_params(&algo_params);
623
624 /* Adjust params if this is the info bank */
625 if (is_info) {
626 buf_set_u32(algo_params.erase_param, 0, 32, FLASH_ERASE_INFO);
627 /* And flag if BSL is unlocked */
628 if (msp432_bank->unlock_bsl)
629 buf_set_u32(algo_params.unlock_bsl, 0, 32, FLASH_UNLOCK_BSL);
630 }
631
632 /* Erase requested sectors one by one */
633 for (unsigned int i = first; i <= last; i++) {
634
635 /* Skip TVL (read-only) sector of the info bank */
636 if (is_info && 1 == i)
637 continue;
638
639 /* Skip BSL sectors of info bank if locked */
640 if (is_info && (2 == i || 3 == i) &&
641 !msp432_bank->unlock_bsl)
642 continue;
643
644 /* Convert sector number to starting address of sector */
645 buf_set_u32(algo_params.address, 0, 32, bank->base +
646 (i * msp432_bank->sector_length));
647
648 /* Issue the sector erase command to the flash helper algorithm */
649 retval = msp432_exec_cmd(target, &algo_params, FLASH_SECTOR_ERASE);
650 if (retval != ERROR_OK) {
651 (void)msp432_quit(bank);
652 return retval;
653 }
654
655 retval = msp432_wait_return_code(target);
656 if (retval != ERROR_OK) {
657 (void)msp432_quit(bank);
658 return retval;
659 }
660 }
661
662 retval = msp432_quit(bank);
663 if (retval != ERROR_OK)
664 return retval;
665
666 return retval;
667 }
668
669 static int msp432_write(struct flash_bank *bank, const uint8_t *buffer,
670 uint32_t offset, uint32_t count)
671 {
672 struct target *target = bank->target;
673 struct msp432_bank *msp432_bank = bank->driver_priv;
674 struct msp432_algo_params algo_params;
675 uint32_t size;
676 uint32_t data_ready = BUFFER_DATA_READY;
677 long long start_ms;
678 long long elapsed_ms;
679
680 bool is_info = bank->base == P4_FLASH_INFO_BASE;
681
682 int retval;
683
684 if (target->state != TARGET_HALTED) {
685 LOG_ERROR("Target not halted");
686 return ERROR_TARGET_NOT_HALTED;
687 }
688
689 /*
690 * Block attempts to write to read-only sectors of flash
691 * The TVL region in sector 1 of the info flash is always read-only
692 * The BSL region in sectors 2 and 3 of the info flash may be unlocked
693 * The helper algorithm will hang on attempts to write to TVL
694 */
695 if (is_info) {
696 /* Set read-only start to TVL sector */
697 uint32_t start = 0x1000;
698 /* Set read-only end after BSL region if locked */
699 uint32_t end = (msp432_bank->unlock_bsl) ? 0x2000 : 0x4000;
700 /* Check if request includes anything in read-only sectors */
701 if ((offset + count - 1) < start || offset >= end) {
702 /* The request includes no bytes in read-only sectors */
703 /* Fall out and process the request normally */
704 } else {
705 /* Send a request for anything before read-only sectors */
706 if (offset < start) {
707 uint32_t start_count = MIN(start - offset, count);
708 retval = msp432_write(bank, buffer, offset, start_count);
709 if (retval != ERROR_OK)
710 return retval;
711 }
712 /* Send a request for anything after read-only sectors */
713 if ((offset + count - 1) >= end) {
714 uint32_t skip = end - offset;
715 count -= skip;
716 offset += skip;
717 buffer += skip;
718 return msp432_write(bank, buffer, offset, count);
719 } else {
720 /* Request is entirely in read-only sectors */
721 return ERROR_OK;
722 }
723 }
724 }
725
726 retval = msp432_init(bank);
727 if (retval != ERROR_OK)
728 return retval;
729
730 /* Initialize algorithm parameters to default values */
731 msp432_init_params(&algo_params);
732
733 /* Set up parameters for requested flash write operation */
734 buf_set_u32(algo_params.address, 0, 32, bank->base + offset);
735 buf_set_u32(algo_params.length, 0, 32, count);
736
737 /* Check if this is the info bank */
738 if (is_info) {
739 /* And flag if BSL is unlocked */
740 if (msp432_bank->unlock_bsl)
741 buf_set_u32(algo_params.unlock_bsl, 0, 32, FLASH_UNLOCK_BSL);
742 }
743
744 /* Set up flash helper algorithm to continuous flash mode */
745 retval = msp432_exec_cmd(target, &algo_params, FLASH_CONTINUOUS);
746 if (retval != ERROR_OK) {
747 (void)msp432_quit(bank);
748 return retval;
749 }
750
751 /* Write requested data, one buffer at a time */
752 start_ms = timeval_ms();
753 while (count > 0) {
754
755 if (count > ALGO_BUFFER_SIZE)
756 size = ALGO_BUFFER_SIZE;
757 else
758 size = count;
759
760 /* Put next block of data to flash into buffer */
761 retval = target_write_buffer(target, ALGO_BUFFER1_ADDR, size, buffer);
762 if (retval != ERROR_OK) {
763 LOG_ERROR("Unable to write data to target memory");
764 (void)msp432_quit(bank);
765 return ERROR_FLASH_OPERATION_FAILED;
766 }
767
768 /* Signal the flash helper algorithm that data is ready to flash */
769 retval = target_write_u32(target, ALGO_BUFFER1_STATUS_ADDR,
770 data_ready);
771 if (retval != ERROR_OK) {
772 (void)msp432_quit(bank);
773 return ERROR_FLASH_OPERATION_FAILED;
774 }
775
776 retval = msp432_wait_inactive(target, 1);
777 if (retval != ERROR_OK) {
778 (void)msp432_quit(bank);
779 return retval;
780 }
781
782 count -= size;
783 buffer += size;
784
785 elapsed_ms = timeval_ms() - start_ms;
786 if (elapsed_ms > 500)
787 keep_alive();
788 }
789
790 /* Confirm that the flash helper algorithm is finished */
791 retval = msp432_wait_return_code(target);
792 if (retval != ERROR_OK) {
793 (void)msp432_quit(bank);
794 return retval;
795 }
796
797 retval = msp432_quit(bank);
798 if (retval != ERROR_OK)
799 return retval;
800
801 return retval;
802 }
803
804 static int msp432_probe(struct flash_bank *bank)
805 {
806 struct target *target = bank->target;
807 struct msp432_bank *msp432_bank = bank->driver_priv;
808
809 uint32_t device_id;
810 uint32_t hardware_rev;
811
812 uint32_t sector_length;
813 uint32_t size;
814 unsigned int num_sectors;
815
816 bool is_main = bank->base == FLASH_BASE;
817 bool is_info = bank->base == P4_FLASH_INFO_BASE;
818
819 int retval;
820
821 /* Check if this bank has already been successfully probed */
822 if (is_main && msp432_bank->probed_main)
823 return ERROR_OK;
824 if (is_info && msp432_bank->probed_info)
825 return ERROR_OK;
826
827 /* Read the flash size register to determine this is a P4 or not */
828 /* MSP432P4s will return the size of flash. MSP432E4s will return zero */
829 retval = target_read_u32(target, P4_FLASH_MAIN_SIZE_REG, &size);
830 if (retval != ERROR_OK)
831 return retval;
832
833 if (size == 0) {
834 /* This is likely an MSP432E4 */
835 msp432_bank->family_type = MSP432E4;
836
837 retval = target_read_u32(target, E4_DID0_REG, &device_id);
838 if (retval != ERROR_OK)
839 return retval;
840
841 msp432_bank->device_id = device_id;
842
843 retval = target_read_u32(target, E4_DID1_REG, &hardware_rev);
844 if (retval != ERROR_OK)
845 return retval;
846
847 msp432_bank->hardware_rev = hardware_rev;
848 } else {
849 /* This is likely an MSP432P4 */
850 msp432_bank->family_type = MSP432P4;
851
852 retval = target_read_u32(target, P4_DEVICE_ID_REG, &device_id);
853 if (retval != ERROR_OK)
854 return retval;
855
856 msp432_bank->device_id = device_id & 0xFFFF;
857
858 retval = target_read_u32(target, P4_HARDWARE_REV_REG, &hardware_rev);
859 if (retval != ERROR_OK)
860 return retval;
861
862 msp432_bank->hardware_rev = hardware_rev & 0xFF;
863 }
864
865 msp432_bank->device_type = msp432_device_type(msp432_bank->family_type,
866 msp432_bank->device_id, msp432_bank->hardware_rev);
867
868 if (msp432_bank->family_type == MSP432P4) {
869 /* Set up MSP432P4 specific flash parameters */
870 if (is_main) {
871 retval = target_read_u32(target, P4_FLASH_MAIN_SIZE_REG, &size);
872 if (retval != ERROR_OK)
873 return retval;
874
875 sector_length = P4_SECTOR_LENGTH;
876 num_sectors = size / sector_length;
877 } else if (is_info) {
878 if (msp432_bank->device_type == MSP432P411X ||
879 msp432_bank->device_type == MSP432P411X_GUESS) {
880 /* MSP432P411x has an info size register, use that for size */
881 retval = target_read_u32(target, P4_FLASH_INFO_SIZE_REG, &size);
882 if (retval != ERROR_OK)
883 return retval;
884 } else {
885 /* All other MSP432P401x devices have fixed info region size */
886 size = 0x4000; /* 16 KB info region */
887 }
888 sector_length = P4_SECTOR_LENGTH;
889 num_sectors = size / sector_length;
890 } else {
891 /* Invalid bank somehow */
892 return ERROR_FAIL;
893 }
894 } else {
895 /* Set up MSP432E4 specific flash parameters */
896 if (is_main) {
897 size = E4_FLASH_SIZE;
898 sector_length = E4_SECTOR_LENGTH;
899 num_sectors = size / sector_length;
900 } else {
901 /* Invalid bank somehow */
902 return ERROR_FAIL;
903 }
904 }
905
906 free(bank->sectors);
907 bank->sectors = NULL;
908
909 if (num_sectors > 0) {
910 bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);
911 if (!bank->sectors)
912 return ERROR_FAIL;
913 }
914
915 bank->size = size;
916 bank->write_start_alignment = 0;
917 bank->write_end_alignment = 0;
918 bank->num_sectors = num_sectors;
919 msp432_bank->sector_length = sector_length;
920
921 for (unsigned int i = 0; i < num_sectors; i++) {
922 bank->sectors[i].offset = i * sector_length;
923 bank->sectors[i].size = sector_length;
924 bank->sectors[i].is_erased = -1;
925 bank->sectors[i].is_protected = 0;
926 }
927
928 /* We've successfully determined the stats on this flash bank */
929 if (is_main)
930 msp432_bank->probed_main = true;
931 if (is_info)
932 msp432_bank->probed_info = true;
933
934 if (is_main && MSP432P4 == msp432_bank->family_type) {
935 /* Create the info flash bank needed by MSP432P4 variants */
936 struct flash_bank *info = calloc(sizeof(struct flash_bank), 1);
937 if (!info)
938 return ERROR_FAIL;
939
940 /* Create a name for the info bank, append "_1" to main name */
941 char *name = malloc(strlen(bank->name) + 3);
942 strcpy(name, bank->name);
943 strcat(name, "_1");
944
945 /* Initialize info bank */
946 info->name = name;
947 info->target = bank->target;
948 info->driver = bank->driver;
949 info->driver_priv = msp432_bank;
950 info->base = P4_FLASH_INFO_BASE;
951
952 flash_bank_add(info);
953 }
954
955 /* If we fall through to here, then all went well */
956
957 return ERROR_OK;
958 }
959
960 static int msp432_auto_probe(struct flash_bank *bank)
961 {
962 struct msp432_bank *msp432_bank = bank->driver_priv;
963
964 bool is_main = bank->base == FLASH_BASE;
965 bool is_info = bank->base == P4_FLASH_INFO_BASE;
966
967 int retval = ERROR_OK;
968
969 if (is_main)
970 if (!msp432_bank->probed_main)
971 retval = msp432_probe(bank);
972 if (is_info)
973 if (!msp432_bank->probed_info)
974 retval = msp432_probe(bank);
975
976 return retval;
977 }
978
979 static int msp432_info(struct flash_bank *bank, struct command_invocation *cmd)
980 {
981 struct msp432_bank *msp432_bank = bank->driver_priv;
982
983 switch (msp432_bank->device_type) {
984 case MSP432P401X_DEPR:
985 if (msp432_bank->device_id == 0xFFFF) {
986 /* Very early pre-production silicon currently deprecated */
987 command_print_sameline(cmd, "MSP432P401x pre-production device (deprecated silicon)\n"
988 SUPPORT_MESSAGE);
989 } else {
990 /* Revision A or B silicon, also deprecated */
991 command_print_sameline(cmd, "MSP432P401x Device Rev %c (deprecated silicon)\n"
992 SUPPORT_MESSAGE, (char)msp432_bank->hardware_rev);
993 }
994 break;
995 case MSP432P401X:
996 command_print_sameline(cmd, "MSP432P401x Device Rev %c\n",
997 (char)msp432_bank->hardware_rev);
998 break;
999 case MSP432P411X:
1000 command_print_sameline(cmd, "MSP432P411x Device Rev %c\n",
1001 (char)msp432_bank->hardware_rev);
1002 break;
1003 case MSP432E401Y:
1004 command_print_sameline(cmd, "MSP432E401Y Device\n");
1005 break;
1006 case MSP432E411Y:
1007 command_print_sameline(cmd, "MSP432E411Y Device\n");
1008 break;
1009 case MSP432E4X_GUESS:
1010 command_print_sameline(cmd,
1011 "Unrecognized MSP432E4 DID0 and DID1 IDs (%08" PRIX32 ", %08" PRIX32 ")",
1012 msp432_bank->device_id, msp432_bank->hardware_rev);
1013 break;
1014 case MSP432P401X_GUESS:
1015 case MSP432P411X_GUESS:
1016 default:
1017 command_print_sameline(cmd,
1018 "Unrecognized MSP432P4 Device ID and Hardware Rev (%04" PRIX32 ", %02" PRIX32 ")",
1019 msp432_bank->device_id, msp432_bank->hardware_rev);
1020 break;
1021 }
1022
1023 return ERROR_OK;
1024 }
1025
1026 static int msp432_protect_check(struct flash_bank *bank)
1027 {
1028 /* Added to suppress warning, not needed for MSP432 flash */
1029 return ERROR_OK;
1030 }
1031
1032 static void msp432_flash_free_driver_priv(struct flash_bank *bank)
1033 {
1034 bool is_main = bank->base == FLASH_BASE;
1035
1036 /* A single private struct is shared between main and info banks */
1037 /* Only free it on the call for main bank */
1038 if (is_main)
1039 free(bank->driver_priv);
1040
1041 /* Forget about the private struct on both main and info banks */
1042 bank->driver_priv = NULL;
1043 }
1044
1045 static const struct command_registration msp432_exec_command_handlers[] = {
1046 {
1047 .name = "mass_erase",
1048 .handler = msp432_mass_erase_command,
1049 .mode = COMMAND_EXEC,
1050 .help = "Erase entire flash memory on device.",
1051 .usage = "bank_id ['main' | 'all']",
1052 },
1053 {
1054 .name = "bsl",
1055 .handler = msp432_bsl_command,
1056 .mode = COMMAND_EXEC,
1057 .help = "Allow BSL to be erased or written by flash commands.",
1058 .usage = "bank_id ['unlock' | 'lock']",
1059 },
1060 COMMAND_REGISTRATION_DONE
1061 };
1062
1063 static const struct command_registration msp432_command_handlers[] = {
1064 {
1065 .name = "msp432",
1066 .mode = COMMAND_EXEC,
1067 .help = "MSP432 flash command group",
1068 .usage = "",
1069 .chain = msp432_exec_command_handlers,
1070 },
1071 COMMAND_REGISTRATION_DONE
1072 };
1073
1074 const struct flash_driver msp432_flash = {
1075 .name = "msp432",
1076 .commands = msp432_command_handlers,
1077 .flash_bank_command = msp432_flash_bank_command,
1078 .erase = msp432_erase,
1079 .write = msp432_write,
1080 .read = default_flash_read,
1081 .probe = msp432_probe,
1082 .auto_probe = msp432_auto_probe,
1083 .erase_check = default_flash_blank_check,
1084 .protect_check = msp432_protect_check,
1085 .info = msp432_info,
1086 .free_driver_priv = msp432_flash_free_driver_priv,
1087 };

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)