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.
 
 
 
 
 
 

955 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. There are some things to notice
  22. * AT91SAM7S64 is tested
  23. * All AT91SAM7Sxx and AT91SAM7Xxx should work but is not tested
  24. * All parameters are identified from onchip configuartion registers
  25. *
  26. * The flash controller handles erases automatically on a page (128/265 byte) basis
  27. * Only an EraseAll command is supported by the controller
  28. * Partial erases can be implemented in software by writing one 0xFFFFFFFF word to
  29. * some location in every page in the region to be erased
  30. *
  31. * Lock regions (sectors) are 32 or 64 pages
  32. *
  33. ***************************************************************************/
  34. #ifdef HAVE_CONFIG_H
  35. #include "config.h"
  36. #endif
  37. #include "replacements.h"
  38. #include "at91sam7.h"
  39. #include "flash.h"
  40. #include "target.h"
  41. #include "log.h"
  42. #include "binarybuffer.h"
  43. #include "types.h"
  44. #include <stdlib.h>
  45. #include <string.h>
  46. #include <unistd.h>
  47. int at91sam7_register_commands(struct command_context_s *cmd_ctx);
  48. int at91sam7_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
  49. int at91sam7_erase(struct flash_bank_s *bank, int first, int last);
  50. int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int last);
  51. int at91sam7_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
  52. int at91sam7_probe(struct flash_bank_s *bank);
  53. int at91sam7_auto_probe(struct flash_bank_s *bank);
  54. int at91sam7_erase_check(struct flash_bank_s *bank);
  55. int at91sam7_protect_check(struct flash_bank_s *bank);
  56. int at91sam7_info(struct flash_bank_s *bank, char *buf, int buf_size);
  57. u32 at91sam7_get_flash_status(flash_bank_t *bank, u8 flashplane);
  58. void at91sam7_set_flash_mode(flash_bank_t *bank, u8 flashplane, int mode);
  59. u32 at91sam7_wait_status_busy(flash_bank_t *bank, u8 flashplane, u32 waitbits, int timeout);
  60. int at91sam7_flash_command(struct flash_bank_s *bank, u8 flashplane, u8 cmd, u16 pagen);
  61. int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
  62. flash_driver_t at91sam7_flash =
  63. {
  64. .name = "at91sam7",
  65. .register_commands = at91sam7_register_commands,
  66. .flash_bank_command = at91sam7_flash_bank_command,
  67. .erase = at91sam7_erase,
  68. .protect = at91sam7_protect,
  69. .write = at91sam7_write,
  70. .probe = at91sam7_probe,
  71. .auto_probe = at91sam7_probe,
  72. .erase_check = at91sam7_erase_check,
  73. .protect_check = at91sam7_protect_check,
  74. .info = at91sam7_info
  75. };
  76. u32 MC_FMR[4] = { 0xFFFFFF60, 0xFFFFFF70, 0xFFFFFF80, 0xFFFFFF90 };
  77. u32 MC_FCR[4] = { 0xFFFFFF64, 0xFFFFFF74, 0xFFFFFF84, 0xFFFFFF94 };
  78. u32 MC_FSR[4] = { 0xFFFFFF68, 0xFFFFFF78, 0xFFFFFF88, 0xFFFFFF98 };
  79. char * EPROC[8]= {"Unknown","ARM946-E","ARM7TDMI","Unknown","ARM920T","ARM926EJ-S","Unknown","Unknown"};
  80. long NVPSIZ[16] = {
  81. 0,
  82. 0x2000, /* 8K */
  83. 0x4000, /* 16K */
  84. 0x8000, /* 32K */
  85. -1,
  86. 0x10000, /* 64K */
  87. -1,
  88. 0x20000, /* 128K */
  89. -1,
  90. 0x40000, /* 256K */
  91. 0x80000, /* 512K */
  92. -1,
  93. 0x100000, /* 1024K */
  94. -1,
  95. 0x200000, /* 2048K */
  96. -1
  97. };
  98. long SRAMSIZ[16] = {
  99. -1,
  100. 0x0400, /* 1K */
  101. 0x0800, /* 2K */
  102. -1,
  103. 0x1c000, /* 112K */
  104. 0x1000, /* 4K */
  105. 0x14000, /* 80K */
  106. 0x28000, /* 160K */
  107. 0x2000, /* 8K */
  108. 0x4000, /* 16K */
  109. 0x8000, /* 32K */
  110. 0x10000, /* 64K */
  111. 0x20000, /* 128K */
  112. 0x40000, /* 256K */
  113. 0x18000, /* 96K */
  114. 0x80000, /* 512K */
  115. };
  116. int at91sam7_register_commands(struct command_context_s *cmd_ctx)
  117. {
  118. command_t *at91sam7_cmd = register_command(cmd_ctx, NULL, "at91sam7", NULL, COMMAND_ANY, NULL);
  119. register_command(cmd_ctx, at91sam7_cmd, "gpnvm", at91sam7_handle_gpnvm_command, COMMAND_EXEC,
  120. "at91sam7 gpnvm <num> <bit> set|clear, set or clear at91sam7 gpnvm bit");
  121. return ERROR_OK;
  122. }
  123. u32 at91sam7_get_flash_status(flash_bank_t *bank, u8 flashplane)
  124. {
  125. target_t *target = bank->target;
  126. u32 fsr;
  127. target_read_u32(target, MC_FSR[flashplane], &fsr);
  128. return fsr;
  129. }
  130. /* Read clock configuration and set at91sam7_info->usec_clocks*/
  131. void at91sam7_read_clock_info(flash_bank_t *bank)
  132. {
  133. at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
  134. target_t *target = bank->target;
  135. u32 mckr, mcfr, pllr;
  136. unsigned long tmp = 0, mainfreq;
  137. int flashplane;
  138. /* Read main clock freqency register */
  139. target_read_u32(target, CKGR_MCFR, &mcfr);
  140. /* Read master clock register */
  141. target_read_u32(target, PMC_MCKR, &mckr);
  142. /* Read Clock Generator PLL Register */
  143. target_read_u32(target, CKGR_PLLR, &pllr);
  144. at91sam7_info->mck_valid = 0;
  145. switch (mckr & PMC_MCKR_CSS)
  146. {
  147. case 0: /* Slow Clock */
  148. at91sam7_info->mck_valid = 1;
  149. mainfreq = RC_FREQ / 16ul * (mcfr & 0xffff);
  150. tmp = mainfreq;
  151. break;
  152. case 1: /* Main Clock */
  153. if (mcfr & CKGR_MCFR_MAINRDY)
  154. {
  155. at91sam7_info->mck_valid = 1;
  156. mainfreq = RC_FREQ / 16ul * (mcfr & 0xffff);
  157. tmp = mainfreq;
  158. }
  159. break;
  160. case 2: /* Reserved */
  161. break;
  162. case 3: /* PLL Clock */
  163. if (mcfr & CKGR_MCFR_MAINRDY)
  164. {
  165. target_read_u32(target, CKGR_PLLR, &pllr);
  166. if (!(pllr & CKGR_PLLR_DIV))
  167. break; /* 0 Hz */
  168. at91sam7_info->mck_valid = 1;
  169. mainfreq = RC_FREQ / 16ul * (mcfr & 0xffff);
  170. /* Integer arithmetic should have sufficient precision
  171. as long as PLL is properly configured. */
  172. tmp = mainfreq / (pllr & CKGR_PLLR_DIV) *
  173. (((pllr & CKGR_PLLR_MUL) >> 16) + 1);
  174. }
  175. break;
  176. }
  177. /* Prescaler adjust */
  178. if (((mckr & PMC_MCKR_PRES) >> 2) == 7)
  179. at91sam7_info->mck_valid = 0;
  180. else
  181. at91sam7_info->mck_freq = tmp >> ((mckr & PMC_MCKR_PRES) >> 2);
  182. /* Forget old flash timing */
  183. for (flashplane = 0; flashplane<at91sam7_info->num_planes; flashplane++)
  184. {
  185. at91sam7_set_flash_mode(bank, flashplane, FMR_TIMING_NONE);
  186. }
  187. }
  188. /* Setup the timimg registers for nvbits or normal flash */
  189. void at91sam7_set_flash_mode(flash_bank_t *bank, u8 flashplane, int mode)
  190. {
  191. u32 fmr, fmcn = 0, fws = 0;
  192. at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
  193. target_t *target = bank->target;
  194. if (mode && (mode != at91sam7_info->flashmode[flashplane]))
  195. {
  196. /* Always round up (ceil) */
  197. if (mode==FMR_TIMING_NVBITS)
  198. {
  199. if (at91sam7_info->cidr_arch == 0x60)
  200. {
  201. /* AT91SAM7A3 uses master clocks in 100 ns */
  202. fmcn = (at91sam7_info->mck_freq/10000000ul)+1;
  203. }
  204. else
  205. {
  206. /* master clocks in 1uS for ARCH 0x7 types */
  207. fmcn = (at91sam7_info->mck_freq/1000000ul)+1;
  208. }
  209. }
  210. else if (mode==FMR_TIMING_FLASH)
  211. /* main clocks in 1.5uS */
  212. fmcn = (at91sam7_info->mck_freq/666666ul)+1;
  213. /* Only allow fmcn=0 if clock period is > 30 us = 33kHz. */
  214. if (at91sam7_info->mck_freq <= 33333ul)
  215. fmcn = 0;
  216. /* Only allow fws=0 if clock frequency is < 30 MHz. */
  217. if (at91sam7_info->mck_freq > 30000000ul)
  218. fws = 1;
  219. LOG_DEBUG("fmcn[%i]: %i", flashplane, fmcn);
  220. fmr = fmcn << 16 | fws << 8;
  221. target_write_u32(target, MC_FMR[flashplane], fmr);
  222. }
  223. at91sam7_info->flashmode[flashplane] = mode;
  224. }
  225. u32 at91sam7_wait_status_busy(flash_bank_t *bank, u8 flashplane, u32 waitbits, int timeout)
  226. {
  227. u32 status;
  228. while ((!((status = at91sam7_get_flash_status(bank,flashplane)) & waitbits)) && (timeout-- > 0))
  229. {
  230. LOG_DEBUG("status[%i]: 0x%x", flashplane, status);
  231. usleep(1000);
  232. }
  233. LOG_DEBUG("status[%i]: 0x%x", flashplane, status);
  234. if (status & 0x0C)
  235. {
  236. LOG_ERROR("status register: 0x%x", status);
  237. if (status & 0x4)
  238. LOG_ERROR("Lock Error Bit Detected, Operation Abort");
  239. if (status & 0x8)
  240. LOG_ERROR("Invalid command and/or bad keyword, Operation Abort");
  241. if (status & 0x10)
  242. LOG_ERROR("Security Bit Set, Operation Abort");
  243. }
  244. return status;
  245. }
  246. /* Send one command to the AT91SAM flash controller */
  247. int at91sam7_flash_command(struct flash_bank_s *bank, u8 flashplane, u8 cmd, u16 pagen)
  248. {
  249. u32 fcr;
  250. at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
  251. target_t *target = bank->target;
  252. fcr = (0x5A<<24) | ((pagen&0x3FF)<<8) | cmd;
  253. target_write_u32(target, MC_FCR[flashplane], fcr);
  254. LOG_DEBUG("Flash command: 0x%x, flashplane: %i, pagenumber:%u", fcr, flashplane, pagen);
  255. if ((at91sam7_info->cidr_arch == 0x60)&&((cmd==SLB)|(cmd==CLB)))
  256. {
  257. /* Lock bit manipulation on AT91SAM7A3 waits for FC_FSR bit 1, EOL */
  258. if (at91sam7_wait_status_busy(bank, flashplane, MC_FSR_EOL, 10)&0x0C)
  259. {
  260. return ERROR_FLASH_OPERATION_FAILED;
  261. }
  262. return ERROR_OK;
  263. }
  264. if (at91sam7_wait_status_busy(bank, flashplane, MC_FSR_FRDY, 10)&0x0C)
  265. {
  266. return ERROR_FLASH_OPERATION_FAILED;
  267. }
  268. return ERROR_OK;
  269. }
  270. /* Read device id register, main clock frequency register and fill in driver info structure */
  271. int at91sam7_read_part_info(struct flash_bank_s *bank)
  272. {
  273. at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
  274. target_t *target = bank->target;
  275. u32 cidr, status;
  276. int sectornum;
  277. if (at91sam7_info->cidr != 0)
  278. return ERROR_OK; /* already probed, multiple probes may cause memory leak, not allowed */
  279. /* Read and parse chip identification register */
  280. target_read_u32(target, DBGU_CIDR, &cidr);
  281. if (cidr == 0)
  282. {
  283. LOG_WARNING("Cannot identify target as an AT91SAM");
  284. return ERROR_FLASH_OPERATION_FAILED;
  285. }
  286. at91sam7_info->cidr = cidr;
  287. at91sam7_info->cidr_ext = (cidr>>31)&0x0001;
  288. at91sam7_info->cidr_nvptyp = (cidr>>28)&0x0007;
  289. at91sam7_info->cidr_arch = (cidr>>20)&0x00FF;
  290. at91sam7_info->cidr_sramsiz = (cidr>>16)&0x000F;
  291. at91sam7_info->cidr_nvpsiz2 = (cidr>>12)&0x000F;
  292. at91sam7_info->cidr_nvpsiz = (cidr>>8)&0x000F;
  293. at91sam7_info->cidr_eproc = (cidr>>5)&0x0007;
  294. at91sam7_info->cidr_version = cidr&0x001F;
  295. bank->size = NVPSIZ[at91sam7_info->cidr_nvpsiz];
  296. at91sam7_info->target_name = "Unknown";
  297. /* Support just for bulk erase of a single flash plane, whole device if flash size <= 256k */
  298. if (NVPSIZ[at91sam7_info->cidr_nvpsiz]<0x80000) /* Flash size less than 512K, one flash plane */
  299. {
  300. bank->num_sectors = 1;
  301. bank->sectors = malloc(sizeof(flash_sector_t));
  302. bank->sectors[0].offset = 0;
  303. bank->sectors[0].size = bank->size;
  304. bank->sectors[0].is_erased = -1;
  305. bank->sectors[0].is_protected = -1;
  306. }
  307. else /* Flash size 512K or larger, several flash planes */
  308. {
  309. bank->num_sectors = NVPSIZ[at91sam7_info->cidr_nvpsiz]/0x40000;
  310. bank->sectors = malloc(bank->num_sectors*sizeof(flash_sector_t));
  311. for (sectornum=0; sectornum<bank->num_sectors; sectornum++)
  312. {
  313. bank->sectors[sectornum].offset = sectornum*0x40000;
  314. bank->sectors[sectornum].size = 0x40000;
  315. bank->sectors[sectornum].is_erased = -1;
  316. bank->sectors[sectornum].is_protected = -1;
  317. }
  318. }
  319. LOG_DEBUG("nvptyp: 0x%3.3x, arch: 0x%4.4x", at91sam7_info->cidr_nvptyp, at91sam7_info->cidr_arch );
  320. /* Read main and master clock freqency register */
  321. at91sam7_read_clock_info(bank);
  322. at91sam7_info->num_planes = 1;
  323. status = at91sam7_get_flash_status(bank, 0);
  324. at91sam7_info->securitybit = (status>>4)&0x01;
  325. at91sam7_protect_check(bank); /* TODO Check the protect check */
  326. if (at91sam7_info->cidr_arch == 0x70 )
  327. {
  328. at91sam7_info->num_nvmbits = 2;
  329. at91sam7_info->nvmbits = (status>>8)&0x03;
  330. bank->base = 0x100000;
  331. bank->bus_width = 4;
  332. if (bank->size==0x80000) /* AT91SAM7S512 */
  333. {
  334. at91sam7_info->target_name = "AT91SAM7S512";
  335. at91sam7_info->num_planes = 2;
  336. if (at91sam7_info->num_planes != bank->num_sectors)
  337. LOG_WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");;
  338. at91sam7_info->num_lockbits = 2*16;
  339. at91sam7_info->pagesize = 256;
  340. at91sam7_info->pages_in_lockregion = 64;
  341. at91sam7_info->num_pages = 2*16*64;
  342. }
  343. if (bank->size==0x40000) /* AT91SAM7S256 */
  344. {
  345. at91sam7_info->target_name = "AT91SAM7S256";
  346. at91sam7_info->num_lockbits = 16;
  347. at91sam7_info->pagesize = 256;
  348. at91sam7_info->pages_in_lockregion = 64;
  349. at91sam7_info->num_pages = 16*64;
  350. }
  351. if (bank->size==0x20000) /* AT91SAM7S128 */
  352. {
  353. at91sam7_info->target_name = "AT91SAM7S128";
  354. at91sam7_info->num_lockbits = 8;
  355. at91sam7_info->pagesize = 256;
  356. at91sam7_info->pages_in_lockregion = 64;
  357. at91sam7_info->num_pages = 8*64;
  358. }
  359. if (bank->size==0x10000) /* AT91SAM7S64 */
  360. {
  361. at91sam7_info->target_name = "AT91SAM7S64";
  362. at91sam7_info->num_lockbits = 16;
  363. at91sam7_info->pagesize = 128;
  364. at91sam7_info->pages_in_lockregion = 32;
  365. at91sam7_info->num_pages = 16*32;
  366. }
  367. if (bank->size==0x08000) /* AT91SAM7S321/32 */
  368. {
  369. at91sam7_info->target_name = "AT91SAM7S321/32";
  370. at91sam7_info->num_lockbits = 8;
  371. at91sam7_info->pagesize = 128;
  372. at91sam7_info->pages_in_lockregion = 32;
  373. at91sam7_info->num_pages = 8*32;
  374. }
  375. return ERROR_OK;
  376. }
  377. if (at91sam7_info->cidr_arch == 0x71 )
  378. {
  379. at91sam7_info->num_nvmbits = 3;
  380. at91sam7_info->nvmbits = (status>>8)&0x07;
  381. bank->base = 0x100000;
  382. bank->bus_width = 4;
  383. if (bank->size==0x80000) /* AT91SAM7XC512 */
  384. {
  385. at91sam7_info->target_name = "AT91SAM7XC512";
  386. at91sam7_info->num_planes = 2;
  387. if (at91sam7_info->num_planes != bank->num_sectors)
  388. LOG_WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");;
  389. at91sam7_info->num_lockbits = 2*16;
  390. at91sam7_info->pagesize = 256;
  391. at91sam7_info->pages_in_lockregion = 64;
  392. at91sam7_info->num_pages = 2*16*64;
  393. }
  394. if (bank->size==0x40000) /* AT91SAM7XC256 */
  395. {
  396. at91sam7_info->target_name = "AT91SAM7XC256";
  397. at91sam7_info->num_lockbits = 16;
  398. at91sam7_info->pagesize = 256;
  399. at91sam7_info->pages_in_lockregion = 64;
  400. at91sam7_info->num_pages = 16*64;
  401. }
  402. if (bank->size==0x20000) /* AT91SAM7XC128 */
  403. {
  404. at91sam7_info->target_name = "AT91SAM7XC128";
  405. at91sam7_info->num_lockbits = 8;
  406. at91sam7_info->pagesize = 256;
  407. at91sam7_info->pages_in_lockregion = 64;
  408. at91sam7_info->num_pages = 8*64;
  409. }
  410. return ERROR_OK;
  411. }
  412. if (at91sam7_info->cidr_arch == 0x72 )
  413. {
  414. at91sam7_info->num_nvmbits = 3;
  415. at91sam7_info->nvmbits = (status>>8)&0x07;
  416. bank->base = 0x100000;
  417. bank->bus_width = 4;
  418. if (bank->size==0x80000) /* AT91SAM7SE512 */
  419. {
  420. at91sam7_info->target_name = "AT91SAM7SE512";
  421. at91sam7_info->num_planes = 2;
  422. if (at91sam7_info->num_planes != bank->num_sectors)
  423. LOG_WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");;
  424. at91sam7_info->num_lockbits = 32;
  425. at91sam7_info->pagesize = 256;
  426. at91sam7_info->pages_in_lockregion = 64;
  427. at91sam7_info->num_pages = 32*64;
  428. }
  429. if (bank->size==0x40000)
  430. {
  431. at91sam7_info->target_name = "AT91SAM7SE256";
  432. at91sam7_info->num_lockbits = 16;
  433. at91sam7_info->pagesize = 256;
  434. at91sam7_info->pages_in_lockregion = 64;
  435. at91sam7_info->num_pages = 16*64;
  436. }
  437. if (bank->size==0x08000)
  438. {
  439. at91sam7_info->target_name = "AT91SAM7SE32";
  440. at91sam7_info->num_lockbits = 8;
  441. at91sam7_info->pagesize = 128;
  442. at91sam7_info->pages_in_lockregion = 32;
  443. at91sam7_info->num_pages = 8*32;
  444. }
  445. return ERROR_OK;
  446. }
  447. if (at91sam7_info->cidr_arch == 0x75 )
  448. {
  449. at91sam7_info->num_nvmbits = 3;
  450. at91sam7_info->nvmbits = (status>>8)&0x07;
  451. bank->base = 0x100000;
  452. bank->bus_width = 4;
  453. if (bank->size==0x80000) /* AT91SAM7X512 */
  454. {
  455. at91sam7_info->target_name = "AT91SAM7X512";
  456. at91sam7_info->num_planes = 2;
  457. if (at91sam7_info->num_planes != bank->num_sectors)
  458. LOG_WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");;
  459. at91sam7_info->num_lockbits = 32;
  460. at91sam7_info->pagesize = 256;
  461. at91sam7_info->pages_in_lockregion = 64;
  462. at91sam7_info->num_pages = 2*16*64;
  463. LOG_DEBUG("Support for AT91SAM7X512 is experimental in this version!");
  464. }
  465. if (bank->size==0x40000) /* AT91SAM7X256 */
  466. {
  467. at91sam7_info->target_name = "AT91SAM7X256";
  468. at91sam7_info->num_lockbits = 16;
  469. at91sam7_info->pagesize = 256;
  470. at91sam7_info->pages_in_lockregion = 64;
  471. at91sam7_info->num_pages = 16*64;
  472. }
  473. if (bank->size==0x20000) /* AT91SAM7X128 */
  474. {
  475. at91sam7_info->target_name = "AT91SAM7X128";
  476. at91sam7_info->num_lockbits = 8;
  477. at91sam7_info->pagesize = 256;
  478. at91sam7_info->pages_in_lockregion = 64;
  479. at91sam7_info->num_pages = 8*64;
  480. }
  481. return ERROR_OK;
  482. }
  483. if (at91sam7_info->cidr_arch == 0x60 )
  484. {
  485. at91sam7_info->num_nvmbits = 3;
  486. at91sam7_info->nvmbits = (status>>8)&0x07;
  487. bank->base = 0x100000;
  488. bank->bus_width = 4;
  489. if (bank->size == 0x40000) /* AT91SAM7A3 */
  490. {
  491. at91sam7_info->target_name = "AT91SAM7A3";
  492. at91sam7_info->num_lockbits = 16;
  493. at91sam7_info->pagesize = 256;
  494. at91sam7_info->pages_in_lockregion = 16;
  495. at91sam7_info->num_pages = 16*64;
  496. }
  497. return ERROR_OK;
  498. }
  499. LOG_WARNING("at91sam7 flash only tested for AT91SAM7Sxx series");
  500. return ERROR_OK;
  501. }
  502. int at91sam7_erase_check(struct flash_bank_s *bank)
  503. {
  504. at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
  505. if (!at91sam7_info->working_area_size)
  506. {
  507. }
  508. else
  509. {
  510. }
  511. return ERROR_OK;
  512. }
  513. int at91sam7_protect_check(struct flash_bank_s *bank)
  514. {
  515. u32 status;
  516. int flashplane;
  517. at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
  518. if (at91sam7_info->cidr == 0)
  519. {
  520. return ERROR_FLASH_BANK_NOT_PROBED;
  521. }
  522. if (bank->target->state != TARGET_HALTED)
  523. {
  524. LOG_ERROR("Target not halted");
  525. return ERROR_TARGET_NOT_HALTED;
  526. }
  527. for (flashplane=0;flashplane<at91sam7_info->num_planes;flashplane++)
  528. {
  529. status = at91sam7_get_flash_status(bank, flashplane);
  530. at91sam7_info->lockbits[flashplane] = (status >> 16);
  531. }
  532. return ERROR_OK;
  533. }
  534. /* flash_bank at91sam7 0 0 0 0 <target#>
  535. */
  536. int at91sam7_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
  537. {
  538. at91sam7_flash_bank_t *at91sam7_info;
  539. int i;
  540. if (argc < 6)
  541. {
  542. LOG_WARNING("incomplete flash_bank at91sam7 configuration");
  543. return ERROR_FLASH_BANK_INVALID;
  544. }
  545. at91sam7_info = malloc(sizeof(at91sam7_flash_bank_t));
  546. bank->driver_priv = at91sam7_info;
  547. /* part wasn't probed for info yet */
  548. at91sam7_info->cidr = 0;
  549. for (i=0;i<4;i++)
  550. at91sam7_info->flashmode[i]=0;
  551. return ERROR_OK;
  552. }
  553. int at91sam7_erase(struct flash_bank_s *bank, int first, int last)
  554. {
  555. at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
  556. u8 flashplane;
  557. if (at91sam7_info->cidr == 0)
  558. {
  559. return ERROR_FLASH_BANK_NOT_PROBED;
  560. }
  561. if (bank->target->state != TARGET_HALTED)
  562. {
  563. LOG_ERROR("Target not halted");
  564. return ERROR_TARGET_NOT_HALTED;
  565. }
  566. if ((first < 0) || (last < first) || (last >= bank->num_sectors))
  567. {
  568. if ((first == 0) && (last == (at91sam7_info->num_lockbits-1)))
  569. {
  570. LOG_WARNING("Sector numbers based on lockbit count, probably a deprecated script");
  571. last = bank->num_sectors-1;
  572. }
  573. else return ERROR_FLASH_SECTOR_INVALID;
  574. }
  575. /* Configure the flash controller timing */
  576. at91sam7_read_clock_info(bank);
  577. for (flashplane = first; flashplane<=last; flashplane++)
  578. {
  579. /* Configure the flash controller timing */
  580. at91sam7_set_flash_mode(bank, flashplane, FMR_TIMING_FLASH);
  581. if (at91sam7_flash_command(bank, flashplane, EA, 0) != ERROR_OK)
  582. {
  583. return ERROR_FLASH_OPERATION_FAILED;
  584. }
  585. }
  586. return ERROR_OK;
  587. }
  588. int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int last)
  589. {
  590. u32 cmd, pagen;
  591. u8 flashplane;
  592. int lockregion;
  593. at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
  594. if (at91sam7_info->cidr == 0)
  595. {
  596. return ERROR_FLASH_BANK_NOT_PROBED;
  597. }
  598. if (bank->target->state != TARGET_HALTED)
  599. {
  600. LOG_ERROR("Target not halted");
  601. return ERROR_TARGET_NOT_HALTED;
  602. }
  603. if ((first < 0) || (last < first) || (last >= at91sam7_info->num_lockbits))
  604. {
  605. return ERROR_FLASH_SECTOR_INVALID;
  606. }
  607. at91sam7_read_clock_info(bank);
  608. for (lockregion=first;lockregion<=last;lockregion++)
  609. {
  610. pagen = lockregion*at91sam7_info->pages_in_lockregion;
  611. flashplane = (pagen>>10)&0x03;
  612. /* Configure the flash controller timing */
  613. at91sam7_set_flash_mode(bank, flashplane, FMR_TIMING_NVBITS);
  614. if (set)
  615. cmd = SLB;
  616. else
  617. cmd = CLB;
  618. if (at91sam7_flash_command(bank, flashplane, cmd, pagen) != ERROR_OK)
  619. {
  620. return ERROR_FLASH_OPERATION_FAILED;
  621. }
  622. }
  623. at91sam7_protect_check(bank);
  624. return ERROR_OK;
  625. }
  626. int at91sam7_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
  627. {
  628. at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
  629. target_t *target = bank->target;
  630. u32 dst_min_alignment, wcount, bytes_remaining = count;
  631. u32 first_page, last_page, pagen, buffer_pos;
  632. u8 flashplane;
  633. if (at91sam7_info->cidr == 0)
  634. {
  635. return ERROR_FLASH_BANK_NOT_PROBED;
  636. }
  637. if (bank->target->state != TARGET_HALTED)
  638. {
  639. LOG_ERROR("Target not halted");
  640. return ERROR_TARGET_NOT_HALTED;
  641. }
  642. if (offset + count > bank->size)
  643. return ERROR_FLASH_DST_OUT_OF_BANK;
  644. dst_min_alignment = at91sam7_info->pagesize;
  645. if (offset % dst_min_alignment)
  646. {
  647. LOG_WARNING("offset 0x%x breaks required alignment 0x%x", offset, dst_min_alignment);
  648. return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
  649. }
  650. if (at91sam7_info->cidr_arch == 0)
  651. return ERROR_FLASH_BANK_NOT_PROBED;
  652. first_page = offset/dst_min_alignment;
  653. last_page = CEIL(offset + count, dst_min_alignment);
  654. LOG_DEBUG("first_page: %i, last_page: %i, count %i", first_page, last_page, count);
  655. at91sam7_read_clock_info(bank);
  656. for (pagen=first_page; pagen<last_page; pagen++)
  657. {
  658. if (bytes_remaining<dst_min_alignment)
  659. count = bytes_remaining;
  660. else
  661. count = dst_min_alignment;
  662. bytes_remaining -= count;
  663. /* Write one block to the PageWriteBuffer */
  664. buffer_pos = (pagen-first_page)*dst_min_alignment;
  665. wcount = CEIL(count,4);
  666. target->type->write_memory(target, bank->base+pagen*dst_min_alignment, 4, wcount, buffer+buffer_pos);
  667. flashplane = (pagen>>10)&0x3;
  668. /* Configure the flash controller timing */
  669. at91sam7_set_flash_mode(bank, flashplane, FMR_TIMING_FLASH);
  670. /* Send Write Page command to Flash Controller */
  671. if (at91sam7_flash_command(bank, flashplane, WP, pagen) != ERROR_OK)
  672. {
  673. return ERROR_FLASH_OPERATION_FAILED;
  674. }
  675. LOG_DEBUG("Write flash plane:%i page number:%i", flashplane, pagen);
  676. }
  677. return ERROR_OK;
  678. }
  679. int at91sam7_probe(struct flash_bank_s *bank)
  680. {
  681. /* we can't probe on an at91sam7
  682. * if this is an at91sam7, it has the configured flash
  683. */
  684. at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
  685. int retval;
  686. if (at91sam7_info->cidr != 0)
  687. {
  688. return ERROR_OK; /* already probed */
  689. }
  690. if (bank->target->state != TARGET_HALTED)
  691. {
  692. LOG_ERROR("Target not halted");
  693. return ERROR_TARGET_NOT_HALTED;
  694. }
  695. retval = at91sam7_read_part_info(bank);
  696. if (retval != ERROR_OK)
  697. return retval;
  698. return ERROR_OK;
  699. }
  700. int at91sam7_info(struct flash_bank_s *bank, char *buf, int buf_size)
  701. {
  702. int printed, flashplane;
  703. at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
  704. if (at91sam7_info->cidr == 0)
  705. {
  706. return ERROR_FLASH_BANK_NOT_PROBED;
  707. }
  708. printed = snprintf(buf, buf_size, "\nat91sam7 information: Chip is %s\n",at91sam7_info->target_name);
  709. buf += printed;
  710. buf_size -= printed;
  711. printed = snprintf(buf, buf_size, "cidr: 0x%8.8x, arch: 0x%4.4x, eproc: %s, version:0x%3.3x, flashsize: 0x%8.8x\n",
  712. at91sam7_info->cidr, at91sam7_info->cidr_arch, EPROC[at91sam7_info->cidr_eproc], at91sam7_info->cidr_version, bank->size);
  713. buf += printed;
  714. buf_size -= printed;
  715. printed = snprintf(buf, buf_size, "master clock(estimated): %ikHz \n", at91sam7_info->mck_freq / 1000);
  716. buf += printed;
  717. buf_size -= printed;
  718. if (at91sam7_info->num_planes>1) {
  719. printed = snprintf(buf, buf_size, "flashplanes: %i, pagesize: %i, lock regions: %i, pages in lock region: %i \n",
  720. at91sam7_info->num_planes, at91sam7_info->pagesize, at91sam7_info->num_lockbits, at91sam7_info->num_pages/at91sam7_info->num_lockbits);
  721. buf += printed;
  722. buf_size -= printed;
  723. for (flashplane=0; flashplane<at91sam7_info->num_planes; flashplane++)
  724. {
  725. printed = snprintf(buf, buf_size, "lockbits[%i]: 0x%4.4x, ", flashplane, at91sam7_info->lockbits[flashplane]);
  726. buf += printed;
  727. buf_size -= printed;
  728. }
  729. }
  730. else
  731. if (at91sam7_info->num_lockbits>0) {
  732. printed = snprintf(buf, buf_size, "pagesize: %i, lockbits: %i 0x%4.4x, pages in lock region: %i \n",
  733. at91sam7_info->pagesize, at91sam7_info->num_lockbits, at91sam7_info->lockbits[0], at91sam7_info->num_pages/at91sam7_info->num_lockbits);
  734. buf += printed;
  735. buf_size -= printed;
  736. }
  737. printed = snprintf(buf, buf_size, "securitybit: %i, nvmbits(%i): 0x%1.1x\n", at91sam7_info->securitybit, at91sam7_info->num_nvmbits, at91sam7_info->nvmbits);
  738. buf += printed;
  739. buf_size -= printed;
  740. return ERROR_OK;
  741. }
  742. /*
  743. * On AT91SAM7S: When the gpnvm bits are set with
  744. * > at91sam7 gpnvm 0 bitnr set
  745. * the changes are not visible in the flash controller status register MC_FSR
  746. * until the processor has been reset.
  747. * On the Olimex board this requires a power cycle.
  748. * Note that the AT91SAM7S has the following errata (doc6175.pdf sec 14.1.3):
  749. * The maximum number of write/erase cycles for Non Volatile Memory bits is 100. This includes
  750. * Lock Bits (LOCKx), General Purpose NVM bits (GPNVMx) and the Security Bit.
  751. */
  752. int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  753. {
  754. flash_bank_t *bank;
  755. int bit;
  756. u8 flashcmd;
  757. u32 status;
  758. char *value;
  759. at91sam7_flash_bank_t *at91sam7_info;
  760. int retval;
  761. if (argc < 3)
  762. {
  763. command_print(cmd_ctx, "at91sam7 gpnvm <num> <bit> <set|clear>");
  764. return ERROR_OK;
  765. }
  766. bank = get_flash_bank_by_num_noprobe(strtoul(args[0], NULL, 0));
  767. bit = atoi(args[1]);
  768. value = args[2];
  769. if (bank == NULL)
  770. {
  771. return ERROR_FLASH_BANK_INVALID;
  772. }
  773. if (bank->driver != &at91sam7_flash)
  774. {
  775. command_print(cmd_ctx, "not an at91sam7 flash bank '%s'", args[0]);
  776. return ERROR_FLASH_BANK_INVALID;
  777. }
  778. if (strcmp(value, "set") == 0)
  779. {
  780. flashcmd = SGPB;
  781. }
  782. else if (strcmp(value, "clear") == 0)
  783. {
  784. flashcmd = CGPB;
  785. }
  786. else
  787. {
  788. return ERROR_COMMAND_SYNTAX_ERROR;
  789. }
  790. at91sam7_info = bank->driver_priv;
  791. if (bank->target->state != TARGET_HALTED)
  792. {
  793. LOG_ERROR("target has to be halted to perform flash operation");
  794. return ERROR_TARGET_NOT_HALTED;
  795. }
  796. if (at91sam7_info->cidr == 0)
  797. {
  798. retval = at91sam7_read_part_info(bank);
  799. if (retval != ERROR_OK) {
  800. return retval;
  801. }
  802. }
  803. if ((bit<0) || (at91sam7_info->num_nvmbits <= bit))
  804. {
  805. command_print(cmd_ctx, "gpnvm bit '#%s' is out of bounds for target %s", args[1],at91sam7_info->target_name);
  806. return ERROR_OK;
  807. }
  808. /* Configure the flash controller timing */
  809. at91sam7_read_clock_info(bank);
  810. at91sam7_set_flash_mode(bank, 0, FMR_TIMING_NVBITS);
  811. if (at91sam7_flash_command(bank, 0, flashcmd, (u16)(bit)) != ERROR_OK)
  812. {
  813. return ERROR_FLASH_OPERATION_FAILED;
  814. }
  815. status = at91sam7_get_flash_status(bank, 0);
  816. LOG_DEBUG("at91sam7_handle_gpnvm_command: cmd 0x%x, value 0x%x, status 0x%x \n",flashcmd,bit,status);
  817. at91sam7_info->nvmbits = (status>>8)&((1<<at91sam7_info->num_nvmbits)-1);
  818. return ERROR_OK;
  819. }