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.
 
 
 
 
 
 

1058 lines
29 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, u32 offset, u32 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 u32 stellaris_get_flash_status(flash_bank_t *bank);
  44. static void stellaris_set_flash_mode(flash_bank_t *bank,int mode);
  45. //static u32 stellaris_wait_status_busy(flash_bank_t *bank, u32 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. u32 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, buf_size, "\nLMI Stellaris information: Chip is class %i(%s) %s v%c.%i\n",
  274. device_class, StellarisClassname[device_class], stellaris_info->target_name,
  275. 'A' + ((stellaris_info->did0>>8) & 0xFF), (stellaris_info->did0) & 0xFF);
  276. buf += printed;
  277. buf_size -= printed;
  278. printed = snprintf(buf, buf_size, "did1: 0x%8.8x, arch: 0x%4.4x, eproc: %s, ramsize:%ik, flashsize: %ik\n",
  279. stellaris_info->did1, stellaris_info->did1, "ARMV7M", (1+((stellaris_info->dc0>>16) & 0xFFFF))/4, (1+(stellaris_info->dc0 & 0xFFFF))*2);
  280. buf += printed;
  281. buf_size -= printed;
  282. printed = snprintf(buf, buf_size, "master clock(estimated): %ikHz, rcc is 0x%x \n", stellaris_info->mck_freq / 1000, stellaris_info->rcc);
  283. buf += printed;
  284. buf_size -= printed;
  285. if (stellaris_info->num_lockbits>0)
  286. {
  287. printed = snprintf(buf, buf_size, "pagesize: %i, lockbits: %i 0x%4.4x, pages in lock region: %i \n", stellaris_info->pagesize, stellaris_info->num_lockbits, stellaris_info->lockbits,stellaris_info->num_pages/stellaris_info->num_lockbits);
  288. buf += printed;
  289. buf_size -= printed;
  290. }
  291. return ERROR_OK;
  292. }
  293. /***************************************************************************
  294. * chip identification and status *
  295. ***************************************************************************/
  296. static u32 stellaris_get_flash_status(flash_bank_t *bank)
  297. {
  298. target_t *target = bank->target;
  299. u32 fmc;
  300. target_read_u32(target, FLASH_CONTROL_BASE|FLASH_FMC, &fmc);
  301. return fmc;
  302. }
  303. /** Read clock configuration and set stellaris_info->usec_clocks*/
  304. static void stellaris_read_clock_info(flash_bank_t *bank)
  305. {
  306. stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
  307. target_t *target = bank->target;
  308. u32 rcc, pllcfg, sysdiv, usesysdiv, bypass, oscsrc;
  309. unsigned long mainfreq;
  310. target_read_u32(target, SCB_BASE|RCC, &rcc);
  311. LOG_DEBUG("Stellaris RCC %x", rcc);
  312. target_read_u32(target, SCB_BASE|PLLCFG, &pllcfg);
  313. LOG_DEBUG("Stellaris PLLCFG %x", pllcfg);
  314. stellaris_info->rcc = rcc;
  315. sysdiv = (rcc>>23) & 0xF;
  316. usesysdiv = (rcc>>22) & 0x1;
  317. bypass = (rcc>>11) & 0x1;
  318. oscsrc = (rcc>>4) & 0x3;
  319. /* xtal = (rcc>>6)&0xF; */
  320. switch (oscsrc)
  321. {
  322. case 0:
  323. mainfreq = 6000000; /* Default xtal */
  324. break;
  325. case 1:
  326. mainfreq = 22500000; /* Internal osc. 15 MHz +- 50% */
  327. break;
  328. case 2:
  329. mainfreq = 5625000; /* Internal osc. / 4 */
  330. break;
  331. case 3:
  332. LOG_WARNING("Invalid oscsrc (3) in rcc register");
  333. mainfreq = 6000000;
  334. break;
  335. default: /* NOTREACHED */
  336. mainfreq = 0;
  337. break;
  338. }
  339. if (!bypass)
  340. mainfreq = 200000000; /* PLL out frec */
  341. if (usesysdiv)
  342. stellaris_info->mck_freq = mainfreq/(1+sysdiv);
  343. else
  344. stellaris_info->mck_freq = mainfreq;
  345. /* Forget old flash timing */
  346. stellaris_set_flash_mode(bank, 0);
  347. }
  348. /* Setup the timimg registers */
  349. static void stellaris_set_flash_mode(flash_bank_t *bank,int mode)
  350. {
  351. stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
  352. target_t *target = bank->target;
  353. u32 usecrl = (stellaris_info->mck_freq/1000000ul-1);
  354. LOG_DEBUG("usecrl = %i",usecrl);
  355. target_write_u32(target, SCB_BASE|USECRL, usecrl);
  356. }
  357. #if 0
  358. static u32 stellaris_wait_status_busy(flash_bank_t *bank, u32 waitbits, int timeout)
  359. {
  360. u32 status;
  361. /* Stellaris waits for cmdbit to clear */
  362. while (((status = stellaris_get_flash_status(bank)) & waitbits) && (timeout-- > 0))
  363. {
  364. LOG_DEBUG("status: 0x%x", status);
  365. alive_sleep(1);
  366. }
  367. /* Flash errors are reflected in the FLASH_CRIS register */
  368. return status;
  369. }
  370. /* Send one command to the flash controller */
  371. static int stellaris_flash_command(struct flash_bank_s *bank,uint8_t cmd,uint16_t pagen)
  372. {
  373. u32 fmc;
  374. target_t *target = bank->target;
  375. fmc = FMC_WRKEY | cmd;
  376. target_write_u32(target, FLASH_CONTROL_BASE|FLASH_FMC, fmc);
  377. LOG_DEBUG("Flash command: 0x%x", fmc);
  378. if (stellaris_wait_status_busy(bank, cmd, 100))
  379. {
  380. return ERROR_FLASH_OPERATION_FAILED;
  381. }
  382. return ERROR_OK;
  383. }
  384. #endif
  385. /* Read device id register, main clock frequency register and fill in driver info structure */
  386. static int stellaris_read_part_info(struct flash_bank_s *bank)
  387. {
  388. stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
  389. target_t *target = bank->target;
  390. u32 did0, did1, ver, fam, status;
  391. int i;
  392. /* Read and parse chip identification register */
  393. target_read_u32(target, SCB_BASE|DID0, &did0);
  394. target_read_u32(target, SCB_BASE|DID1, &did1);
  395. target_read_u32(target, SCB_BASE|DC0, &stellaris_info->dc0);
  396. target_read_u32(target, SCB_BASE|DC1, &stellaris_info->dc1);
  397. LOG_DEBUG("did0 0x%x, did1 0x%x, dc0 0x%x, dc1 0x%x", did0, did1, stellaris_info->dc0, stellaris_info->dc1);
  398. ver = did0 >> 28;
  399. if((ver != 0) && (ver != 1))
  400. {
  401. LOG_WARNING("Unknown did0 version, cannot identify target");
  402. return ERROR_FLASH_OPERATION_FAILED;
  403. }
  404. if (did1 == 0)
  405. {
  406. LOG_WARNING("Cannot identify target as a Stellaris");
  407. return ERROR_FLASH_OPERATION_FAILED;
  408. }
  409. ver = did1 >> 28;
  410. fam = (did1 >> 24) & 0xF;
  411. if(((ver != 0) && (ver != 1)) || (fam != 0))
  412. {
  413. LOG_WARNING("Unknown did1 version/family, cannot positively identify target as a Stellaris");
  414. }
  415. for (i = 0; StellarisParts[i].partno; i++)
  416. {
  417. if (StellarisParts[i].partno == ((did1 >> 16) & 0xFF))
  418. break;
  419. }
  420. stellaris_info->target_name = StellarisParts[i].partname;
  421. stellaris_info->did0 = did0;
  422. stellaris_info->did1 = did1;
  423. stellaris_info->num_lockbits = 1 + (stellaris_info->dc0 & 0xFFFF);
  424. stellaris_info->num_pages = 2 *(1+(stellaris_info->dc0 & 0xFFFF));
  425. stellaris_info->pagesize = 1024;
  426. bank->size = 1024 * stellaris_info->num_pages;
  427. stellaris_info->pages_in_lockregion = 2;
  428. target_read_u32(target, SCB_BASE|FMPPE, &stellaris_info->lockbits);
  429. /* provide this for the benefit of the higher flash driver layers */
  430. bank->num_sectors = stellaris_info->num_pages;
  431. bank->sectors = malloc(sizeof(flash_sector_t) * bank->num_sectors);
  432. for (i = 0; i < bank->num_sectors; i++)
  433. {
  434. bank->sectors[i].offset = i * stellaris_info->pagesize;
  435. bank->sectors[i].size = stellaris_info->pagesize;
  436. bank->sectors[i].is_erased = -1;
  437. bank->sectors[i].is_protected = -1;
  438. }
  439. /* Read main and master clock freqency register */
  440. stellaris_read_clock_info(bank);
  441. status = stellaris_get_flash_status(bank);
  442. return ERROR_OK;
  443. }
  444. /***************************************************************************
  445. * flash operations *
  446. ***************************************************************************/
  447. static int stellaris_protect_check(struct flash_bank_s *bank)
  448. {
  449. u32 status;
  450. stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
  451. if (bank->target->state != TARGET_HALTED)
  452. {
  453. LOG_ERROR("Target not halted");
  454. return ERROR_TARGET_NOT_HALTED;
  455. }
  456. if (stellaris_info->did1 == 0)
  457. {
  458. stellaris_read_part_info(bank);
  459. }
  460. if (stellaris_info->did1 == 0)
  461. {
  462. LOG_WARNING("Cannot identify target as an AT91SAM");
  463. return ERROR_FLASH_OPERATION_FAILED;
  464. }
  465. status = stellaris_get_flash_status(bank);
  466. stellaris_info->lockbits = status >> 16;
  467. return ERROR_OK;
  468. }
  469. static int stellaris_erase(struct flash_bank_s *bank, int first, int last)
  470. {
  471. int banknr;
  472. u32 flash_fmc, flash_cris;
  473. stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
  474. target_t *target = bank->target;
  475. if (bank->target->state != TARGET_HALTED)
  476. {
  477. LOG_ERROR("Target not halted");
  478. return ERROR_TARGET_NOT_HALTED;
  479. }
  480. if (stellaris_info->did1 == 0)
  481. {
  482. stellaris_read_part_info(bank);
  483. }
  484. if (stellaris_info->did1 == 0)
  485. {
  486. LOG_WARNING("Cannot identify target as Stellaris");
  487. return ERROR_FLASH_OPERATION_FAILED;
  488. }
  489. if ((first < 0) || (last < first) || (last >= (int)stellaris_info->num_pages))
  490. {
  491. return ERROR_FLASH_SECTOR_INVALID;
  492. }
  493. if ((first == 0) && (last == ((int)stellaris_info->num_pages-1)))
  494. {
  495. return stellaris_mass_erase(bank);
  496. }
  497. /* Configure the flash controller timing */
  498. stellaris_read_clock_info(bank);
  499. stellaris_set_flash_mode(bank,0);
  500. /* Clear and disable flash programming interrupts */
  501. target_write_u32(target, FLASH_CIM, 0);
  502. target_write_u32(target, FLASH_MISC, PMISC|AMISC);
  503. for (banknr = first; banknr <= last; banknr++)
  504. {
  505. /* Address is first word in page */
  506. target_write_u32(target, FLASH_FMA, banknr * stellaris_info->pagesize);
  507. /* Write erase command */
  508. target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_ERASE);
  509. /* Wait until erase complete */
  510. do
  511. {
  512. target_read_u32(target, FLASH_FMC, &flash_fmc);
  513. }
  514. while(flash_fmc & FMC_ERASE);
  515. /* Check acess violations */
  516. target_read_u32(target, FLASH_CRIS, &flash_cris);
  517. if(flash_cris & (AMASK))
  518. {
  519. LOG_WARNING("Error erasing flash page %i, flash_cris 0x%x", banknr, flash_cris);
  520. target_write_u32(target, FLASH_CRIS, 0);
  521. return ERROR_FLASH_OPERATION_FAILED;
  522. }
  523. bank->sectors[banknr].is_erased = 1;
  524. }
  525. return ERROR_OK;
  526. }
  527. static int stellaris_protect(struct flash_bank_s *bank, int set, int first, int last)
  528. {
  529. u32 fmppe, flash_fmc, flash_cris;
  530. int lockregion;
  531. stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
  532. target_t *target = bank->target;
  533. if (bank->target->state != TARGET_HALTED)
  534. {
  535. LOG_ERROR("Target not halted");
  536. return ERROR_TARGET_NOT_HALTED;
  537. }
  538. if ((first < 0) || (last < first) || (last >= stellaris_info->num_lockbits))
  539. {
  540. return ERROR_FLASH_SECTOR_INVALID;
  541. }
  542. if (stellaris_info->did1 == 0)
  543. {
  544. stellaris_read_part_info(bank);
  545. }
  546. if (stellaris_info->did1 == 0)
  547. {
  548. LOG_WARNING("Cannot identify target as an Stellaris MCU");
  549. return ERROR_FLASH_OPERATION_FAILED;
  550. }
  551. /* Configure the flash controller timing */
  552. stellaris_read_clock_info(bank);
  553. stellaris_set_flash_mode(bank, 0);
  554. fmppe = stellaris_info->lockbits;
  555. for (lockregion = first; lockregion <= last; lockregion++)
  556. {
  557. if (set)
  558. fmppe &= ~(1<<lockregion);
  559. else
  560. fmppe |= (1<<lockregion);
  561. }
  562. /* Clear and disable flash programming interrupts */
  563. target_write_u32(target, FLASH_CIM, 0);
  564. target_write_u32(target, FLASH_MISC, PMISC|AMISC);
  565. LOG_DEBUG("fmppe 0x%x",fmppe);
  566. target_write_u32(target, SCB_BASE|FMPPE, fmppe);
  567. /* Commit FMPPE */
  568. target_write_u32(target, FLASH_FMA, 1);
  569. /* Write commit command */
  570. /* TODO safety check, sice this cannot be undone */
  571. LOG_WARNING("Flash protection cannot be removed once commited, commit is NOT executed !");
  572. /* target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_COMT); */
  573. /* Wait until erase complete */
  574. do
  575. {
  576. target_read_u32(target, FLASH_FMC, &flash_fmc);
  577. }
  578. while(flash_fmc & FMC_COMT);
  579. /* Check acess violations */
  580. target_read_u32(target, FLASH_CRIS, &flash_cris);
  581. if(flash_cris & (AMASK))
  582. {
  583. LOG_WARNING("Error setting flash page protection, flash_cris 0x%x", flash_cris);
  584. target_write_u32(target, FLASH_CRIS, 0);
  585. return ERROR_FLASH_OPERATION_FAILED;
  586. }
  587. target_read_u32(target, SCB_BASE|FMPPE, &stellaris_info->lockbits);
  588. return ERROR_OK;
  589. }
  590. static uint8_t stellaris_write_code[] =
  591. {
  592. /*
  593. Call with :
  594. r0 = buffer address
  595. r1 = destination address
  596. r2 = bytecount (in) - endaddr (work)
  597. Used registers:
  598. r3 = pFLASH_CTRL_BASE
  599. r4 = FLASHWRITECMD
  600. r5 = #1
  601. r6 = bytes written
  602. r7 = temp reg
  603. */
  604. 0x07,0x4B, /* ldr r3,pFLASH_CTRL_BASE */
  605. 0x08,0x4C, /* ldr r4,FLASHWRITECMD */
  606. 0x01,0x25, /* movs r5, 1 */
  607. 0x00,0x26, /* movs r6, #0 */
  608. /* mainloop: */
  609. 0x19,0x60, /* str r1, [r3, #0] */
  610. 0x87,0x59, /* ldr r7, [r0, r6] */
  611. 0x5F,0x60, /* str r7, [r3, #4] */
  612. 0x9C,0x60, /* str r4, [r3, #8] */
  613. /* waitloop: */
  614. 0x9F,0x68, /* ldr r7, [r3, #8] */
  615. 0x2F,0x42, /* tst r7, r5 */
  616. 0xFC,0xD1, /* bne waitloop */
  617. 0x04,0x31, /* adds r1, r1, #4 */
  618. 0x04,0x36, /* adds r6, r6, #4 */
  619. 0x96,0x42, /* cmp r6, r2 */
  620. 0xF4,0xD1, /* bne mainloop */
  621. /* exit: */
  622. 0xFE,0xE7, /* b exit */
  623. /* pFLASH_CTRL_BASE: */
  624. 0x00,0xD0,0x0F,0x40, /* .word 0x400FD000 */
  625. /* FLASHWRITECMD: */
  626. 0x01,0x00,0x42,0xA4 /* .word 0xA4420001 */
  627. };
  628. static int stellaris_write_block(struct flash_bank_s *bank, uint8_t *buffer, u32 offset, u32 wcount)
  629. {
  630. target_t *target = bank->target;
  631. u32 buffer_size = 8192;
  632. working_area_t *source;
  633. working_area_t *write_algorithm;
  634. u32 address = bank->base + offset;
  635. reg_param_t reg_params[3];
  636. armv7m_algorithm_t armv7m_info;
  637. int retval = ERROR_OK;
  638. LOG_DEBUG("(bank=%p buffer=%p offset=%08X wcount=%08X)",
  639. bank, buffer, offset, wcount);
  640. /* flash write code */
  641. if (target_alloc_working_area(target, sizeof(stellaris_write_code), &write_algorithm) != ERROR_OK)
  642. {
  643. LOG_WARNING("no working area available, can't do block memory writes");
  644. return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
  645. };
  646. target_write_buffer(target, write_algorithm->address, sizeof(stellaris_write_code), stellaris_write_code);
  647. /* memory buffer */
  648. while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
  649. {
  650. LOG_DEBUG("called target_alloc_working_area(target=%p buffer_size=%08X source=%p)",
  651. target, buffer_size, source);
  652. buffer_size /= 2;
  653. if (buffer_size <= 256)
  654. {
  655. /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
  656. if (write_algorithm)
  657. target_free_working_area(target, write_algorithm);
  658. LOG_WARNING("no large enough working area available, can't do block memory writes");
  659. return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
  660. }
  661. };
  662. armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
  663. armv7m_info.core_mode = ARMV7M_MODE_ANY;
  664. init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
  665. init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
  666. init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
  667. while (wcount > 0)
  668. {
  669. u32 thisrun_count = (wcount > (buffer_size / 4)) ? (buffer_size / 4) : wcount;
  670. target_write_buffer(target, source->address, thisrun_count * 4, buffer);
  671. buf_set_u32(reg_params[0].value, 0, 32, source->address);
  672. buf_set_u32(reg_params[1].value, 0, 32, address);
  673. buf_set_u32(reg_params[2].value, 0, 32, 4*thisrun_count);
  674. LOG_INFO("Algorithm flash write %i words to 0x%x, %i remaining", thisrun_count, address, wcount);
  675. LOG_DEBUG("Algorithm flash write %i words to 0x%x, %i remaining", thisrun_count, address, wcount);
  676. 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)
  677. {
  678. LOG_ERROR("error executing stellaris flash write algorithm");
  679. retval = ERROR_FLASH_OPERATION_FAILED;
  680. break;
  681. }
  682. buffer += thisrun_count * 4;
  683. address += thisrun_count * 4;
  684. wcount -= thisrun_count;
  685. }
  686. target_free_working_area(target, write_algorithm);
  687. target_free_working_area(target, source);
  688. destroy_reg_param(&reg_params[0]);
  689. destroy_reg_param(&reg_params[1]);
  690. destroy_reg_param(&reg_params[2]);
  691. return retval;
  692. }
  693. static int stellaris_write(struct flash_bank_s *bank, uint8_t *buffer, u32 offset, u32 count)
  694. {
  695. stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
  696. target_t *target = bank->target;
  697. u32 address = offset;
  698. u32 flash_cris, flash_fmc;
  699. u32 words_remaining = (count / 4);
  700. u32 bytes_remaining = (count & 0x00000003);
  701. u32 bytes_written = 0;
  702. int retval;
  703. if (bank->target->state != TARGET_HALTED)
  704. {
  705. LOG_ERROR("Target not halted");
  706. return ERROR_TARGET_NOT_HALTED;
  707. }
  708. LOG_DEBUG("(bank=%p buffer=%p offset=%08X count=%08X)",
  709. bank, buffer, offset, count);
  710. if (stellaris_info->did1 == 0)
  711. {
  712. stellaris_read_part_info(bank);
  713. }
  714. if (stellaris_info->did1 == 0)
  715. {
  716. LOG_WARNING("Cannot identify target as a Stellaris processor");
  717. return ERROR_FLASH_OPERATION_FAILED;
  718. }
  719. if (offset & 0x3)
  720. {
  721. LOG_WARNING("offset size must be word aligned");
  722. return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
  723. }
  724. if (offset + count > bank->size)
  725. return ERROR_FLASH_DST_OUT_OF_BANK;
  726. /* Configure the flash controller timing */
  727. stellaris_read_clock_info(bank);
  728. stellaris_set_flash_mode(bank, 0);
  729. /* Clear and disable flash programming interrupts */
  730. target_write_u32(target, FLASH_CIM, 0);
  731. target_write_u32(target, FLASH_MISC, PMISC|AMISC);
  732. /* multiple words to be programmed? */
  733. if (words_remaining > 0)
  734. {
  735. /* try using a block write */
  736. if ((retval = stellaris_write_block(bank, buffer, offset, words_remaining)) != ERROR_OK)
  737. {
  738. if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
  739. {
  740. /* if block write failed (no sufficient working area),
  741. * we use normal (slow) single dword accesses */
  742. LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
  743. }
  744. else if (retval == ERROR_FLASH_OPERATION_FAILED)
  745. {
  746. /* if an error occured, we examine the reason, and quit */
  747. target_read_u32(target, FLASH_CRIS, &flash_cris);
  748. LOG_ERROR("flash writing failed with CRIS: 0x%x", flash_cris);
  749. return ERROR_FLASH_OPERATION_FAILED;
  750. }
  751. }
  752. else
  753. {
  754. buffer += words_remaining * 4;
  755. address += words_remaining * 4;
  756. words_remaining = 0;
  757. }
  758. }
  759. while (words_remaining > 0)
  760. {
  761. if (!(address & 0xff))
  762. LOG_DEBUG("0x%x", address);
  763. /* Program one word */
  764. target_write_u32(target, FLASH_FMA, address);
  765. target_write_buffer(target, FLASH_FMD, 4, buffer);
  766. target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_WRITE);
  767. /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
  768. /* Wait until write complete */
  769. do
  770. {
  771. target_read_u32(target, FLASH_FMC, &flash_fmc);
  772. } while (flash_fmc & FMC_WRITE);
  773. buffer += 4;
  774. address += 4;
  775. words_remaining--;
  776. }
  777. if (bytes_remaining)
  778. {
  779. uint8_t last_word[4] = {0xff, 0xff, 0xff, 0xff};
  780. int i = 0;
  781. while(bytes_remaining > 0)
  782. {
  783. last_word[i++] = *(buffer + bytes_written);
  784. bytes_remaining--;
  785. bytes_written++;
  786. }
  787. if (!(address & 0xff))
  788. LOG_DEBUG("0x%x", address);
  789. /* Program one word */
  790. target_write_u32(target, FLASH_FMA, address);
  791. target_write_buffer(target, FLASH_FMD, 4, last_word);
  792. target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_WRITE);
  793. /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
  794. /* Wait until write complete */
  795. do
  796. {
  797. target_read_u32(target, FLASH_FMC, &flash_fmc);
  798. } while (flash_fmc & FMC_WRITE);
  799. }
  800. /* Check access violations */
  801. target_read_u32(target, FLASH_CRIS, &flash_cris);
  802. if (flash_cris & (AMASK))
  803. {
  804. LOG_DEBUG("flash_cris 0x%x", flash_cris);
  805. return ERROR_FLASH_OPERATION_FAILED;
  806. }
  807. return ERROR_OK;
  808. }
  809. static int stellaris_probe(struct flash_bank_s *bank)
  810. {
  811. /* we can't probe on an stellaris
  812. * if this is an stellaris, it has the configured flash
  813. */
  814. if (bank->target->state != TARGET_HALTED)
  815. {
  816. LOG_ERROR("Target not halted");
  817. return ERROR_TARGET_NOT_HALTED;
  818. }
  819. /* stellaris_read_part_info() already takes care about error checking and reporting */
  820. return stellaris_read_part_info(bank);
  821. }
  822. static int stellaris_auto_probe(struct flash_bank_s *bank)
  823. {
  824. stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
  825. if (stellaris_info->did1)
  826. return ERROR_OK;
  827. return stellaris_probe(bank);
  828. }
  829. static int stellaris_mass_erase(struct flash_bank_s *bank)
  830. {
  831. target_t *target = NULL;
  832. stellaris_flash_bank_t *stellaris_info = NULL;
  833. u32 flash_fmc;
  834. stellaris_info = bank->driver_priv;
  835. target = bank->target;
  836. if (target->state != TARGET_HALTED)
  837. {
  838. LOG_ERROR("Target not halted");
  839. return ERROR_TARGET_NOT_HALTED;
  840. }
  841. if (stellaris_info->did1 == 0)
  842. {
  843. stellaris_read_part_info(bank);
  844. }
  845. if (stellaris_info->did1 == 0)
  846. {
  847. LOG_WARNING("Cannot identify target as Stellaris");
  848. return ERROR_FLASH_OPERATION_FAILED;
  849. }
  850. /* Configure the flash controller timing */
  851. stellaris_read_clock_info(bank);
  852. stellaris_set_flash_mode(bank, 0);
  853. /* Clear and disable flash programming interrupts */
  854. target_write_u32(target, FLASH_CIM, 0);
  855. target_write_u32(target, FLASH_MISC, PMISC|AMISC);
  856. target_write_u32(target, FLASH_FMA, 0);
  857. target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_MERASE);
  858. /* Wait until erase complete */
  859. do
  860. {
  861. target_read_u32(target, FLASH_FMC, &flash_fmc);
  862. }
  863. while (flash_fmc & FMC_MERASE);
  864. /* if device has > 128k, then second erase cycle is needed
  865. * this is only valid for older devices, but will not hurt */
  866. if (stellaris_info->num_pages * stellaris_info->pagesize > 0x20000)
  867. {
  868. target_write_u32(target, FLASH_FMA, 0x20000);
  869. target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_MERASE);
  870. /* Wait until erase complete */
  871. do
  872. {
  873. target_read_u32(target, FLASH_FMC, &flash_fmc);
  874. }
  875. while (flash_fmc & FMC_MERASE);
  876. }
  877. return ERROR_OK;
  878. }
  879. static int stellaris_handle_mass_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  880. {
  881. flash_bank_t *bank;
  882. int i;
  883. if (argc < 1)
  884. {
  885. command_print(cmd_ctx, "stellaris mass_erase <bank>");
  886. return ERROR_OK;
  887. }
  888. bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
  889. if (!bank)
  890. {
  891. command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
  892. return ERROR_OK;
  893. }
  894. if (stellaris_mass_erase(bank) == ERROR_OK)
  895. {
  896. /* set all sectors as erased */
  897. for (i = 0; i < bank->num_sectors; i++)
  898. {
  899. bank->sectors[i].is_erased = 1;
  900. }
  901. command_print(cmd_ctx, "stellaris mass erase complete");
  902. }
  903. else
  904. {
  905. command_print(cmd_ctx, "stellaris mass erase failed");
  906. }
  907. return ERROR_OK;
  908. }