OpenOCD
msp432.c
Go to the documentation of this file.
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;
40  uint32_t sector_length;
43  bool unlock_bsl;
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 
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 */
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 */
203 
204  return retval;
205 }
206 
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 */
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,
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,
339  }
340 
341  /* Check for working area to use for flash helper algorithm */
344 
347  if (retval != ERROR_OK)
348  return retval;
349 
350  /* Confirm the defined working address is the area we need to use */
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 */
363 
364  /* Initialize algorithm parameters to default values */
365  msp432_init_params(&algo_params);
366 
367  /* Write out parameters to target memory */
369  sizeof(algo_params), (uint8_t *)&algo_params);
370  if (retval != ERROR_OK)
371  return retval;
372 
373  /* Initialize stack pointer for flash helper algorithm */
374  init_reg_param(&reg_params[0], "sp", 32, PARAM_OUT);
375  buf_set_u32(reg_params[0].value, 0, 32, ALGO_STACK_POINTER_ADDR);
376 
377  /* Begin executing the flash helper algorithm */
378  retval = target_start_algorithm(target, 0, 0, 1, reg_params,
379  algo_entry_addr, 0, &msp432_bank->armv7m_info);
380  destroy_reg_param(&reg_params[0]);
381  if (retval != ERROR_OK) {
382  LOG_ERROR("msp432: Failed to start flash helper algorithm");
383  return retval;
384  }
385 
386  /*
387  * At this point, the algorithm is running on the target and
388  * ready to receive commands and data to flash the target
389  */
390 
391  /* Issue the init command to the flash helper algorithm */
392  retval = msp432_exec_cmd(target, &algo_params, FLASH_INIT);
393  if (retval != ERROR_OK)
394  return retval;
395 
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 
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,
425 
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");
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,
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 
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)
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
503  } else {
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)
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
557  } else if (1 != CMD_ARGC) {
558  /* Extra, unknown argument passed in */
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)
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;
585  msp432_bank->sector_length = 0x1000;
586  msp432_bank->probed_main = false;
587  msp432_bank->probed_info = false;
588  msp432_bank->unlock_bsl = false;
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");
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) &&
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 
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");
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)
761  else
762  size = count;
763 
764  /* Put next block of data to flash into buffer */
766  if (retval != ERROR_OK) {
767  LOG_ERROR("Unable to write data to target memory");
768  (void)msp432_quit(bank);
770  }
771 
772  /* Signal the flash helper algorithm that data is ready to flash */
774  data_ready);
775  if (retval != ERROR_OK) {
776  (void)msp432_quit(bank);
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 */
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 */
834  if (retval != ERROR_OK)
835  return retval;
836 
837  if (size == 0) {
838  /* This is likely an MSP432E4 */
840 
842  if (retval != ERROR_OK)
843  return retval;
844 
846 
848  if (retval != ERROR_OK)
849  return retval;
850 
852  } else {
853  /* This is likely an MSP432P4 */
855 
857  if (retval != ERROR_OK)
858  return retval;
859 
860  msp432_bank->device_id = device_id & 0xFFFF;
861 
863  if (retval != ERROR_OK)
864  return retval;
865 
867  }
868 
871 
872  if (msp432_bank->family_type == MSP432P4) {
873  /* Set up MSP432P4 specific flash parameters */
874  if (is_main) {
876  if (retval != ERROR_OK)
877  return retval;
878 
880  num_sectors = size / sector_length;
881  } else if (is_info) {
884  /* MSP432P411x has an info size register, use that for 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  }
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) {
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;
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 
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"
993  } else {
994  /* Revision A or B silicon, also deprecated */
995  command_print_sameline(cmd, "MSP432P401x Device Rev %c (deprecated silicon)\n"
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:
1015  "Unrecognized MSP432E4 DID0 and DID1 IDs (%08" PRIX32 ", %08" PRIX32 ")",
1017  break;
1018  case MSP432P401X_GUESS:
1019  case MSP432P411X_GUESS:
1020  default:
1022  "Unrecognized MSP432P4 Device ID and Hardware Rev (%04" PRIX32 ", %02" PRIX32 ")",
1024  break;
1025  }
1026 
1027  return ERROR_OK;
1028 }
1029 
1031 {
1032  /* Added to suppress warning, not needed for MSP432 flash */
1033  return ERROR_OK;
1034 }
1035 
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  },
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 = "",
1074  },
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 };
void init_reg_param(struct reg_param *param, char *reg_name, uint32_t size, enum param_direction direction)
Definition: algorithm.c:29
void destroy_reg_param(struct reg_param *param)
Definition: algorithm.c:37
@ PARAM_OUT
Definition: algorithm.h:16
@ ARM_MODE_THREAD
Definition: arm.h:86
const char * name
Definition: armv4_5.c:76
#define ARMV7M_COMMON_MAGIC
Definition: armv7m.h:218
Support functions to access arbitrary bits in a byte array.
static void buf_set_u32(uint8_t *_buffer, unsigned first, unsigned num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
Definition: binarybuffer.h:30
void command_print_sameline(struct command_invocation *cmd, const char *format,...)
Definition: command.c:450
#define CALL_COMMAND_HANDLER(name, extra ...)
Use this to macro to call a command helper (or a nested handler).
Definition: command.h:117
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:155
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:385
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:150
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:247
@ COMMAND_EXEC
Definition: command.h:40
uint8_t bank
Definition: esirisc.c:135
#define ERROR_FLASH_OPERATION_FAILED
Definition: flash/common.h:30
int default_flash_blank_check(struct flash_bank *bank)
Provides default erased-bank check handling.
void flash_bank_add(struct flash_bank *bank)
Adds a new NOR bank to the global list of banks.
int default_flash_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
Provides default read implementation for flash memory.
#define FLASH_BASE
Definition: fm4.c:23
void keep_alive(void)
Definition: log.c:419
static int64_t start
Definition: log.c:41
#define LOG_WARNING(expr ...)
Definition: log.h:120
#define ERROR_FAIL
Definition: log.h:161
#define LOG_ERROR(expr ...)
Definition: log.h:123
#define LOG_INFO(expr ...)
Definition: log.h:117
#define ERROR_OK
Definition: log.h:155
#define FLASH_INIT
Definition: lpc288x.c:44
#define P4_DEVICE_ID_REG
Definition: msp432.c:22
static int msp432_protect_check(struct flash_bank *bank)
Definition: msp432.c:1030
static int msp432_probe(struct flash_bank *bank)
Definition: msp432.c:808
static int msp432_auto_probe(struct flash_bank *bank)
Definition: msp432.c:964
#define E4_DID1_REG
Definition: msp432.c:27
static int msp432_wait_inactive(struct target *target, uint32_t buffer)
Definition: msp432.c:237
static int msp432_wait_return_code(struct target *target)
Definition: msp432.c:207
const struct flash_driver msp432_flash
Definition: msp432.c:1078
static const struct command_registration msp432_command_handlers[]
Definition: msp432.c:1067
FLASH_BANK_COMMAND_HANDLER(msp432_flash_bank_command)
Definition: msp432.c:568
#define SUPPORT_MESSAGE
Definition: msp432.c:31
static int msp432_mass_erase(struct flash_bank *bank, bool all)
Definition: msp432.c:432
static int msp432_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
Definition: msp432.c:598
static const struct command_registration msp432_exec_command_handlers[]
Definition: msp432.c:1049
#define P4_FLASH_MAIN_SIZE_REG
Definition: msp432.c:20
#define P4_HARDWARE_REV_REG
Definition: msp432.c:23
static int msp432_device_type(uint32_t family_type, uint32_t device_id, uint32_t hardware_rev)
Definition: msp432.c:65
#define E4_DID0_REG
Definition: msp432.c:26
static int msp432_quit(struct flash_bank *bank)
Definition: msp432.c:401
#define FLASH_TIMEOUT
Definition: msp432.c:29
static const char * msp432_return_text(uint32_t return_code)
Definition: msp432.c:149
static const uint8_t msp432p411x_algo[]
Definition: msp432.c:54
static void msp432_init_params(struct msp432_algo_params *algo_params)
Definition: msp432.c:171
#define P4_FLASH_INFO_SIZE_REG
Definition: msp432.c:21
static int msp432_info(struct flash_bank *bank, struct command_invocation *cmd)
Definition: msp432.c:983
static int msp432_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
Definition: msp432.c:673
static int msp432_exec_cmd(struct target *target, struct msp432_algo_params *algo_params, uint32_t command)
Definition: msp432.c:184
static int msp432_init(struct flash_bank *bank)
Definition: msp432.c:279
COMMAND_HANDLER(msp432_mass_erase_command)
Definition: msp432.c:478
static void msp432_flash_free_driver_priv(struct flash_bank *bank)
Definition: msp432.c:1036
static const uint8_t msp432p401x_algo[]
Definition: msp432.c:49
static const uint8_t msp432e4x_algo[]
Definition: msp432.c:59
#define ALGO_BASE_ADDR
Definition: msp432.h:42
#define FLASH_ERASE_INFO
Definition: msp432.h:85
#define ALGO_PARAMS_BASE_ADDR
Definition: msp432.h:45
#define ALGO_BUFFER2_STATUS_ADDR
Definition: msp432.h:51
#define ALGO_BUFFER1_STATUS_ADDR
Definition: msp432.h:50
#define E4_FLASH_SIZE
Definition: msp432.h:37
#define MSP432E401Y
Definition: msp432.h:22
#define FLASH_SUCCESS
Definition: msp432.h:71
#define MSP432_NO_FAMILY
Definition: msp432.h:11
#define FLASH_MASS_ERASE
Definition: msp432.h:62
#define MSP432P401X_DEPR
Definition: msp432.h:17
#define ALGO_STACK_POINTER_ADDR
Definition: msp432.h:54
#define ALGO_BUFFER_SIZE
Definition: msp432.h:57
#define E4_SECTOR_LENGTH
Definition: msp432.h:38
#define BUFFER_DATA_READY
Definition: msp432.h:81
#define FLASH_LOCK_BSL
Definition: msp432.h:88
#define FLASH_BUSY
Definition: msp432.h:70
#define BUFFER_ACTIVE
Definition: msp432.h:80
#define P4_ALGO_ENTRY_ADDR
Definition: msp432.h:33
#define MSP432_NO_TYPE
Definition: msp432.h:16
#define MSP432E4X_GUESS
Definition: msp432.h:24
#define ALGO_FLASH_COMMAND_ADDR
Definition: msp432.h:46
#define FLASH_WRONG_COMMAND
Definition: msp432.h:75
#define FLASH_ERROR
Definition: msp432.h:72
#define P4_SECTOR_LENGTH
Definition: msp432.h:32
#define FLASH_POWER_ERROR
Definition: msp432.h:76
#define E4_ALGO_ENTRY_ADDR
Definition: msp432.h:39
#define FLASH_UNLOCK_BSL
Definition: msp432.h:89
#define FLASH_VERIFY_ERROR
Definition: msp432.h:74
#define FLASH_ERASE_MAIN
Definition: msp432.h:84
#define MSP432P411X
Definition: msp432.h:19
#define MSP432P401X
Definition: msp432.h:18
#define MSP432P411X_GUESS
Definition: msp432.h:21
#define MSP432E411Y
Definition: msp432.h:23
#define FLASH_EXIT
Definition: msp432.h:66
#define P4_FLASH_INFO_BASE
Definition: msp432.h:31
#define FLASH_NO_COMMAND
Definition: msp432.h:61
#define FLASH_SECTOR_ERASE
Definition: msp432.h:63
#define MSP432E4
Definition: msp432.h:12
#define ALGO_WORKING_SIZE
Definition: msp432.h:58
#define ALGO_BUFFER1_ADDR
Definition: msp432.h:43
#define MSP432P4
Definition: msp432.h:13
#define FLASH_CONTINUOUS
Definition: msp432.h:67
#define FLASH_TIMEOUT_ERROR
Definition: msp432.h:73
#define MSP432P401X_GUESS
Definition: msp432.h:20
#define ALGO_RETURN_CODE_ADDR
Definition: msp432.h:47
#define BUFFER_INACTIVE
Definition: msp432.h:79
#define MIN(a, b)
Definition: replacements.h:22
size_t size
Size of the control block search area.
Definition: rtt/rtt.c:30
unsigned int common_magic
Definition: armv7m.h:293
enum arm_mode core_mode
Definition: armv7m.h:295
When run_command is called, a new instance will be created on the stack, filled with the proper value...
Definition: command.h:76
const char * name
Definition: command.h:229
Provides details of a flash bank, available either on-chip or through a major interface.
Definition: nor/core.h:75
Provides the implementation-independent structure that defines all of the callbacks required by OpenO...
Definition: nor/driver.h:39
const char * name
Gives a human-readable name of this flash driver, This field is used to select and initialize the dri...
Definition: nor/driver.h:44
Describes the geometry and status of a single flash sector within a flash bank.
Definition: nor/core.h:28
uint8_t unlock_bsl[4]
Definition: msp432.h:101
uint8_t _reserved0[4]
Definition: msp432.h:95
uint8_t length[4]
Definition: msp432.h:97
uint8_t buffer2_status[4]
Definition: msp432.h:99
uint8_t return_code[4]
Definition: msp432.h:94
uint8_t address[4]
Definition: msp432.h:96
uint8_t erase_param[4]
Definition: msp432.h:100
uint8_t buffer1_status[4]
Definition: msp432.h:98
uint8_t flash_command[4]
Definition: msp432.h:93
bool unlock_bsl
Definition: msp432.c:43
uint32_t sector_length
Definition: msp432.c:40
struct working_area * working_area
Definition: msp432.c:44
bool probed_info
Definition: msp432.c:42
uint32_t hardware_rev
Definition: msp432.c:37
struct armv7m_algorithm armv7m_info
Definition: msp432.c:45
int device_type
Definition: msp432.c:39
uint32_t device_id
Definition: msp432.c:36
int family_type
Definition: msp432.c:38
bool probed_main
Definition: msp432.c:41
uint8_t * value
Definition: algorithm.h:30
Definition: target.h:120
enum target_state state
Definition: target.h:162
target_addr_t address
Definition: target.h:90
int target_halt(struct target *target)
Definition: target.c:585
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
Definition: target.c:2408
int target_wait_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, target_addr_t exit_point, int timeout_ms, void *arch_info)
Waits for an algorithm started with target_start_algorithm() to complete.
Definition: target.c:931
int target_alloc_working_area(struct target *target, uint32_t size, struct working_area **area)
Definition: target.c:2129
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
Definition: target.c:2707
int target_free_working_area(struct target *target, struct working_area *area)
Free a working area.
Definition: target.c:2187
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
Definition: target.c:2616
int target_start_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, target_addr_t entry_point, target_addr_t exit_point, void *arch_info)
Executes a target-specific native code algorithm and leaves it running.
Definition: target.c:887
#define ERROR_TARGET_NOT_HALTED
Definition: target.h:792
@ TARGET_HALTED
Definition: target.h:55
#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE
Definition: target.h:796
int64_t timeval_ms(void)
static struct ublast_lowlevel_priv info
#define NULL
Definition: usb.h:16
uint8_t cmd
Definition: vdebug.c:1
uint8_t offset[4]
Definition: vdebug.c:9
uint8_t count[4]
Definition: vdebug.c:22