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 
206 {
207  uint32_t return_code = 0;
208  long long start_ms;
209  long long elapsed_ms;
210 
211  int retval = ERROR_OK;
212 
213  start_ms = timeval_ms();
214  while ((return_code == 0) || (return_code == FLASH_BUSY)) {
215  retval = target_read_u32(target, ALGO_RETURN_CODE_ADDR, &return_code);
216  if (retval != ERROR_OK)
217  return retval;
218 
219  elapsed_ms = timeval_ms() - start_ms;
220  if (elapsed_ms > FLASH_TIMEOUT)
221  break;
222 
223  keep_alive();
224  };
225 
226  if (return_code != FLASH_SUCCESS) {
227  LOG_ERROR("msp432: Flash operation failed: %s",
228  msp432_return_text(return_code));
229  return ERROR_FAIL;
230  }
231 
232  return ERROR_OK;
233 }
234 
235 static int msp432_wait_inactive(struct target *target, uint32_t buffer)
236 {
237  uint32_t status_code = BUFFER_ACTIVE;
238  uint32_t status_addr;
239  long long start_ms;
240  long long elapsed_ms;
241 
242  int retval;
243 
244  switch (buffer) {
245  case 1: /* Buffer 1 */
246  status_addr = ALGO_BUFFER1_STATUS_ADDR;
247  break;
248  case 2: /* Buffer 2 */
249  status_addr = ALGO_BUFFER2_STATUS_ADDR;
250  break;
251  default:
252  return ERROR_FAIL;
253  }
254 
255  start_ms = timeval_ms();
256  while (status_code != BUFFER_INACTIVE) {
257  retval = target_read_u32(target, status_addr, &status_code);
258  if (retval != ERROR_OK)
259  return retval;
260 
261  elapsed_ms = timeval_ms() - start_ms;
262  if (elapsed_ms > FLASH_TIMEOUT)
263  break;
264 
265  keep_alive();
266  };
267 
268  if (status_code != BUFFER_INACTIVE) {
269  LOG_ERROR(
270  "msp432: Flash operation failed: buffer not written to flash");
271  return ERROR_FAIL;
272  }
273 
274  return ERROR_OK;
275 }
276 
277 static int msp432_init(struct flash_bank *bank)
278 {
279  struct target *target = bank->target;
280  struct msp432_bank *msp432_bank = bank->driver_priv;
281  struct msp432_algo_params algo_params;
282  struct reg_param reg_params[1];
283 
284  const uint8_t *loader_code;
285  uint32_t loader_size;
286  uint32_t algo_entry_addr;
287  int retval;
288 
289  /* Make sure we've probed the flash to get the device and size */
290  retval = msp432_auto_probe(bank);
291  if (retval != ERROR_OK)
292  return retval;
293 
294  /* Choose appropriate flash helper algorithm */
295  switch (msp432_bank->device_type) {
296  case MSP432P401X:
297  case MSP432P401X_DEPR:
298  case MSP432P401X_GUESS:
299  default:
300  loader_code = msp432p401x_algo;
301  loader_size = sizeof(msp432p401x_algo);
302  algo_entry_addr = P4_ALGO_ENTRY_ADDR;
303  break;
304  case MSP432P411X:
305  case MSP432P411X_GUESS:
306  loader_code = msp432p411x_algo;
307  loader_size = sizeof(msp432p411x_algo);
308  algo_entry_addr = P4_ALGO_ENTRY_ADDR;
309  break;
310  case MSP432E401Y:
311  case MSP432E411Y:
312  case MSP432E4X_GUESS:
313  loader_code = msp432e4x_algo;
314  loader_size = sizeof(msp432e4x_algo);
315  algo_entry_addr = E4_ALGO_ENTRY_ADDR;
316  break;
317  }
318 
319  /* Issue warnings if this is a device we may not be able to flash */
322  /* Explicit device type check failed. Report this. */
323  LOG_WARNING(
324  "msp432: Unrecognized MSP432P4 Device ID and Hardware "
325  "Rev (%04" PRIX32 ", %02" PRIX32 ")", msp432_bank->device_id,
327  } else if (msp432_bank->device_type == MSP432P401X_DEPR) {
328  LOG_WARNING(
329  "msp432: MSP432P401x pre-production device (deprecated "
330  "silicon)\n" SUPPORT_MESSAGE);
331  } else if (msp432_bank->device_type == MSP432E4X_GUESS) {
332  /* Explicit device type check failed. Report this. */
333  LOG_WARNING(
334  "msp432: Unrecognized MSP432E4 DID0 and DID1 values "
335  "(%08" PRIX32 ", %08" PRIX32 ")", msp432_bank->device_id,
337  }
338 
339  /* Check for working area to use for flash helper algorithm */
342 
345  if (retval != ERROR_OK)
346  return retval;
347 
348  /* Confirm the defined working address is the area we need to use */
351 
352  /* Write flash helper algorithm into target memory */
353  retval = target_write_buffer(target, ALGO_BASE_ADDR, loader_size,
354  loader_code);
355  if (retval != ERROR_OK)
356  return retval;
357 
358  /* Initialize the ARMv7 specific info to run the algorithm */
361 
362  /* Initialize algorithm parameters to default values */
363  msp432_init_params(&algo_params);
364 
365  /* Write out parameters to target memory */
367  sizeof(algo_params), (uint8_t *)&algo_params);
368  if (retval != ERROR_OK)
369  return retval;
370 
371  /* Initialize stack pointer for flash helper algorithm */
372  init_reg_param(&reg_params[0], "sp", 32, PARAM_OUT);
373  buf_set_u32(reg_params[0].value, 0, 32, ALGO_STACK_POINTER_ADDR);
374 
375  /* Begin executing the flash helper algorithm */
376  retval = target_start_algorithm(target, 0, NULL, 1, reg_params,
377  algo_entry_addr, 0, &msp432_bank->armv7m_info);
378  destroy_reg_param(&reg_params[0]);
379  if (retval != ERROR_OK) {
380  LOG_ERROR("msp432: Failed to start flash helper algorithm");
381  return retval;
382  }
383 
384  /*
385  * At this point, the algorithm is running on the target and
386  * ready to receive commands and data to flash the target
387  */
388 
389  /* Issue the init command to the flash helper algorithm */
390  retval = msp432_exec_cmd(target, &algo_params, FLASH_INIT);
391  if (retval != ERROR_OK)
392  return retval;
393 
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 
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,
421 
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");
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,
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 
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)
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
499  } else {
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)
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
553  } else if (1 != CMD_ARGC) {
554  /* Extra, unknown argument passed in */
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)
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;
581  msp432_bank->sector_length = 0x1000;
582  msp432_bank->probed_main = false;
583  msp432_bank->probed_info = false;
584  msp432_bank->unlock_bsl = false;
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");
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) &&
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 
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 
678  bool is_info = bank->base == P4_FLASH_INFO_BASE;
679 
680  int retval;
681 
682  if (target->state != TARGET_HALTED) {
683  LOG_ERROR("Target not halted");
685  }
686 
687  /*
688  * Block attempts to write to read-only sectors of flash
689  * The TVL region in sector 1 of the info flash is always read-only
690  * The BSL region in sectors 2 and 3 of the info flash may be unlocked
691  * The helper algorithm will hang on attempts to write to TVL
692  */
693  if (is_info) {
694  /* Set read-only start to TVL sector */
695  uint32_t start = 0x1000;
696  /* Set read-only end after BSL region if locked */
697  uint32_t end = (msp432_bank->unlock_bsl) ? 0x2000 : 0x4000;
698  /* Check if request includes anything in read-only sectors */
699  if ((offset + count - 1) < start || offset >= end) {
700  /* The request includes no bytes in read-only sectors */
701  /* Fall out and process the request normally */
702  } else {
703  /* Send a request for anything before read-only sectors */
704  if (offset < start) {
705  uint32_t start_count = MIN(start - offset, count);
706  retval = msp432_write(bank, buffer, offset, start_count);
707  if (retval != ERROR_OK)
708  return retval;
709  }
710  /* Send a request for anything after read-only sectors */
711  if ((offset + count - 1) >= end) {
712  uint32_t skip = end - offset;
713  count -= skip;
714  offset += skip;
715  buffer += skip;
716  return msp432_write(bank, buffer, offset, count);
717  } else {
718  /* Request is entirely in read-only sectors */
719  return ERROR_OK;
720  }
721  }
722  }
723 
724  retval = msp432_init(bank);
725  if (retval != ERROR_OK)
726  return retval;
727 
728  /* Initialize algorithm parameters to default values */
729  msp432_init_params(&algo_params);
730 
731  /* Set up parameters for requested flash write operation */
732  buf_set_u32(algo_params.address, 0, 32, bank->base + offset);
733  buf_set_u32(algo_params.length, 0, 32, count);
734 
735  /* Check if this is the info bank */
736  if (is_info) {
737  /* And flag if BSL is unlocked */
738  if (msp432_bank->unlock_bsl)
739  buf_set_u32(algo_params.unlock_bsl, 0, 32, FLASH_UNLOCK_BSL);
740  }
741 
742  /* Set up flash helper algorithm to continuous flash mode */
743  retval = msp432_exec_cmd(target, &algo_params, FLASH_CONTINUOUS);
744  if (retval != ERROR_OK) {
745  (void)msp432_quit(bank);
746  return retval;
747  }
748 
749  /* Write requested data, one buffer at a time */
750  while (count > 0) {
751 
752  if (count > ALGO_BUFFER_SIZE)
754  else
755  size = count;
756 
757  /* Put next block of data to flash into buffer */
759  if (retval != ERROR_OK) {
760  LOG_ERROR("Unable to write data to target memory");
761  (void)msp432_quit(bank);
763  }
764 
765  /* Signal the flash helper algorithm that data is ready to flash */
767  data_ready);
768  if (retval != ERROR_OK) {
769  (void)msp432_quit(bank);
771  }
772 
773  retval = msp432_wait_inactive(target, 1);
774  if (retval != ERROR_OK) {
775  (void)msp432_quit(bank);
776  return retval;
777  }
778 
779  count -= size;
780  buffer += size;
781 
782  keep_alive();
783  }
784 
785  /* Confirm that the flash helper algorithm is finished */
787  if (retval != ERROR_OK) {
788  (void)msp432_quit(bank);
789  return retval;
790  }
791 
792  retval = msp432_quit(bank);
793  if (retval != ERROR_OK)
794  return retval;
795 
796  return retval;
797 }
798 
799 static int msp432_probe(struct flash_bank *bank)
800 {
801  struct target *target = bank->target;
802  struct msp432_bank *msp432_bank = bank->driver_priv;
803 
804  uint32_t device_id;
805  uint32_t hardware_rev;
806 
807  uint32_t sector_length;
808  uint32_t size;
809  unsigned int num_sectors;
810 
811  bool is_main = bank->base == FLASH_BASE;
812  bool is_info = bank->base == P4_FLASH_INFO_BASE;
813 
814  int retval;
815 
816  /* Check if this bank has already been successfully probed */
817  if (is_main && msp432_bank->probed_main)
818  return ERROR_OK;
819  if (is_info && msp432_bank->probed_info)
820  return ERROR_OK;
821 
822  /* Read the flash size register to determine this is a P4 or not */
823  /* MSP432P4s will return the size of flash. MSP432E4s will return zero */
825  if (retval != ERROR_OK)
826  return retval;
827 
828  if (size == 0) {
829  /* This is likely an MSP432E4 */
831 
833  if (retval != ERROR_OK)
834  return retval;
835 
837 
839  if (retval != ERROR_OK)
840  return retval;
841 
843  } else {
844  /* This is likely an MSP432P4 */
846 
848  if (retval != ERROR_OK)
849  return retval;
850 
851  msp432_bank->device_id = device_id & 0xFFFF;
852 
854  if (retval != ERROR_OK)
855  return retval;
856 
858  }
859 
862 
863  if (msp432_bank->family_type == MSP432P4) {
864  /* Set up MSP432P4 specific flash parameters */
865  if (is_main) {
867  if (retval != ERROR_OK)
868  return retval;
869 
871  num_sectors = size / sector_length;
872  } else if (is_info) {
875  /* MSP432P411x has an info size register, use that for size */
877  if (retval != ERROR_OK)
878  return retval;
879  } else {
880  /* All other MSP432P401x devices have fixed info region size */
881  size = 0x4000; /* 16 KB info region */
882  }
884  num_sectors = size / sector_length;
885  } else {
886  /* Invalid bank somehow */
887  return ERROR_FAIL;
888  }
889  } else {
890  /* Set up MSP432E4 specific flash parameters */
891  if (is_main) {
894  num_sectors = size / sector_length;
895  } else {
896  /* Invalid bank somehow */
897  return ERROR_FAIL;
898  }
899  }
900 
901  free(bank->sectors);
902  bank->sectors = NULL;
903 
904  if (num_sectors > 0) {
905  bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);
906  if (!bank->sectors)
907  return ERROR_FAIL;
908  }
909 
910  bank->size = size;
911  bank->write_start_alignment = 0;
912  bank->write_end_alignment = 0;
913  bank->num_sectors = num_sectors;
915 
916  for (unsigned int i = 0; i < num_sectors; i++) {
917  bank->sectors[i].offset = i * sector_length;
918  bank->sectors[i].size = sector_length;
919  bank->sectors[i].is_erased = -1;
920  bank->sectors[i].is_protected = 0;
921  }
922 
923  /* We've successfully determined the stats on this flash bank */
924  if (is_main)
925  msp432_bank->probed_main = true;
926  if (is_info)
927  msp432_bank->probed_info = true;
928 
929  if (is_main && MSP432P4 == msp432_bank->family_type) {
930  /* Create the info flash bank needed by MSP432P4 variants */
931  struct flash_bank *info = calloc(1, sizeof(struct flash_bank));
932  if (!info)
933  return ERROR_FAIL;
934 
935  /* Create a name for the info bank, append "_1" to main name */
936  char *name = malloc(strlen(bank->name) + 3);
937  strcpy(name, bank->name);
938  strcat(name, "_1");
939 
940  /* Initialize info bank */
941  info->name = name;
942  info->target = bank->target;
943  info->driver = bank->driver;
944  info->driver_priv = msp432_bank;
945  info->base = P4_FLASH_INFO_BASE;
946 
948  }
949 
950  /* If we fall through to here, then all went well */
951 
952  return ERROR_OK;
953 }
954 
955 static int msp432_auto_probe(struct flash_bank *bank)
956 {
957  struct msp432_bank *msp432_bank = bank->driver_priv;
958 
959  bool is_main = bank->base == FLASH_BASE;
960  bool is_info = bank->base == P4_FLASH_INFO_BASE;
961 
962  int retval = ERROR_OK;
963 
964  if (is_main)
965  if (!msp432_bank->probed_main)
966  retval = msp432_probe(bank);
967  if (is_info)
968  if (!msp432_bank->probed_info)
969  retval = msp432_probe(bank);
970 
971  return retval;
972 }
973 
974 static int msp432_info(struct flash_bank *bank, struct command_invocation *cmd)
975 {
976  struct msp432_bank *msp432_bank = bank->driver_priv;
977 
978  switch (msp432_bank->device_type) {
979  case MSP432P401X_DEPR:
980  if (msp432_bank->device_id == 0xFFFF) {
981  /* Very early pre-production silicon currently deprecated */
982  command_print_sameline(cmd, "MSP432P401x pre-production device (deprecated silicon)\n"
984  } else {
985  /* Revision A or B silicon, also deprecated */
986  command_print_sameline(cmd, "MSP432P401x Device Rev %c (deprecated silicon)\n"
988  }
989  break;
990  case MSP432P401X:
991  command_print_sameline(cmd, "MSP432P401x Device Rev %c\n",
992  (char)msp432_bank->hardware_rev);
993  break;
994  case MSP432P411X:
995  command_print_sameline(cmd, "MSP432P411x Device Rev %c\n",
996  (char)msp432_bank->hardware_rev);
997  break;
998  case MSP432E401Y:
999  command_print_sameline(cmd, "MSP432E401Y Device\n");
1000  break;
1001  case MSP432E411Y:
1002  command_print_sameline(cmd, "MSP432E411Y Device\n");
1003  break;
1004  case MSP432E4X_GUESS:
1006  "Unrecognized MSP432E4 DID0 and DID1 IDs (%08" PRIX32 ", %08" PRIX32 ")",
1008  break;
1009  case MSP432P401X_GUESS:
1010  case MSP432P411X_GUESS:
1011  default:
1013  "Unrecognized MSP432P4 Device ID and Hardware Rev (%04" PRIX32 ", %02" PRIX32 ")",
1015  break;
1016  }
1017 
1018  return ERROR_OK;
1019 }
1020 
1022 {
1023  /* Added to suppress warning, not needed for MSP432 flash */
1024  return ERROR_OK;
1025 }
1026 
1028 {
1029  bool is_main = bank->base == FLASH_BASE;
1030 
1031  /* A single private struct is shared between main and info banks */
1032  /* Only free it on the call for main bank */
1033  if (is_main)
1034  free(bank->driver_priv);
1035 
1036  /* Forget about the private struct on both main and info banks */
1037  bank->driver_priv = NULL;
1038 }
1039 
1040 static const struct command_registration msp432_exec_command_handlers[] = {
1041  {
1042  .name = "mass_erase",
1043  .handler = msp432_mass_erase_command,
1044  .mode = COMMAND_EXEC,
1045  .help = "Erase entire flash memory on device.",
1046  .usage = "bank_id ['main' | 'all']",
1047  },
1048  {
1049  .name = "bsl",
1050  .handler = msp432_bsl_command,
1051  .mode = COMMAND_EXEC,
1052  .help = "Allow BSL to be erased or written by flash commands.",
1053  .usage = "bank_id ['unlock' | 'lock']",
1054  },
1056 };
1057 
1058 static const struct command_registration msp432_command_handlers[] = {
1059  {
1060  .name = "msp432",
1061  .mode = COMMAND_EXEC,
1062  .help = "MSP432 flash command group",
1063  .usage = "",
1065  },
1067 };
1068 
1069 const struct flash_driver msp432_flash = {
1070  .name = "msp432",
1071  .commands = msp432_command_handlers,
1072  .flash_bank_command = msp432_flash_bank_command,
1073  .erase = msp432_erase,
1074  .write = msp432_write,
1075  .read = default_flash_read,
1076  .probe = msp432_probe,
1077  .auto_probe = msp432_auto_probe,
1078  .erase_check = default_flash_blank_check,
1079  .protect_check = msp432_protect_check,
1080  .info = msp432_info,
1081  .free_driver_priv = msp432_flash_free_driver_priv,
1082 };
void init_reg_param(struct reg_param *param, const 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:38
@ PARAM_OUT
Definition: algorithm.h:16
@ ARM_MODE_THREAD
Definition: arm.h:94
const char * name
Definition: armv4_5.c:76
#define ARMV7M_COMMON_MAGIC
Definition: armv7m.h:229
#define FLASH_BASE
Definition: artery.h:12
Support functions to access arbitrary bits in a byte array.
static void buf_set_u32(uint8_t *_buffer, unsigned int first, unsigned int num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
Definition: binarybuffer.h:34
void command_print_sameline(struct command_invocation *cmd, const char *format,...)
Definition: command.c:378
#define CALL_COMMAND_HANDLER(name, extra ...)
Use this to macro to call a command helper (or a nested handler).
Definition: command.h:123
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:161
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:405
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:156
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:256
@ COMMAND_EXEC
Definition: command.h:40
uint64_t buffer
Pointer to data buffer to send over SPI.
Definition: dw-spi-helper.h:0
uint32_t size
Size of dw_spi_transaction::buffer.
Definition: dw-spi-helper.h:4
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.
void keep_alive(void)
Definition: log.c:437
static int64_t start
Definition: log.c:38
#define LOG_WARNING(expr ...)
Definition: log.h:144
#define ERROR_FAIL
Definition: log.h:188
#define LOG_ERROR(expr ...)
Definition: log.h:147
#define LOG_INFO(expr ...)
Definition: log.h:141
#define ERROR_OK
Definition: log.h:182
#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:1021
static int msp432_probe(struct flash_bank *bank)
Definition: msp432.c:799
static int msp432_auto_probe(struct flash_bank *bank)
Definition: msp432.c:955
#define E4_DID1_REG
Definition: msp432.c:27
static int msp432_wait_inactive(struct target *target, uint32_t buffer)
Definition: msp432.c:235
static int msp432_wait_return_code(struct target *target)
Definition: msp432.c:205
const struct flash_driver msp432_flash
Definition: msp432.c:1069
static const struct command_registration msp432_command_handlers[]
Definition: msp432.c:1058
FLASH_BANK_COMMAND_HANDLER(msp432_flash_bank_command)
Definition: msp432.c:564
#define SUPPORT_MESSAGE
Definition: msp432.c:31
static int msp432_mass_erase(struct flash_bank *bank, bool all)
Definition: msp432.c:428
static int msp432_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
Definition: msp432.c:594
static const struct command_registration msp432_exec_command_handlers[]
Definition: msp432.c:1040
#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:397
#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:974
static int msp432_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
Definition: msp432.c:669
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:277
COMMAND_HANDLER(msp432_mass_erase_command)
Definition: msp432.c:474
static void msp432_flash_free_driver_priv(struct flash_bank *bank)
Definition: msp432.c:1027
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
unsigned int common_magic
Definition: armv7m.h:306
enum arm_mode core_mode
Definition: armv7m.h:308
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:239
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:119
enum target_state state
Definition: target.h:167
target_addr_t address
Definition: target.h:89
int target_halt(struct target *target)
Definition: target.c:517
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
Definition: target.c:2369
int target_alloc_working_area(struct target *target, uint32_t size, struct working_area **area)
Definition: target.c:2090
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
Definition: target.c:2635
int target_free_working_area(struct target *target, struct working_area *area)
Free a working area.
Definition: target.c:2148
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
Definition: target.c:2561
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, unsigned int timeout_ms, void *arch_info)
Waits for an algorithm started with target_start_algorithm() to complete.
Definition: target.c:873
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:828
#define ERROR_TARGET_NOT_HALTED
Definition: target.h:817
@ TARGET_HALTED
Definition: target.h:58
#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE
Definition: target.h:821
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