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.
 
 
 
 
 
 

363 lines
9.8 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2007 by Pavel Chromy *
  3. * chromy@asix.cz *
  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. #ifdef HAVE_CONFIG_H
  21. #include "config.h"
  22. #endif
  23. #include "ocl.h"
  24. #include "flash.h"
  25. #include "embeddedice.h"
  26. struct ocl_priv
  27. {
  28. struct arm_jtag *jtag_info;
  29. unsigned int buflen;
  30. unsigned int bufalign;
  31. };
  32. static int ocl_erase_check(struct flash_bank *bank)
  33. {
  34. return ERROR_OK;
  35. }
  36. static int ocl_protect_check(struct flash_bank *bank)
  37. {
  38. return ERROR_OK;
  39. }
  40. /* flash_bank ocl 0 0 0 0 <target#> */
  41. FLASH_BANK_COMMAND_HANDLER(ocl_flash_bank_command)
  42. {
  43. int retval;
  44. struct arm *armv4_5;
  45. struct arm7_9_common *arm7_9;
  46. struct ocl_priv *ocl;
  47. if (argc < 6)
  48. {
  49. LOG_WARNING("incomplete flash_bank ocl configuration");
  50. return ERROR_FLASH_BANK_INVALID;
  51. }
  52. if ((retval = arm7_9_get_arch_pointers(bank->target, &armv4_5, &arm7_9)) != ERROR_OK)
  53. return retval;
  54. ocl = bank->driver_priv = malloc(sizeof(struct ocl_priv));
  55. ocl->jtag_info = &arm7_9->jtag_info;
  56. ocl->buflen = 0;
  57. ocl->bufalign = 1;
  58. return ERROR_OK;
  59. }
  60. static int ocl_erase(struct flash_bank *bank, int first, int last)
  61. {
  62. struct ocl_priv *ocl = bank->driver_priv;
  63. int retval;
  64. uint32_t dcc_buffer[3];
  65. /* check preconditions */
  66. if (bank->num_sectors == 0)
  67. return ERROR_FLASH_BANK_NOT_PROBED;
  68. if (bank->target->state != TARGET_RUNNING)
  69. {
  70. LOG_ERROR("target has to be running to communicate with the loader");
  71. return ERROR_TARGET_NOT_RUNNING;
  72. }
  73. if ((first == 0) && (last == bank->num_sectors - 1))
  74. {
  75. dcc_buffer[0] = OCL_ERASE_ALL;
  76. if ((retval = embeddedice_send(ocl->jtag_info, dcc_buffer, 1) != ERROR_OK))
  77. return retval;
  78. }
  79. else
  80. {
  81. dcc_buffer[0] = OCL_ERASE_BLOCK;
  82. dcc_buffer[1] = first;
  83. dcc_buffer[2] = last;
  84. if ((retval = embeddedice_send(ocl->jtag_info, dcc_buffer, 3) != ERROR_OK))
  85. return retval;
  86. }
  87. /* wait for response, fixed timeout of 1 s */
  88. if ((retval = embeddedice_handshake(ocl->jtag_info, EICE_COMM_CTRL_WBIT, 1000) != ERROR_OK))
  89. {
  90. if (retval == ERROR_TARGET_TIMEOUT)
  91. LOG_ERROR("loader not responding");
  92. return retval;
  93. }
  94. /* receive response */
  95. if ((retval = embeddedice_receive(ocl->jtag_info, dcc_buffer + 1, 1) != ERROR_OK))
  96. return retval;
  97. if (dcc_buffer[1] != OCL_CMD_DONE)
  98. {
  99. if (dcc_buffer[0] == OCL_ERASE_ALL)
  100. LOG_ERROR("loader response to OCL_ERASE_ALL 0x%08" PRIx32 "", dcc_buffer[1]);
  101. else
  102. LOG_ERROR("loader response to OCL_ERASE_BLOCK 0x%08" PRIx32 "", dcc_buffer[1]);
  103. return ERROR_FLASH_OPERATION_FAILED;
  104. }
  105. return ERROR_OK;
  106. }
  107. static int ocl_protect(struct flash_bank *bank, int set, int first, int last)
  108. {
  109. return ERROR_OK;
  110. }
  111. static int ocl_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
  112. {
  113. struct ocl_priv *ocl = bank->driver_priv;
  114. int retval;
  115. uint32_t *dcc_buffer;
  116. uint32_t *dcc_bufptr;
  117. int byteofs;
  118. int runlen;
  119. uint32_t chksum;
  120. int i;
  121. /* check preconditions */
  122. if (ocl->buflen == 0 || ocl->bufalign == 0)
  123. return ERROR_FLASH_BANK_NOT_PROBED;
  124. if (bank->target->state != TARGET_RUNNING)
  125. {
  126. LOG_ERROR("target has to be running to communicate with the loader");
  127. return ERROR_TARGET_NOT_RUNNING;
  128. }
  129. /* allocate buffer for max. ocl buffer + overhead */
  130. dcc_buffer = malloc(sizeof(uint32_t)*(ocl->buflen/4 + 3));
  131. while (count)
  132. {
  133. if (count + (offset % ocl->bufalign) > ocl->buflen)
  134. runlen = ocl->buflen - (offset % ocl->bufalign);
  135. else
  136. runlen = count;
  137. dcc_buffer[0] = OCL_FLASH_BLOCK | runlen;
  138. dcc_buffer[1] = offset;
  139. dcc_bufptr = &dcc_buffer[2];
  140. *dcc_bufptr = 0xffffffff;
  141. byteofs = (offset % ocl->bufalign) % 4;
  142. chksum = OCL_CHKS_INIT;
  143. /* copy data to DCC buffer in proper byte order and properly aligned */
  144. for (i = 0; i < runlen; i++)
  145. {
  146. switch (byteofs++)
  147. {
  148. case 0:
  149. *dcc_bufptr &= *(buffer++) | 0xffffff00;
  150. break;
  151. case 1:
  152. *dcc_bufptr &= ((*(buffer++)) << 8) | 0xffff00ff;
  153. break;
  154. case 2:
  155. *dcc_bufptr &= ((*(buffer++)) << 16) | 0xff00ffff;
  156. break;
  157. case 3:
  158. *dcc_bufptr &= ((*(buffer++)) << 24) | 0x00ffffff;
  159. chksum ^= *(dcc_bufptr++);
  160. *dcc_bufptr = 0xffffffff;
  161. byteofs = 0;
  162. break;
  163. }
  164. }
  165. /* add the remaining word to checksum */
  166. if (byteofs)
  167. chksum ^= *(dcc_bufptr++);
  168. *(dcc_bufptr++) = chksum;
  169. /* send the data */
  170. if ((retval = embeddedice_send(ocl->jtag_info, dcc_buffer, dcc_bufptr-dcc_buffer)) != ERROR_OK)
  171. {
  172. free(dcc_buffer);
  173. return retval;
  174. }
  175. /* wait for response, fixed timeout of 1 s */
  176. if ((retval = embeddedice_handshake(ocl->jtag_info, EICE_COMM_CTRL_WBIT, 1000) != ERROR_OK))
  177. {
  178. if (retval == ERROR_TARGET_TIMEOUT)
  179. LOG_ERROR("loader not responding");
  180. free(dcc_buffer);
  181. return retval;
  182. }
  183. /* receive response */
  184. if ((retval = embeddedice_receive(ocl->jtag_info, dcc_buffer, 1) != ERROR_OK))
  185. {
  186. free(dcc_buffer);
  187. return retval;
  188. }
  189. if (dcc_buffer[0] != OCL_CMD_DONE)
  190. {
  191. LOG_ERROR("loader response to OCL_FLASH_BLOCK 0x%08" PRIx32 "", dcc_buffer[0]);
  192. free(dcc_buffer);
  193. return ERROR_FLASH_OPERATION_FAILED;
  194. }
  195. count -= runlen;
  196. offset += runlen;
  197. }
  198. free(dcc_buffer);
  199. return ERROR_OK;
  200. }
  201. static int ocl_probe(struct flash_bank *bank)
  202. {
  203. struct ocl_priv *ocl = bank->driver_priv;
  204. int retval;
  205. uint32_t dcc_buffer[1];
  206. int sectsize;
  207. int i;
  208. /* purge pending data in DCC */
  209. embeddedice_receive(ocl->jtag_info, dcc_buffer, 1);
  210. dcc_buffer[0] = OCL_PROBE;
  211. if ((retval = embeddedice_send(ocl->jtag_info, dcc_buffer, 1) != ERROR_OK))
  212. return retval;
  213. /* wait for response, fixed timeout of 1 s */
  214. if ((retval = embeddedice_handshake(ocl->jtag_info, EICE_COMM_CTRL_WBIT, 1000) != ERROR_OK))
  215. {
  216. if (retval == ERROR_TARGET_TIMEOUT)
  217. LOG_ERROR("loader not responding");
  218. return retval;
  219. }
  220. /* receive response */
  221. if ((retval = embeddedice_receive(ocl->jtag_info, dcc_buffer, 1) != ERROR_OK))
  222. return retval;
  223. if (dcc_buffer[0] != OCL_CMD_DONE)
  224. {
  225. LOG_ERROR("loader response to OCL_PROBE 0x%08" PRIx32 "", dcc_buffer[0]);
  226. return ERROR_FLASH_OPERATION_FAILED;
  227. }
  228. /* receive and fill in parameters, detection of loader is important, receive it one by one */
  229. if ((retval = embeddedice_handshake(ocl->jtag_info, EICE_COMM_CTRL_WBIT, 0) != ERROR_OK)
  230. || (retval = embeddedice_receive(ocl->jtag_info, dcc_buffer, 1) != ERROR_OK))
  231. return retval;
  232. bank->base = dcc_buffer[0];
  233. if ((retval = embeddedice_handshake(ocl->jtag_info, EICE_COMM_CTRL_WBIT, 0) != ERROR_OK)
  234. || (retval = embeddedice_receive(ocl->jtag_info, dcc_buffer, 1) != ERROR_OK))
  235. return retval;
  236. bank->size = dcc_buffer[0];
  237. if ((retval = embeddedice_handshake(ocl->jtag_info, EICE_COMM_CTRL_WBIT, 0) != ERROR_OK)
  238. || (retval = embeddedice_receive(ocl->jtag_info, dcc_buffer, 1) != ERROR_OK))
  239. return retval;
  240. bank->num_sectors = dcc_buffer[0];
  241. if ((retval = embeddedice_handshake(ocl->jtag_info, EICE_COMM_CTRL_WBIT, 0) != ERROR_OK)
  242. || (retval = embeddedice_receive(ocl->jtag_info, dcc_buffer, 1) != ERROR_OK))
  243. return retval;
  244. ocl->buflen = dcc_buffer[0] & 0xffff;
  245. ocl->bufalign = dcc_buffer[0] >> 16;
  246. bank->sectors = realloc(bank->sectors, sizeof(struct flash_sector)*bank->num_sectors);
  247. if (bank->num_sectors == 0)
  248. {
  249. LOG_ERROR("number of sectors shall be non zero value");
  250. return ERROR_FLASH_BANK_INVALID;
  251. }
  252. if (bank->size % bank->num_sectors) {
  253. LOG_ERROR("bank size not divisible by number of sectors");
  254. return ERROR_FLASH_BANK_INVALID;
  255. }
  256. sectsize = bank->size / bank->num_sectors;
  257. for (i = 0; i < bank->num_sectors; i++)
  258. {
  259. bank->sectors[i].offset = i * sectsize;
  260. bank->sectors[i].size = sectsize;
  261. bank->sectors[i].is_erased = -1;
  262. bank->sectors[i].is_protected = -1;
  263. }
  264. if (ocl->bufalign == 0)
  265. ocl->bufalign = 1;
  266. if (ocl->buflen == 0)
  267. {
  268. LOG_ERROR("buflen shall be non zero value");
  269. return ERROR_FLASH_BANK_INVALID;
  270. }
  271. if ((ocl->bufalign > ocl->buflen) || (ocl->buflen % ocl->bufalign))
  272. {
  273. LOG_ERROR("buflen is not multiple of bufalign");
  274. return ERROR_FLASH_BANK_INVALID;
  275. }
  276. if (ocl->buflen % 4)
  277. {
  278. LOG_ERROR("buflen shall be divisible by 4");
  279. return ERROR_FLASH_BANK_INVALID;
  280. }
  281. return ERROR_OK;
  282. }
  283. static int ocl_info(struct flash_bank *bank, char *buf, int buf_size)
  284. {
  285. return ERROR_OK;
  286. }
  287. static int ocl_auto_probe(struct flash_bank *bank)
  288. {
  289. struct ocl_priv *ocl = bank->driver_priv;
  290. if (ocl->buflen == 0 || ocl->bufalign == 0)
  291. return ERROR_FLASH_BANK_NOT_PROBED;
  292. return ERROR_OK;
  293. }
  294. struct flash_driver ocl_flash = {
  295. .name = "ocl",
  296. .flash_bank_command = &ocl_flash_bank_command,
  297. .erase = &ocl_erase,
  298. .protect = &ocl_protect,
  299. .write = &ocl_write,
  300. .probe = &ocl_probe,
  301. .erase_check = &ocl_erase_check,
  302. .protect_check = &ocl_protect_check,
  303. .info = &ocl_info,
  304. .auto_probe = &ocl_auto_probe,
  305. };