You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1080 lines
30 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2006 by Magnus Lundin *
  3. * lundin@mlu.mine.nu *
  4. * *
  5. * Copyright (C) 2008 by Spencer Oliver *
  6. * spen@spen-soft.co.uk *
  7. * *
  8. * This program is free software; you can redistribute it and/or modify *
  9. * it under the terms of the GNU General Public License as published by *
  10. * the Free Software Foundation; either version 2 of the License, or *
  11. * (at your option) any later version. *
  12. * *
  13. * This program is distributed in the hope that it will be useful, *
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  16. * GNU General Public License for more details. *
  17. * *
  18. * You should have received a copy of the GNU General Public License *
  19. * along with this program; if not, write to the *
  20. * Free Software Foundation, Inc., *
  21. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  22. ***************************************************************************/
  23. /***************************************************************************
  24. * STELLARIS is tested on LM3S811, LM3S6965
  25. ***************************************************************************/
  26. #ifdef HAVE_CONFIG_H
  27. #include "config.h"
  28. #endif
  29. #include "stellaris.h"
  30. #include "armv7m.h"
  31. #include "binarybuffer.h"
  32. #define DID0_VER(did0) ((did0 >> 28)&0x07)
  33. static int stellaris_register_commands(struct command_context_s *cmd_ctx);
  34. static int stellaris_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
  35. static int stellaris_erase(struct flash_bank_s *bank, int first, int last);
  36. static int stellaris_protect(struct flash_bank_s *bank, int set, int first, int last);
  37. static int stellaris_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count);
  38. static int stellaris_auto_probe(struct flash_bank_s *bank);
  39. static int stellaris_probe(struct flash_bank_s *bank);
  40. static int stellaris_protect_check(struct flash_bank_s *bank);
  41. static int stellaris_info(struct flash_bank_s *bank, char *buf, int buf_size);
  42. static int stellaris_read_part_info(struct flash_bank_s *bank);
  43. static uint32_t stellaris_get_flash_status(flash_bank_t *bank);
  44. static void stellaris_set_flash_mode(flash_bank_t *bank,int mode);
  45. //static uint32_t stellaris_wait_status_busy(flash_bank_t *bank, uint32_t waitbits, int timeout);
  46. static int stellaris_handle_mass_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
  47. static int stellaris_mass_erase(struct flash_bank_s *bank);
  48. flash_driver_t stellaris_flash =
  49. {
  50. .name = "stellaris",
  51. .register_commands = stellaris_register_commands,
  52. .flash_bank_command = stellaris_flash_bank_command,
  53. .erase = stellaris_erase,
  54. .protect = stellaris_protect,
  55. .write = stellaris_write,
  56. .probe = stellaris_probe,
  57. .auto_probe = stellaris_auto_probe,
  58. .erase_check = default_flash_mem_blank_check,
  59. .protect_check = stellaris_protect_check,
  60. .info = stellaris_info
  61. };
  62. static struct {
  63. uint32_t partno;
  64. char *partname;
  65. } StellarisParts[] =
  66. {
  67. {0x01,"LM3S101"},
  68. {0x02,"LM3S102"},
  69. {0x03,"LM3S1625"},
  70. {0x04,"LM3S1626"},
  71. {0x05,"LM3S1627"},
  72. {0x06,"LM3S1607"},
  73. {0x10,"LM3S1776"},
  74. {0x19,"LM3S300"},
  75. {0x11,"LM3S301"},
  76. {0x12,"LM3S310"},
  77. {0x1A,"LM3S308"},
  78. {0x13,"LM3S315"},
  79. {0x14,"LM3S316"},
  80. {0x17,"LM3S317"},
  81. {0x18,"LM3S318"},
  82. {0x15,"LM3S328"},
  83. {0x2A,"LM3S600"},
  84. {0x21,"LM3S601"},
  85. {0x2B,"LM3S608"},
  86. {0x22,"LM3S610"},
  87. {0x23,"LM3S611"},
  88. {0x24,"LM3S612"},
  89. {0x25,"LM3S613"},
  90. {0x26,"LM3S615"},
  91. {0x28,"LM3S617"},
  92. {0x29,"LM3S618"},
  93. {0x27,"LM3S628"},
  94. {0x38,"LM3S800"},
  95. {0x31,"LM3S801"},
  96. {0x39,"LM3S808"},
  97. {0x32,"LM3S811"},
  98. {0x33,"LM3S812"},
  99. /*{0x33,"LM3S2616"},*/
  100. {0x34,"LM3S815"},
  101. {0x36,"LM3S817"},
  102. {0x37,"LM3S818"},
  103. {0x35,"LM3S828"},
  104. {0x39,"LM3S2276"},
  105. {0x3A,"LM3S2776"},
  106. {0x43,"LM3S3651"},
  107. {0x44,"LM3S3739"},
  108. {0x45,"LM3S3749"},
  109. {0x46,"LM3S3759"},
  110. {0x48,"LM3S3768"},
  111. {0x49,"LM3S3748"},
  112. {0x50,"LM3S2678"},
  113. {0x51,"LM3S2110"},
  114. {0x52,"LM3S2739"},
  115. {0x53,"LM3S2651"},
  116. {0x54,"LM3S2939"},
  117. {0x55,"LM3S2965"},
  118. {0x56,"LM3S2432"},
  119. {0x57,"LM3S2620"},
  120. {0x58,"LM3S2950"},
  121. {0x59,"LM3S2412"},
  122. {0x5A,"LM3S2533"},
  123. {0x61,"LM3S8630"},
  124. {0x62,"LM3S8970"},
  125. {0x63,"LM3S8730"},
  126. {0x64,"LM3S8530"},
  127. {0x65,"LM3S8930"},
  128. {0x71,"LM3S6610"},
  129. {0x72,"LM3S6950"},
  130. {0x73,"LM3S6965"},
  131. {0x74,"LM3S6110"},
  132. {0x75,"LM3S6432"},
  133. {0x76,"LM3S6537"},
  134. {0x77,"LM3S6753"},
  135. {0x78,"LM3S6952"},
  136. {0x80,"LM3S2671"},
  137. {0x81,"LM3S5632"},
  138. {0x82,"LM3S6422"},
  139. {0x83,"LM3S6633"},
  140. {0x84,"LM3S2139"},
  141. {0x85,"LM3S2637"},
  142. {0x86,"LM3S8738"},
  143. {0x88,"LM3S8938"},
  144. {0x89,"LM3S6938"},
  145. {0x8A,"LM3S5652"},
  146. {0x8B,"LM3S6637"},
  147. {0x8C,"LM3S8933"},
  148. {0x8D,"LM3S8733"},
  149. {0x8E,"LM3S8538"},
  150. {0x8F,"LM3S2948"},
  151. {0x91,"LM3S5662"},
  152. {0x96,"LM3S5732"},
  153. {0x97,"LM3S5737"},
  154. {0x99,"LM3S5747"},
  155. {0x9A,"LM3S5752"},
  156. {0x9B,"LM3S5757"},
  157. {0x9C,"LM3S5762"},
  158. {0x9D,"LM3S5767"},
  159. {0xA0,"LM3S5739"},
  160. {0xA1,"LM3S6100"},
  161. {0xA2,"LM3S2410"},
  162. {0xA3,"LM3S6730"},
  163. {0xA4,"LM3S2730"},
  164. {0xA5,"LM3S6420"},
  165. {0xA6,"LM3S8962"},
  166. {0xA7,"LM3S5749"},
  167. {0xA8,"LM3S5769"},
  168. {0xA9,"LM3S5768"},
  169. {0xB3,"LM3S1635"},
  170. {0xB4,"LM3S1850"},
  171. {0xB5,"LM3S1960"},
  172. {0xB7,"LM3S1937"},
  173. {0xB8,"LM3S1968"},
  174. {0xB9,"LM3S1751"},
  175. {0xBA,"LM3S1439"},
  176. {0xBB,"LM3S1512"},
  177. {0xBC,"LM3S1435"},
  178. {0xBD,"LM3S1637"},
  179. {0xBE,"LM3S1958"},
  180. {0xBF,"LM3S1110"},
  181. {0xC0,"LM3S1620"},
  182. {0xC1,"LM3S1150"},
  183. {0xC2,"LM3S1165"},
  184. {0xC3,"LM3S1133"},
  185. {0xC4,"LM3S1162"},
  186. {0xC5,"LM3S1138"},
  187. {0xC6,"LM3S1332"},
  188. {0xC7,"LM3S1538"},
  189. {0xD0,"LM3S6815"},
  190. {0xD1,"LM3S6816"},
  191. {0xD2,"LM3S6915"},
  192. {0xD3,"LM3S6916"},
  193. {0xD4,"LM3S2016"},
  194. {0xD5,"LM3S1615"},
  195. {0xD6,"LM3S1616"},
  196. {0xD7,"LM3S8971"},
  197. {0xD8,"LM3S1108"},
  198. {0xD9,"LM3S1101"},
  199. {0xDA,"LM3S1608"},
  200. {0xDB,"LM3S1601"},
  201. {0xDC,"LM3S1918"},
  202. {0xDD,"LM3S1911"},
  203. {0xDE,"LM3S2108"},
  204. {0xDF,"LM3S2101"},
  205. {0xE0,"LM3S2608"},
  206. {0xE1,"LM3S2601"},
  207. {0xE2,"LM3S2918"},
  208. {0xE3,"LM3S2911"},
  209. {0xE4,"LM3S6118"},
  210. {0xE5,"LM3S6111"},
  211. {0xE6,"LM3S6618"},
  212. {0xE7,"LM3S6611"},
  213. {0xE8,"LM3S6918"},
  214. {0xE9,"LM3S6911"},
  215. {0,"Unknown part"}
  216. };
  217. static char * StellarisClassname[5] =
  218. {
  219. "Sandstorm",
  220. "Fury",
  221. "Unknown",
  222. "DustDevil",
  223. "Tempest"
  224. };
  225. /***************************************************************************
  226. * openocd command interface *
  227. ***************************************************************************/
  228. /* flash_bank stellaris <base> <size> 0 0 <target#>
  229. */
  230. static int stellaris_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
  231. {
  232. stellaris_flash_bank_t *stellaris_info;
  233. if (argc < 6)
  234. {
  235. LOG_WARNING("incomplete flash_bank stellaris configuration");
  236. return ERROR_FLASH_BANK_INVALID;
  237. }
  238. stellaris_info = calloc(sizeof(stellaris_flash_bank_t), 1);
  239. bank->base = 0x0;
  240. bank->driver_priv = stellaris_info;
  241. stellaris_info->target_name = "Unknown target";
  242. /* part wasn't probed for info yet */
  243. stellaris_info->did1 = 0;
  244. /* TODO Use an optional main oscillator clock rate in kHz from arg[6] */
  245. return ERROR_OK;
  246. }
  247. static int stellaris_register_commands(struct command_context_s *cmd_ctx)
  248. {
  249. command_t *stm32x_cmd = register_command(cmd_ctx, NULL, "stellaris", NULL, COMMAND_ANY, "stellaris flash specific commands");
  250. register_command(cmd_ctx, stm32x_cmd, "mass_erase", stellaris_handle_mass_erase_command, COMMAND_EXEC, "mass erase device");
  251. return ERROR_OK;
  252. }
  253. static int stellaris_info(struct flash_bank_s *bank, char *buf, int buf_size)
  254. {
  255. int printed, device_class;
  256. stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
  257. stellaris_read_part_info(bank);
  258. if (stellaris_info->did1 == 0)
  259. {
  260. printed = snprintf(buf, buf_size, "Cannot identify target as a Stellaris\n");
  261. buf += printed;
  262. buf_size -= printed;
  263. return ERROR_FLASH_OPERATION_FAILED;
  264. }
  265. if (DID0_VER(stellaris_info->did0) > 0)
  266. {
  267. device_class = (stellaris_info->did0 >> 16) & 0xFF;
  268. }
  269. else
  270. {
  271. device_class = 0;
  272. }
  273. printed = snprintf(buf,
  274. buf_size,
  275. "\nLMI Stellaris information: Chip is class %i(%s) %s v%c.%i\n",
  276. device_class,
  277. StellarisClassname[device_class],
  278. stellaris_info->target_name,
  279. (int)('A' + ((stellaris_info->did0 >> 8) & 0xFF)),
  280. (int)((stellaris_info->did0) & 0xFF));
  281. buf += printed;
  282. buf_size -= printed;
  283. printed = snprintf(buf,
  284. buf_size,
  285. "did1: 0x%8.8" PRIx32 ", arch: 0x%4.4" PRIx32 ", eproc: %s, ramsize:%ik, flashsize: %ik\n",
  286. stellaris_info->did1,
  287. stellaris_info->did1,
  288. "ARMV7M",
  289. (int)((1 + ((stellaris_info->dc0 >> 16) & 0xFFFF))/4),
  290. (int)((1 + (stellaris_info->dc0 & 0xFFFF))*2));
  291. buf += printed;
  292. buf_size -= printed;
  293. printed = snprintf(buf,
  294. buf_size,
  295. "master clock(estimated): %ikHz, rcc is 0x%" PRIx32 " \n",
  296. (int)(stellaris_info->mck_freq / 1000),
  297. stellaris_info->rcc);
  298. buf += printed;
  299. buf_size -= printed;
  300. if (stellaris_info->num_lockbits > 0)
  301. {
  302. printed = snprintf(buf,
  303. buf_size,
  304. "pagesize: %" PRIi32 ", lockbits: %i 0x%4.4" PRIx32 ", pages in lock region: %i \n",
  305. stellaris_info->pagesize,
  306. stellaris_info->num_lockbits,
  307. stellaris_info->lockbits,
  308. (int)(stellaris_info->num_pages/stellaris_info->num_lockbits));
  309. buf += printed;
  310. buf_size -= printed;
  311. }
  312. return ERROR_OK;
  313. }
  314. /***************************************************************************
  315. * chip identification and status *
  316. ***************************************************************************/
  317. static uint32_t stellaris_get_flash_status(flash_bank_t *bank)
  318. {
  319. target_t *target = bank->target;
  320. uint32_t fmc;
  321. target_read_u32(target, FLASH_CONTROL_BASE | FLASH_FMC, &fmc);
  322. return fmc;
  323. }
  324. /** Read clock configuration and set stellaris_info->usec_clocks*/
  325. static void stellaris_read_clock_info(flash_bank_t *bank)
  326. {
  327. stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
  328. target_t *target = bank->target;
  329. uint32_t rcc, pllcfg, sysdiv, usesysdiv, bypass, oscsrc;
  330. unsigned long mainfreq;
  331. target_read_u32(target, SCB_BASE | RCC, &rcc);
  332. LOG_DEBUG("Stellaris RCC %" PRIx32 "", rcc);
  333. target_read_u32(target, SCB_BASE | PLLCFG, &pllcfg);
  334. LOG_DEBUG("Stellaris PLLCFG %" PRIx32 "", pllcfg);
  335. stellaris_info->rcc = rcc;
  336. sysdiv = (rcc >> 23) & 0xF;
  337. usesysdiv = (rcc >> 22) & 0x1;
  338. bypass = (rcc >> 11) & 0x1;
  339. oscsrc = (rcc >> 4) & 0x3;
  340. /* xtal = (rcc >> 6)&0xF; */
  341. switch (oscsrc)
  342. {
  343. case 0:
  344. mainfreq = 6000000; /* Default xtal */
  345. break;
  346. case 1:
  347. mainfreq = 22500000; /* Internal osc. 15 MHz +- 50% */
  348. break;
  349. case 2:
  350. mainfreq = 5625000; /* Internal osc. / 4 */
  351. break;
  352. case 3:
  353. LOG_WARNING("Invalid oscsrc (3) in rcc register");
  354. mainfreq = 6000000;
  355. break;
  356. default: /* NOTREACHED */
  357. mainfreq = 0;
  358. break;
  359. }
  360. if (!bypass)
  361. mainfreq = 200000000; /* PLL out frec */
  362. if (usesysdiv)
  363. stellaris_info->mck_freq = mainfreq/(1 + sysdiv);
  364. else
  365. stellaris_info->mck_freq = mainfreq;
  366. /* Forget old flash timing */
  367. stellaris_set_flash_mode(bank, 0);
  368. }
  369. /* Setup the timimg registers */
  370. static void stellaris_set_flash_mode(flash_bank_t *bank,int mode)
  371. {
  372. stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
  373. target_t *target = bank->target;
  374. uint32_t usecrl = (stellaris_info->mck_freq/1000000ul-1);
  375. LOG_DEBUG("usecrl = %i",(int)(usecrl));
  376. target_write_u32(target, SCB_BASE | USECRL, usecrl);
  377. }
  378. #if 0
  379. static uint32_t stellaris_wait_status_busy(flash_bank_t *bank, uint32_t waitbits, int timeout)
  380. {
  381. uint32_t status;
  382. /* Stellaris waits for cmdbit to clear */
  383. while (((status = stellaris_get_flash_status(bank)) & waitbits) && (timeout-- > 0))
  384. {
  385. LOG_DEBUG("status: 0x%x", status);
  386. alive_sleep(1);
  387. }
  388. /* Flash errors are reflected in the FLASH_CRIS register */
  389. return status;
  390. }
  391. /* Send one command to the flash controller */
  392. static int stellaris_flash_command(struct flash_bank_s *bank,uint8_t cmd,uint16_t pagen)
  393. {
  394. uint32_t fmc;
  395. target_t *target = bank->target;
  396. fmc = FMC_WRKEY | cmd;
  397. target_write_u32(target, FLASH_CONTROL_BASE | FLASH_FMC, fmc);
  398. LOG_DEBUG("Flash command: 0x%x", fmc);
  399. if (stellaris_wait_status_busy(bank, cmd, 100))
  400. {
  401. return ERROR_FLASH_OPERATION_FAILED;
  402. }
  403. return ERROR_OK;
  404. }
  405. #endif
  406. /* Read device id register, main clock frequency register and fill in driver info structure */
  407. static int stellaris_read_part_info(struct flash_bank_s *bank)
  408. {
  409. stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
  410. target_t *target = bank->target;
  411. uint32_t did0, did1, ver, fam, status;
  412. int i;
  413. /* Read and parse chip identification register */
  414. target_read_u32(target, SCB_BASE | DID0, &did0);
  415. target_read_u32(target, SCB_BASE | DID1, &did1);
  416. target_read_u32(target, SCB_BASE | DC0, &stellaris_info->dc0);
  417. target_read_u32(target, SCB_BASE | DC1, &stellaris_info->dc1);
  418. LOG_DEBUG("did0 0x%" PRIx32 ", did1 0x%" PRIx32 ", dc0 0x%" PRIx32 ", dc1 0x%" PRIx32 "",
  419. did0, did1, stellaris_info->dc0, stellaris_info->dc1);
  420. ver = did0 >> 28;
  421. if ((ver != 0) && (ver != 1))
  422. {
  423. LOG_WARNING("Unknown did0 version, cannot identify target");
  424. return ERROR_FLASH_OPERATION_FAILED;
  425. }
  426. if (did1 == 0)
  427. {
  428. LOG_WARNING("Cannot identify target as a Stellaris");
  429. return ERROR_FLASH_OPERATION_FAILED;
  430. }
  431. ver = did1 >> 28;
  432. fam = (did1 >> 24) & 0xF;
  433. if (((ver != 0) && (ver != 1)) || (fam != 0))
  434. {
  435. LOG_WARNING("Unknown did1 version/family, cannot positively identify target as a Stellaris");
  436. }
  437. for (i = 0; StellarisParts[i].partno; i++)
  438. {
  439. if (StellarisParts[i].partno == ((did1 >> 16) & 0xFF))
  440. break;
  441. }
  442. stellaris_info->target_name = StellarisParts[i].partname;
  443. stellaris_info->did0 = did0;
  444. stellaris_info->did1 = did1;
  445. stellaris_info->num_lockbits = 1 + (stellaris_info->dc0 & 0xFFFF);
  446. stellaris_info->num_pages = 2 *(1 + (stellaris_info->dc0 & 0xFFFF));
  447. stellaris_info->pagesize = 1024;
  448. bank->size = 1024 * stellaris_info->num_pages;
  449. stellaris_info->pages_in_lockregion = 2;
  450. target_read_u32(target, SCB_BASE | FMPPE, &stellaris_info->lockbits);
  451. /* provide this for the benefit of the higher flash driver layers */
  452. bank->num_sectors = stellaris_info->num_pages;
  453. bank->sectors = malloc(sizeof(flash_sector_t) * bank->num_sectors);
  454. for (i = 0; i < bank->num_sectors; i++)
  455. {
  456. bank->sectors[i].offset = i * stellaris_info->pagesize;
  457. bank->sectors[i].size = stellaris_info->pagesize;
  458. bank->sectors[i].is_erased = -1;
  459. bank->sectors[i].is_protected = -1;
  460. }
  461. /* Read main and master clock freqency register */
  462. stellaris_read_clock_info(bank);
  463. status = stellaris_get_flash_status(bank);
  464. return ERROR_OK;
  465. }
  466. /***************************************************************************
  467. * flash operations *
  468. ***************************************************************************/
  469. static int stellaris_protect_check(struct flash_bank_s *bank)
  470. {
  471. uint32_t status;
  472. stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
  473. if (bank->target->state != TARGET_HALTED)
  474. {
  475. LOG_ERROR("Target not halted");
  476. return ERROR_TARGET_NOT_HALTED;
  477. }
  478. if (stellaris_info->did1 == 0)
  479. {
  480. stellaris_read_part_info(bank);
  481. }
  482. if (stellaris_info->did1 == 0)
  483. {
  484. LOG_WARNING("Cannot identify target as an AT91SAM");
  485. return ERROR_FLASH_OPERATION_FAILED;
  486. }
  487. status = stellaris_get_flash_status(bank);
  488. stellaris_info->lockbits = status >> 16;
  489. return ERROR_OK;
  490. }
  491. static int stellaris_erase(struct flash_bank_s *bank, int first, int last)
  492. {
  493. int banknr;
  494. uint32_t flash_fmc, flash_cris;
  495. stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
  496. target_t *target = bank->target;
  497. if (bank->target->state != TARGET_HALTED)
  498. {
  499. LOG_ERROR("Target not halted");
  500. return ERROR_TARGET_NOT_HALTED;
  501. }
  502. if (stellaris_info->did1 == 0)
  503. {
  504. stellaris_read_part_info(bank);
  505. }
  506. if (stellaris_info->did1 == 0)
  507. {
  508. LOG_WARNING("Cannot identify target as Stellaris");
  509. return ERROR_FLASH_OPERATION_FAILED;
  510. }
  511. if ((first < 0) || (last < first) || (last >= (int)stellaris_info->num_pages))
  512. {
  513. return ERROR_FLASH_SECTOR_INVALID;
  514. }
  515. if ((first == 0) && (last == ((int)stellaris_info->num_pages-1)))
  516. {
  517. return stellaris_mass_erase(bank);
  518. }
  519. /* Configure the flash controller timing */
  520. stellaris_read_clock_info(bank);
  521. stellaris_set_flash_mode(bank,0);
  522. /* Clear and disable flash programming interrupts */
  523. target_write_u32(target, FLASH_CIM, 0);
  524. target_write_u32(target, FLASH_MISC, PMISC | AMISC);
  525. for (banknr = first; banknr <= last; banknr++)
  526. {
  527. /* Address is first word in page */
  528. target_write_u32(target, FLASH_FMA, banknr * stellaris_info->pagesize);
  529. /* Write erase command */
  530. target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_ERASE);
  531. /* Wait until erase complete */
  532. do
  533. {
  534. target_read_u32(target, FLASH_FMC, &flash_fmc);
  535. }
  536. while (flash_fmc & FMC_ERASE);
  537. /* Check acess violations */
  538. target_read_u32(target, FLASH_CRIS, &flash_cris);
  539. if (flash_cris & (AMASK))
  540. {
  541. LOG_WARNING("Error erasing flash page %i, flash_cris 0x%" PRIx32 "", banknr, flash_cris);
  542. target_write_u32(target, FLASH_CRIS, 0);
  543. return ERROR_FLASH_OPERATION_FAILED;
  544. }
  545. bank->sectors[banknr].is_erased = 1;
  546. }
  547. return ERROR_OK;
  548. }
  549. static int stellaris_protect(struct flash_bank_s *bank, int set, int first, int last)
  550. {
  551. uint32_t fmppe, flash_fmc, flash_cris;
  552. int lockregion;
  553. stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
  554. target_t *target = bank->target;
  555. if (bank->target->state != TARGET_HALTED)
  556. {
  557. LOG_ERROR("Target not halted");
  558. return ERROR_TARGET_NOT_HALTED;
  559. }
  560. if ((first < 0) || (last < first) || (last >= stellaris_info->num_lockbits))
  561. {
  562. return ERROR_FLASH_SECTOR_INVALID;
  563. }
  564. if (stellaris_info->did1 == 0)
  565. {
  566. stellaris_read_part_info(bank);
  567. }
  568. if (stellaris_info->did1 == 0)
  569. {
  570. LOG_WARNING("Cannot identify target as an Stellaris MCU");
  571. return ERROR_FLASH_OPERATION_FAILED;
  572. }
  573. /* Configure the flash controller timing */
  574. stellaris_read_clock_info(bank);
  575. stellaris_set_flash_mode(bank, 0);
  576. fmppe = stellaris_info->lockbits;
  577. for (lockregion = first; lockregion <= last; lockregion++)
  578. {
  579. if (set)
  580. fmppe &= ~(1 << lockregion);
  581. else
  582. fmppe |= (1 << lockregion);
  583. }
  584. /* Clear and disable flash programming interrupts */
  585. target_write_u32(target, FLASH_CIM, 0);
  586. target_write_u32(target, FLASH_MISC, PMISC | AMISC);
  587. LOG_DEBUG("fmppe 0x%" PRIx32 "",fmppe);
  588. target_write_u32(target, SCB_BASE | FMPPE, fmppe);
  589. /* Commit FMPPE */
  590. target_write_u32(target, FLASH_FMA, 1);
  591. /* Write commit command */
  592. /* TODO safety check, sice this cannot be undone */
  593. LOG_WARNING("Flash protection cannot be removed once commited, commit is NOT executed !");
  594. /* target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_COMT); */
  595. /* Wait until erase complete */
  596. do
  597. {
  598. target_read_u32(target, FLASH_FMC, &flash_fmc);
  599. }
  600. while (flash_fmc & FMC_COMT);
  601. /* Check acess violations */
  602. target_read_u32(target, FLASH_CRIS, &flash_cris);
  603. if (flash_cris & (AMASK))
  604. {
  605. LOG_WARNING("Error setting flash page protection, flash_cris 0x%" PRIx32 "", flash_cris);
  606. target_write_u32(target, FLASH_CRIS, 0);
  607. return ERROR_FLASH_OPERATION_FAILED;
  608. }
  609. target_read_u32(target, SCB_BASE | FMPPE, &stellaris_info->lockbits);
  610. return ERROR_OK;
  611. }
  612. static uint8_t stellaris_write_code[] =
  613. {
  614. /*
  615. Call with :
  616. r0 = buffer address
  617. r1 = destination address
  618. r2 = bytecount (in) - endaddr (work)
  619. Used registers:
  620. r3 = pFLASH_CTRL_BASE
  621. r4 = FLASHWRITECMD
  622. r5 = #1
  623. r6 = bytes written
  624. r7 = temp reg
  625. */
  626. 0x07,0x4B, /* ldr r3,pFLASH_CTRL_BASE */
  627. 0x08,0x4C, /* ldr r4,FLASHWRITECMD */
  628. 0x01,0x25, /* movs r5, 1 */
  629. 0x00,0x26, /* movs r6, #0 */
  630. /* mainloop: */
  631. 0x19,0x60, /* str r1, [r3, #0] */
  632. 0x87,0x59, /* ldr r7, [r0, r6] */
  633. 0x5F,0x60, /* str r7, [r3, #4] */
  634. 0x9C,0x60, /* str r4, [r3, #8] */
  635. /* waitloop: */
  636. 0x9F,0x68, /* ldr r7, [r3, #8] */
  637. 0x2F,0x42, /* tst r7, r5 */
  638. 0xFC,0xD1, /* bne waitloop */
  639. 0x04,0x31, /* adds r1, r1, #4 */
  640. 0x04,0x36, /* adds r6, r6, #4 */
  641. 0x96,0x42, /* cmp r6, r2 */
  642. 0xF4,0xD1, /* bne mainloop */
  643. /* exit: */
  644. 0xFE,0xE7, /* b exit */
  645. /* pFLASH_CTRL_BASE: */
  646. 0x00,0xD0,0x0F,0x40, /* .word 0x400FD000 */
  647. /* FLASHWRITECMD: */
  648. 0x01,0x00,0x42,0xA4 /* .word 0xA4420001 */
  649. };
  650. static int stellaris_write_block(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t wcount)
  651. {
  652. target_t *target = bank->target;
  653. uint32_t buffer_size = 8192;
  654. working_area_t *source;
  655. working_area_t *write_algorithm;
  656. uint32_t address = bank->base + offset;
  657. reg_param_t reg_params[3];
  658. armv7m_algorithm_t armv7m_info;
  659. int retval = ERROR_OK;
  660. LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32 " wcount=%08" PRIx32 "",
  661. bank, buffer, offset, wcount);
  662. /* flash write code */
  663. if (target_alloc_working_area(target, sizeof(stellaris_write_code), &write_algorithm) != ERROR_OK)
  664. {
  665. LOG_WARNING("no working area available, can't do block memory writes");
  666. return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
  667. };
  668. target_write_buffer(target, write_algorithm->address, sizeof(stellaris_write_code), stellaris_write_code);
  669. /* memory buffer */
  670. while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
  671. {
  672. LOG_DEBUG("called target_alloc_working_area(target=%p buffer_size=%08" PRIx32 " source=%p)",
  673. target, buffer_size, source);
  674. buffer_size /= 2;
  675. if (buffer_size <= 256)
  676. {
  677. /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
  678. if (write_algorithm)
  679. target_free_working_area(target, write_algorithm);
  680. LOG_WARNING("no large enough working area available, can't do block memory writes");
  681. return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
  682. }
  683. };
  684. armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
  685. armv7m_info.core_mode = ARMV7M_MODE_ANY;
  686. init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
  687. init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
  688. init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
  689. while (wcount > 0)
  690. {
  691. uint32_t thisrun_count = (wcount > (buffer_size / 4)) ? (buffer_size / 4) : wcount;
  692. target_write_buffer(target, source->address, thisrun_count * 4, buffer);
  693. buf_set_u32(reg_params[0].value, 0, 32, source->address);
  694. buf_set_u32(reg_params[1].value, 0, 32, address);
  695. buf_set_u32(reg_params[2].value, 0, 32, 4*thisrun_count);
  696. LOG_INFO("Algorithm flash write %" PRIi32 " words to 0x%" PRIx32 ", %" PRIi32 " remaining", thisrun_count, address, wcount);
  697. LOG_DEBUG("Algorithm flash write %" PRIi32 " words to 0x%" PRIx32 ", %" PRIi32 " remaining", thisrun_count, address, wcount);
  698. if ((retval = target_run_algorithm(target, 0, NULL, 3, reg_params, write_algorithm->address, write_algorithm->address + sizeof(stellaris_write_code)-10, 10000, &armv7m_info)) != ERROR_OK)
  699. {
  700. LOG_ERROR("error executing stellaris flash write algorithm");
  701. retval = ERROR_FLASH_OPERATION_FAILED;
  702. break;
  703. }
  704. buffer += thisrun_count * 4;
  705. address += thisrun_count * 4;
  706. wcount -= thisrun_count;
  707. }
  708. target_free_working_area(target, write_algorithm);
  709. target_free_working_area(target, source);
  710. destroy_reg_param(&reg_params[0]);
  711. destroy_reg_param(&reg_params[1]);
  712. destroy_reg_param(&reg_params[2]);
  713. return retval;
  714. }
  715. static int stellaris_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
  716. {
  717. stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
  718. target_t *target = bank->target;
  719. uint32_t address = offset;
  720. uint32_t flash_cris, flash_fmc;
  721. uint32_t words_remaining = (count / 4);
  722. uint32_t bytes_remaining = (count & 0x00000003);
  723. uint32_t bytes_written = 0;
  724. int retval;
  725. if (bank->target->state != TARGET_HALTED)
  726. {
  727. LOG_ERROR("Target not halted");
  728. return ERROR_TARGET_NOT_HALTED;
  729. }
  730. LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32 " count=%08" PRIx32 "",
  731. bank, buffer, offset, count);
  732. if (stellaris_info->did1 == 0)
  733. {
  734. stellaris_read_part_info(bank);
  735. }
  736. if (stellaris_info->did1 == 0)
  737. {
  738. LOG_WARNING("Cannot identify target as a Stellaris processor");
  739. return ERROR_FLASH_OPERATION_FAILED;
  740. }
  741. if (offset & 0x3)
  742. {
  743. LOG_WARNING("offset size must be word aligned");
  744. return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
  745. }
  746. if (offset + count > bank->size)
  747. return ERROR_FLASH_DST_OUT_OF_BANK;
  748. /* Configure the flash controller timing */
  749. stellaris_read_clock_info(bank);
  750. stellaris_set_flash_mode(bank, 0);
  751. /* Clear and disable flash programming interrupts */
  752. target_write_u32(target, FLASH_CIM, 0);
  753. target_write_u32(target, FLASH_MISC, PMISC | AMISC);
  754. /* multiple words to be programmed? */
  755. if (words_remaining > 0)
  756. {
  757. /* try using a block write */
  758. if ((retval = stellaris_write_block(bank, buffer, offset, words_remaining)) != ERROR_OK)
  759. {
  760. if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
  761. {
  762. /* if block write failed (no sufficient working area),
  763. * we use normal (slow) single dword accesses */
  764. LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
  765. }
  766. else if (retval == ERROR_FLASH_OPERATION_FAILED)
  767. {
  768. /* if an error occured, we examine the reason, and quit */
  769. target_read_u32(target, FLASH_CRIS, &flash_cris);
  770. LOG_ERROR("flash writing failed with CRIS: 0x%" PRIx32 "", flash_cris);
  771. return ERROR_FLASH_OPERATION_FAILED;
  772. }
  773. }
  774. else
  775. {
  776. buffer += words_remaining * 4;
  777. address += words_remaining * 4;
  778. words_remaining = 0;
  779. }
  780. }
  781. while (words_remaining > 0)
  782. {
  783. if (!(address & 0xff))
  784. LOG_DEBUG("0x%" PRIx32 "", address);
  785. /* Program one word */
  786. target_write_u32(target, FLASH_FMA, address);
  787. target_write_buffer(target, FLASH_FMD, 4, buffer);
  788. target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_WRITE);
  789. /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
  790. /* Wait until write complete */
  791. do
  792. {
  793. target_read_u32(target, FLASH_FMC, &flash_fmc);
  794. } while (flash_fmc & FMC_WRITE);
  795. buffer += 4;
  796. address += 4;
  797. words_remaining--;
  798. }
  799. if (bytes_remaining)
  800. {
  801. uint8_t last_word[4] = {0xff, 0xff, 0xff, 0xff};
  802. int i = 0;
  803. while (bytes_remaining > 0)
  804. {
  805. last_word[i++] = *(buffer + bytes_written);
  806. bytes_remaining--;
  807. bytes_written++;
  808. }
  809. if (!(address & 0xff))
  810. LOG_DEBUG("0x%" PRIx32 "", address);
  811. /* Program one word */
  812. target_write_u32(target, FLASH_FMA, address);
  813. target_write_buffer(target, FLASH_FMD, 4, last_word);
  814. target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_WRITE);
  815. /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
  816. /* Wait until write complete */
  817. do
  818. {
  819. target_read_u32(target, FLASH_FMC, &flash_fmc);
  820. } while (flash_fmc & FMC_WRITE);
  821. }
  822. /* Check access violations */
  823. target_read_u32(target, FLASH_CRIS, &flash_cris);
  824. if (flash_cris & (AMASK))
  825. {
  826. LOG_DEBUG("flash_cris 0x%" PRIx32 "", flash_cris);
  827. return ERROR_FLASH_OPERATION_FAILED;
  828. }
  829. return ERROR_OK;
  830. }
  831. static int stellaris_probe(struct flash_bank_s *bank)
  832. {
  833. /* we can't probe on an stellaris
  834. * if this is an stellaris, it has the configured flash
  835. */
  836. if (bank->target->state != TARGET_HALTED)
  837. {
  838. LOG_ERROR("Target not halted");
  839. return ERROR_TARGET_NOT_HALTED;
  840. }
  841. /* stellaris_read_part_info() already takes care about error checking and reporting */
  842. return stellaris_read_part_info(bank);
  843. }
  844. static int stellaris_auto_probe(struct flash_bank_s *bank)
  845. {
  846. stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
  847. if (stellaris_info->did1)
  848. return ERROR_OK;
  849. return stellaris_probe(bank);
  850. }
  851. static int stellaris_mass_erase(struct flash_bank_s *bank)
  852. {
  853. target_t *target = NULL;
  854. stellaris_flash_bank_t *stellaris_info = NULL;
  855. uint32_t flash_fmc;
  856. stellaris_info = bank->driver_priv;
  857. target = bank->target;
  858. if (target->state != TARGET_HALTED)
  859. {
  860. LOG_ERROR("Target not halted");
  861. return ERROR_TARGET_NOT_HALTED;
  862. }
  863. if (stellaris_info->did1 == 0)
  864. {
  865. stellaris_read_part_info(bank);
  866. }
  867. if (stellaris_info->did1 == 0)
  868. {
  869. LOG_WARNING("Cannot identify target as Stellaris");
  870. return ERROR_FLASH_OPERATION_FAILED;
  871. }
  872. /* Configure the flash controller timing */
  873. stellaris_read_clock_info(bank);
  874. stellaris_set_flash_mode(bank, 0);
  875. /* Clear and disable flash programming interrupts */
  876. target_write_u32(target, FLASH_CIM, 0);
  877. target_write_u32(target, FLASH_MISC, PMISC | AMISC);
  878. target_write_u32(target, FLASH_FMA, 0);
  879. target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_MERASE);
  880. /* Wait until erase complete */
  881. do
  882. {
  883. target_read_u32(target, FLASH_FMC, &flash_fmc);
  884. }
  885. while (flash_fmc & FMC_MERASE);
  886. /* if device has > 128k, then second erase cycle is needed
  887. * this is only valid for older devices, but will not hurt */
  888. if (stellaris_info->num_pages * stellaris_info->pagesize > 0x20000)
  889. {
  890. target_write_u32(target, FLASH_FMA, 0x20000);
  891. target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_MERASE);
  892. /* Wait until erase complete */
  893. do
  894. {
  895. target_read_u32(target, FLASH_FMC, &flash_fmc);
  896. }
  897. while (flash_fmc & FMC_MERASE);
  898. }
  899. return ERROR_OK;
  900. }
  901. static int stellaris_handle_mass_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  902. {
  903. flash_bank_t *bank;
  904. int i;
  905. if (argc < 1)
  906. {
  907. command_print(cmd_ctx, "stellaris mass_erase <bank>");
  908. return ERROR_OK;
  909. }
  910. bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
  911. if (!bank)
  912. {
  913. command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
  914. return ERROR_OK;
  915. }
  916. if (stellaris_mass_erase(bank) == ERROR_OK)
  917. {
  918. /* set all sectors as erased */
  919. for (i = 0; i < bank->num_sectors; i++)
  920. {
  921. bank->sectors[i].is_erased = 1;
  922. }
  923. command_print(cmd_ctx, "stellaris mass erase complete");
  924. }
  925. else
  926. {
  927. command_print(cmd_ctx, "stellaris mass erase failed");
  928. }
  929. return ERROR_OK;
  930. }