target/xtensa: avoid IHI for writes to non-executable memory
[openocd.git] / src / flash / nor / msp432.c
blob5e2935d02bf41d510847f5159ef8f528df16c615
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2018 by Texas Instruments, Inc. *
5 ***************************************************************************/
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
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>
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
25 /* MSP432E4 hardware registers */
26 #define E4_DID0_REG 0x400FE000
27 #define E4_DID1_REG 0x400FE004
29 #define FLASH_TIMEOUT 8000
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"
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;
48 /* Flash helper algorithm for MSP432P401x targets */
49 static const uint8_t msp432p401x_algo[] = {
50 #include "../../../contrib/loaders/flash/msp432/msp432p401x_algo.inc"
53 /* Flash helper algorithm for MSP432P411x targets */
54 static const uint8_t msp432p411x_algo[] = {
55 #include "../../../contrib/loaders/flash/msp432/msp432p411x_algo.inc"
58 /* Flash helper algorithm for MSP432E4x targets */
59 static const uint8_t msp432e4x_algo[] = {
60 #include "../../../contrib/loaders/flash/msp432/msp432e4x_algo.inc"
63 static int msp432_auto_probe(struct flash_bank *bank);
65 static int msp432_device_type(uint32_t family_type, uint32_t device_id,
66 uint32_t hardware_rev)
68 int device_type = MSP432_NO_TYPE;
70 if (family_type == MSP432E4) {
71 /* MSP432E4 device family */
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;
84 } else {
85 /* Wild guess that this is an MSP432E4 */
86 device_type = MSP432E4X_GUESS;
88 } else {
89 /* MSP432P4 device family */
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;
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;
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;
142 break;
146 return device_type;
149 static const char *msp432_return_text(uint32_t return_code)
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";
171 static void msp432_init_params(struct msp432_algo_params *algo_params)
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);
184 static int msp432_exec_cmd(struct target *target, struct msp432_algo_params
185 *algo_params, uint32_t command)
187 int retval;
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);
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;
201 /* Write out command to target memory */
202 retval = target_write_u32(target, ALGO_FLASH_COMMAND_ADDR, command);
204 return retval;
207 static int msp432_wait_return_code(struct target *target)
209 uint32_t return_code = 0;
210 long long start_ms;
211 long long elapsed_ms;
213 int retval = ERROR_OK;
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;
221 elapsed_ms = timeval_ms() - start_ms;
222 if (elapsed_ms > 500)
223 keep_alive();
224 if (elapsed_ms > FLASH_TIMEOUT)
225 break;
228 if (return_code != FLASH_SUCCESS) {
229 LOG_ERROR("msp432: Flash operation failed: %s",
230 msp432_return_text(return_code));
231 return ERROR_FAIL;
234 return ERROR_OK;
237 static int msp432_wait_inactive(struct target *target, uint32_t buffer)
239 uint32_t status_code = BUFFER_ACTIVE;
240 uint32_t status_addr;
241 long long start_ms;
242 long long elapsed_ms;
244 int retval;
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;
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;
263 elapsed_ms = timeval_ms() - start_ms;
264 if (elapsed_ms > 500)
265 keep_alive();
266 if (elapsed_ms > FLASH_TIMEOUT)
267 break;
270 if (status_code != BUFFER_INACTIVE) {
271 LOG_ERROR(
272 "msp432: Flash operation failed: buffer not written to flash");
273 return ERROR_FAIL;
276 return ERROR_OK;
279 static int msp432_init(struct flash_bank *bank)
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];
286 const uint8_t *loader_code;
287 uint32_t loader_size;
288 uint32_t algo_entry_addr;
289 int retval;
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;
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;
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);
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;
345 retval = target_alloc_working_area(target, ALGO_WORKING_SIZE,
346 &msp432_bank->working_area);
347 if (retval != ERROR_OK)
348 return retval;
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;
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;
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;
364 /* Initialize algorithm parameters to default values */
365 msp432_init_params(&algo_params);
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;
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);
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;
387 * At this point, the algorithm is running on the target and
388 * ready to receive commands and data to flash the target
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;
396 retval = msp432_wait_return_code(target);
398 return retval;
401 static int msp432_quit(struct flash_bank *bank)
403 struct target *target = bank->target;
404 struct msp432_bank *msp432_bank = bank->driver_priv;
405 struct msp432_algo_params algo_params;
407 int retval;
409 /* Initialize algorithm parameters to default values */
410 msp432_init_params(&algo_params);
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;
417 (void)msp432_wait_return_code(target);
419 /* Regardless of the return code, attempt to halt the target */
420 (void)target_halt(target);
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);
426 target_free_working_area(target, msp432_bank->working_area);
427 msp432_bank->working_area = NULL;
429 return retval;
432 static int msp432_mass_erase(struct flash_bank *bank, bool all)
434 struct target *target = bank->target;
435 struct msp432_bank *msp432_bank = bank->driver_priv;
436 struct msp432_algo_params algo_params;
438 int retval;
440 if (target->state != TARGET_HALTED) {
441 LOG_ERROR("Target not halted");
442 return ERROR_TARGET_NOT_HALTED;
445 retval = msp432_init(bank);
446 if (retval != ERROR_OK)
447 return retval;
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);
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;
465 retval = msp432_wait_return_code(target);
466 if (retval != ERROR_OK) {
467 (void)msp432_quit(bank);
468 return retval;
471 retval = msp432_quit(bank);
472 if (retval != ERROR_OK)
473 return retval;
475 return retval;
478 COMMAND_HANDLER(msp432_mass_erase_command)
480 struct flash_bank *bank;
481 struct msp432_bank *msp432_bank;
482 bool all;
484 int retval;
486 if (1 > CMD_ARGC)
487 return ERROR_COMMAND_SYNTAX_ERROR;
489 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
490 if (retval != ERROR_OK)
491 return retval;
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;
507 msp432_bank = bank->driver_priv;
509 if (msp432_bank->family_type == MSP432E4) {
510 /* MSP432E4 does not have main vs info regions, ignore "all" */
511 all = false;
514 retval = msp432_mass_erase(bank, all);
515 if (retval != ERROR_OK)
516 return retval;
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");
526 return ERROR_OK;
529 COMMAND_HANDLER(msp432_bsl_command)
531 struct flash_bank *bank;
532 struct msp432_bank *msp432_bank;
534 int retval;
536 if (1 > CMD_ARGC)
537 return ERROR_COMMAND_SYNTAX_ERROR;
539 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
540 if (retval != ERROR_OK)
541 return retval;
543 msp432_bank = bank->driver_priv;
545 if (msp432_bank->family_type == MSP432E4) {
546 LOG_WARNING("msp432: MSP432E4 does not have a BSL region");
547 return ERROR_OK;
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;
562 LOG_INFO("msp432: BSL flash region is currently %slocked",
563 msp432_bank->unlock_bsl ? "un" : "");
565 return ERROR_OK;
568 FLASH_BANK_COMMAND_HANDLER(msp432_flash_bank_command)
570 struct msp432_bank *msp432_bank;
572 if (CMD_ARGC < 6)
573 return ERROR_COMMAND_SYNTAX_ERROR;
575 /* Create shared private struct for flash banks */
576 msp432_bank = malloc(sizeof(struct msp432_bank));
577 if (!msp432_bank)
578 return ERROR_FAIL;
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;
591 /* Finish up initial settings here */
592 bank->driver_priv = msp432_bank;
593 bank->base = FLASH_BASE;
595 return ERROR_OK;
598 static int msp432_erase(struct flash_bank *bank, unsigned int first,
599 unsigned int last)
601 struct target *target = bank->target;
602 struct msp432_bank *msp432_bank = bank->driver_priv;
603 struct msp432_algo_params algo_params;
605 bool is_main = bank->base == FLASH_BASE;
606 bool is_info = bank->base == P4_FLASH_INFO_BASE;
608 int retval;
610 if (target->state != TARGET_HALTED) {
611 LOG_ERROR("Target not halted");
612 return ERROR_TARGET_NOT_HALTED;
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);
621 retval = msp432_init(bank);
622 if (retval != ERROR_OK)
623 return retval;
625 /* Initialize algorithm parameters to default values */
626 msp432_init_params(&algo_params);
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);
636 /* Erase requested sectors one by one */
637 for (unsigned int i = first; i <= last; i++) {
639 /* Skip TVL (read-only) sector of the info bank */
640 if (is_info && 1 == i)
641 continue;
643 /* Skip BSL sectors of info bank if locked */
644 if (is_info && (2 == i || 3 == i) &&
645 !msp432_bank->unlock_bsl)
646 continue;
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));
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;
659 retval = msp432_wait_return_code(target);
660 if (retval != ERROR_OK) {
661 (void)msp432_quit(bank);
662 return retval;
666 retval = msp432_quit(bank);
667 if (retval != ERROR_OK)
668 return retval;
670 return retval;
673 static int msp432_write(struct flash_bank *bank, const uint8_t *buffer,
674 uint32_t offset, uint32_t count)
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;
684 bool is_info = bank->base == P4_FLASH_INFO_BASE;
686 int retval;
688 if (target->state != TARGET_HALTED) {
689 LOG_ERROR("Target not halted");
690 return ERROR_TARGET_NOT_HALTED;
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
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;
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;
730 retval = msp432_init(bank);
731 if (retval != ERROR_OK)
732 return retval;
734 /* Initialize algorithm parameters to default values */
735 msp432_init_params(&algo_params);
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);
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);
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;
755 /* Write requested data, one buffer at a time */
756 start_ms = timeval_ms();
757 while (count > 0) {
759 if (count > ALGO_BUFFER_SIZE)
760 size = ALGO_BUFFER_SIZE;
761 else
762 size = count;
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;
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;
780 retval = msp432_wait_inactive(target, 1);
781 if (retval != ERROR_OK) {
782 (void)msp432_quit(bank);
783 return retval;
786 count -= size;
787 buffer += size;
789 elapsed_ms = timeval_ms() - start_ms;
790 if (elapsed_ms > 500)
791 keep_alive();
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;
801 retval = msp432_quit(bank);
802 if (retval != ERROR_OK)
803 return retval;
805 return retval;
808 static int msp432_probe(struct flash_bank *bank)
810 struct target *target = bank->target;
811 struct msp432_bank *msp432_bank = bank->driver_priv;
813 uint32_t device_id;
814 uint32_t hardware_rev;
816 uint32_t sector_length;
817 uint32_t size;
818 unsigned int num_sectors;
820 bool is_main = bank->base == FLASH_BASE;
821 bool is_info = bank->base == P4_FLASH_INFO_BASE;
823 int retval;
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;
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;
837 if (size == 0) {
838 /* This is likely an MSP432E4 */
839 msp432_bank->family_type = MSP432E4;
841 retval = target_read_u32(target, E4_DID0_REG, &device_id);
842 if (retval != ERROR_OK)
843 return retval;
845 msp432_bank->device_id = device_id;
847 retval = target_read_u32(target, E4_DID1_REG, &hardware_rev);
848 if (retval != ERROR_OK)
849 return retval;
851 msp432_bank->hardware_rev = hardware_rev;
852 } else {
853 /* This is likely an MSP432P4 */
854 msp432_bank->family_type = MSP432P4;
856 retval = target_read_u32(target, P4_DEVICE_ID_REG, &device_id);
857 if (retval != ERROR_OK)
858 return retval;
860 msp432_bank->device_id = device_id & 0xFFFF;
862 retval = target_read_u32(target, P4_HARDWARE_REV_REG, &hardware_rev);
863 if (retval != ERROR_OK)
864 return retval;
866 msp432_bank->hardware_rev = hardware_rev & 0xFF;
869 msp432_bank->device_type = msp432_device_type(msp432_bank->family_type,
870 msp432_bank->device_id, msp432_bank->hardware_rev);
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;
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 */
892 sector_length = P4_SECTOR_LENGTH;
893 num_sectors = size / sector_length;
894 } else {
895 /* Invalid bank somehow */
896 return ERROR_FAIL;
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;
910 free(bank->sectors);
911 bank->sectors = NULL;
913 if (num_sectors > 0) {
914 bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);
915 if (!bank->sectors)
916 return ERROR_FAIL;
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;
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;
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;
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;
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");
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;
956 flash_bank_add(info);
959 /* If we fall through to here, then all went well */
961 return ERROR_OK;
964 static int msp432_auto_probe(struct flash_bank *bank)
966 struct msp432_bank *msp432_bank = bank->driver_priv;
968 bool is_main = bank->base == FLASH_BASE;
969 bool is_info = bank->base == P4_FLASH_INFO_BASE;
971 int retval = ERROR_OK;
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);
980 return retval;
983 static int msp432_info(struct flash_bank *bank, struct command_invocation *cmd)
985 struct msp432_bank *msp432_bank = bank->driver_priv;
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);
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;
1027 return ERROR_OK;
1030 static int msp432_protect_check(struct flash_bank *bank)
1032 /* Added to suppress warning, not needed for MSP432 flash */
1033 return ERROR_OK;
1036 static void msp432_flash_free_driver_priv(struct flash_bank *bank)
1038 bool is_main = bank->base == FLASH_BASE;
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);
1045 /* Forget about the private struct on both main and info banks */
1046 bank->driver_priv = NULL;
1049 static const struct command_registration msp432_exec_command_handlers[] = {
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']",
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']",
1064 COMMAND_REGISTRATION_DONE
1067 static const struct command_registration msp432_command_handlers[] = {
1069 .name = "msp432",
1070 .mode = COMMAND_EXEC,
1071 .help = "MSP432 flash command group",
1072 .usage = "",
1073 .chain = msp432_exec_command_handlers,
1075 COMMAND_REGISTRATION_DONE
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,