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.
 
 
 
 
 
 

1033 lines
28 KiB

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