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.
 
 
 
 
 
 

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