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.
 
 
 
 
 
 

482 lines
14 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2008 Øyvind Harboe *
  3. * oyvind.harboe@zylin.com *
  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 "replacements.h"
  24. #include "flash.h"
  25. #include "target.h"
  26. #include "flash.h"
  27. #include "target.h"
  28. #include "log.h"
  29. #include "binarybuffer.h"
  30. #include "../target/embeddedice.h"
  31. #include "types.h"
  32. int ecosflash_register_commands(struct command_context_s *cmd_ctx);
  33. int ecosflash_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
  34. int ecosflash_erase(struct flash_bank_s *bank, int first, int last);
  35. int ecosflash_protect(struct flash_bank_s *bank, int set, int first, int last);
  36. int ecosflash_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
  37. int ecosflash_probe(struct flash_bank_s *bank);
  38. int ecosflash_erase_check(struct flash_bank_s *bank);
  39. int ecosflash_protect_check(struct flash_bank_s *bank);
  40. int ecosflash_info(struct flash_bank_s *bank, char *buf, int buf_size);
  41. u32 ecosflash_get_flash_status(flash_bank_t *bank);
  42. void ecosflash_set_flash_mode(flash_bank_t *bank,int mode);
  43. u32 ecosflash_wait_status_busy(flash_bank_t *bank, u32 waitbits, int timeout);
  44. int ecosflash_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
  45. flash_driver_t ecosflash_flash =
  46. {
  47. .name = "ecosflash",
  48. .register_commands = ecosflash_register_commands,
  49. .flash_bank_command = ecosflash_flash_bank_command,
  50. .erase = ecosflash_erase,
  51. .protect = ecosflash_protect,
  52. .write = ecosflash_write,
  53. .probe = ecosflash_probe,
  54. .auto_probe = ecosflash_probe,
  55. .erase_check = ecosflash_erase_check,
  56. .protect_check = ecosflash_protect_check,
  57. .info = ecosflash_info
  58. };
  59. typedef struct ecosflash_flash_bank_s
  60. {
  61. struct target_s *target;
  62. working_area_t *write_algorithm;
  63. working_area_t *erase_check_algorithm;
  64. char *driverPath;
  65. u32 start_address;
  66. } ecosflash_flash_bank_t;
  67. static const int sectorSize=0x10000;
  68. #define FLASH_ERR_OK 0x00 // No error - operation complete
  69. #define FLASH_ERR_INVALID 0x01 // Invalid FLASH address
  70. #define FLASH_ERR_ERASE 0x02 // Error trying to erase
  71. #define FLASH_ERR_LOCK 0x03 // Error trying to lock/unlock
  72. #define FLASH_ERR_PROGRAM 0x04 // Error trying to program
  73. #define FLASH_ERR_PROTOCOL 0x05 // Generic error
  74. #define FLASH_ERR_PROTECT 0x06 // Device/region is write-protected
  75. #define FLASH_ERR_NOT_INIT 0x07 // FLASH info not yet initialized
  76. #define FLASH_ERR_HWR 0x08 // Hardware (configuration?) problem
  77. #define FLASH_ERR_ERASE_SUSPEND 0x09 // Device is in erase suspend mode
  78. #define FLASH_ERR_PROGRAM_SUSPEND 0x0a // Device is in in program suspend mode
  79. #define FLASH_ERR_DRV_VERIFY 0x0b // Driver failed to verify data
  80. #define FLASH_ERR_DRV_TIMEOUT 0x0c // Driver timed out waiting for device
  81. #define FLASH_ERR_DRV_WRONG_PART 0x0d // Driver does not support device
  82. #define FLASH_ERR_LOW_VOLTAGE 0x0e // Not enough juice to complete job
  83. char *
  84. flash_errmsg(int err)
  85. {
  86. switch (err) {
  87. case FLASH_ERR_OK:
  88. return "No error - operation complete";
  89. case FLASH_ERR_ERASE_SUSPEND:
  90. return "Device is in erase suspend state";
  91. case FLASH_ERR_PROGRAM_SUSPEND:
  92. return "Device is in program suspend state";
  93. case FLASH_ERR_INVALID:
  94. return "Invalid FLASH address";
  95. case FLASH_ERR_ERASE:
  96. return "Error trying to erase";
  97. case FLASH_ERR_LOCK:
  98. return "Error trying to lock/unlock";
  99. case FLASH_ERR_PROGRAM:
  100. return "Error trying to program";
  101. case FLASH_ERR_PROTOCOL:
  102. return "Generic error";
  103. case FLASH_ERR_PROTECT:
  104. return "Device/region is write-protected";
  105. case FLASH_ERR_NOT_INIT:
  106. return "FLASH sub-system not initialized";
  107. case FLASH_ERR_DRV_VERIFY:
  108. return "Data verify failed after operation";
  109. case FLASH_ERR_DRV_TIMEOUT:
  110. return "Driver timed out waiting for device";
  111. case FLASH_ERR_DRV_WRONG_PART:
  112. return "Driver does not support device";
  113. case FLASH_ERR_LOW_VOLTAGE:
  114. return "Device reports low voltage";
  115. default:
  116. return "Unknown error";
  117. }
  118. }
  119. /* flash bank ecosflash <base> <size> <chip_width> <bus_width> <target#> <driverPath>
  120. */
  121. int ecosflash_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
  122. {
  123. ecosflash_flash_bank_t *info;
  124. if (argc < 7)
  125. {
  126. WARNING("incomplete flash_bank ecosflash configuration");
  127. return ERROR_FLASH_BANK_INVALID;
  128. }
  129. info = malloc(sizeof(ecosflash_flash_bank_t));
  130. if(info == NULL)
  131. {
  132. ERROR("no memory for flash bank info");
  133. exit(-1);
  134. }
  135. bank->driver_priv = info;
  136. info->driverPath=strdup(args[6]);
  137. // eCos flash sector sizes are not exposed to OpenOCD, use 0x10000 as
  138. // a way to improve impeadance matach between OpenOCD and eCos flash
  139. // driver
  140. int i = 0;
  141. u32 offset = 0;
  142. bank->num_sectors=bank->size/sectorSize;
  143. bank->sectors = malloc(sizeof(flash_sector_t) * bank->num_sectors);
  144. for (i = 0; i < bank->num_sectors; i++)
  145. {
  146. bank->sectors[i].offset = offset;
  147. bank->sectors[i].size = sectorSize;
  148. offset += bank->sectors[i].size;
  149. bank->sectors[i].is_erased = -1;
  150. bank->sectors[i].is_protected = 0;
  151. }
  152. info->target = get_target_by_num(strtoul(args[5], NULL, 0));
  153. if (info->target == NULL)
  154. {
  155. ERROR("no target '%i' configured", (int)strtoul(args[5], NULL, 0));
  156. exit(-1);
  157. }
  158. return ERROR_OK;
  159. }
  160. int loadDriver(ecosflash_flash_bank_t *info)
  161. {
  162. u32 buf_cnt;
  163. u32 image_size;
  164. image_t image;
  165. image.base_address_set = 0;
  166. image.start_address_set = 0;
  167. target_t *target=info->target;
  168. if (image_open(&image, info->driverPath, NULL) != ERROR_OK)
  169. {
  170. ERROR("load_image error: %s", image.error_str);
  171. return ERROR_FLASH_BANK_INVALID;
  172. }
  173. info->start_address=image.start_address;
  174. image_size = 0x0;
  175. int i;
  176. for (i = 0; i < image.num_sections; i++)
  177. {
  178. void *buffer = malloc(image.sections[i].size);
  179. int retval;
  180. if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
  181. {
  182. ERROR("image_read_section failed with error code: %i", retval);
  183. free(buffer);
  184. image_close(&image);
  185. return ERROR_FLASH_BANK_INVALID;
  186. }
  187. target_write_buffer(target, image.sections[i].base_address, buf_cnt, buffer);
  188. image_size += buf_cnt;
  189. DEBUG("%u byte written at address 0x%8.8x", buf_cnt, image.sections[i].base_address);
  190. free(buffer);
  191. }
  192. image_close(&image);
  193. return ERROR_OK;
  194. }
  195. static int const OFFSET_ERASE=0x0;
  196. static int const OFFSET_ERASE_SIZE=0x8;
  197. static int const OFFSET_FLASH=0xc;
  198. static int const OFFSET_FLASH_SIZE=0x8;
  199. static int const OFFSET_GET_WORKAREA=0x18;
  200. static int const OFFSET_GET_WORKAREA_SIZE=0x4;
  201. int runCode(ecosflash_flash_bank_t *info,
  202. u32 codeStart, u32 codeStop, u32 r0, u32 r1, u32 r2,
  203. u32 *result,
  204. // timeout in ms
  205. int timeout)
  206. {
  207. target_t *target=info->target;
  208. reg_param_t reg_params[3];
  209. armv4_5_algorithm_t armv4_5_info;
  210. armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
  211. armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
  212. armv4_5_info.core_state = ARMV4_5_STATE_ARM;
  213. init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);
  214. init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
  215. init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
  216. buf_set_u32(reg_params[0].value, 0, 32, r0);
  217. buf_set_u32(reg_params[1].value, 0, 32, r1);
  218. buf_set_u32(reg_params[2].value, 0, 32, r2);
  219. int retval;
  220. if ((retval = target->type->run_algorithm(target, 0, NULL, 3, reg_params,
  221. codeStart,
  222. codeStop, timeout,
  223. &armv4_5_info)) != ERROR_OK)
  224. {
  225. ERROR("error executing eCos flash algorithm");
  226. return retval;
  227. }
  228. *result=buf_get_u32(reg_params[0].value, 0, 32);
  229. destroy_reg_param(&reg_params[0]);
  230. destroy_reg_param(&reg_params[1]);
  231. destroy_reg_param(&reg_params[2]);
  232. return ERROR_OK;
  233. }
  234. int eCosBoard_erase(ecosflash_flash_bank_t *info, u32 address, u32 len)
  235. {
  236. int retval;
  237. int timeout = (len / 20480 + 1) * 1000; /*asume 20 KB/s*/
  238. retval=loadDriver(info);
  239. if (retval!=ERROR_OK)
  240. return retval;
  241. u32 flashErr;
  242. retval=runCode(info,
  243. info->start_address+OFFSET_ERASE,
  244. info->start_address+OFFSET_ERASE+OFFSET_ERASE_SIZE,
  245. address,
  246. len,
  247. 0,
  248. &flashErr,
  249. timeout
  250. );
  251. if (retval!=ERROR_OK)
  252. return retval;
  253. if (flashErr != 0x0)
  254. {
  255. ERROR("Flash erase failed with %d (%s)\n", flashErr, flash_errmsg(flashErr));
  256. return ERROR_JTAG_DEVICE_ERROR;
  257. }
  258. return ERROR_OK;
  259. }
  260. int eCosBoard_flash(ecosflash_flash_bank_t *info, void *data, u32 address, u32 len)
  261. {
  262. target_t *target=info->target;
  263. const int chunk=8192;
  264. int retval=ERROR_OK;
  265. int timeout = (chunk / 20480 + 1) * 1000; /*asume 20 KB/s + 1 second*/
  266. retval=loadDriver(info);
  267. if (retval!=ERROR_OK)
  268. return retval;
  269. u32 buffer;
  270. retval=runCode(info,
  271. info->start_address+OFFSET_GET_WORKAREA,
  272. info->start_address+OFFSET_GET_WORKAREA+OFFSET_GET_WORKAREA_SIZE,
  273. 0,
  274. 0,
  275. 0,
  276. &buffer,
  277. 1000);
  278. if (retval!=ERROR_OK)
  279. return retval;
  280. int i;
  281. for (i=0; i<len; i+=chunk)
  282. {
  283. int t=len-i;
  284. if (t>chunk)
  285. {
  286. t=chunk;
  287. }
  288. int retval;
  289. retval=target_write_buffer(target, buffer, t, ((char *)data)+i);
  290. if (retval != ERROR_OK)
  291. return retval;
  292. u32 flashErr;
  293. retval=runCode(info,
  294. info->start_address+OFFSET_FLASH,
  295. info->start_address+OFFSET_FLASH+OFFSET_FLASH_SIZE,
  296. buffer,
  297. address+i,
  298. t,
  299. &flashErr,
  300. timeout);
  301. if (retval != ERROR_OK)
  302. return retval;
  303. if (flashErr != 0x0)
  304. {
  305. ERROR("Flash prog failed with %d (%s)\n", flashErr, flash_errmsg(flashErr));
  306. return ERROR_JTAG_DEVICE_ERROR;
  307. }
  308. }
  309. return ERROR_OK;
  310. }
  311. int ecosflash_probe(struct flash_bank_s *bank)
  312. {
  313. return ERROR_OK;
  314. }
  315. int ecosflash_register_commands(struct command_context_s *cmd_ctx)
  316. {
  317. register_command(cmd_ctx, NULL, "ecosflash", NULL, COMMAND_ANY, NULL);
  318. return ERROR_OK;
  319. }
  320. /*
  321. static void command(flash_bank_t *bank, u8 cmd, u8 *cmd_buf)
  322. {
  323. ecosflash_flash_bank_t *info = bank->driver_priv;
  324. int i;
  325. if (info->target->endianness == TARGET_LITTLE_ENDIAN)
  326. {
  327. for (i = bank->bus_width; i > 0; i--)
  328. {
  329. *cmd_buf++ = (i & (bank->chip_width - 1)) ? 0x0 : cmd;
  330. }
  331. }
  332. else
  333. {
  334. for (i = 1; i <= bank->bus_width; i++)
  335. {
  336. *cmd_buf++ = (i & (bank->chip_width - 1)) ? 0x0 : cmd;
  337. }
  338. }
  339. }
  340. */
  341. u32 ecosflash_address(struct flash_bank_s *bank, u32 address)
  342. {
  343. u32 retval = 0;
  344. switch(bank->bus_width)
  345. {
  346. case 4:
  347. retval = address & 0xfffffffc;
  348. case 2:
  349. retval = address & 0xfffffffe;
  350. case 1:
  351. retval = address;
  352. }
  353. return retval + bank->base;
  354. }
  355. int ecosflash_erase(struct flash_bank_s *bank, int first, int last)
  356. {
  357. struct flash_bank_s *c=bank;
  358. ecosflash_flash_bank_t *info = bank->driver_priv;
  359. return eCosBoard_erase(info, c->base+first*sectorSize, sectorSize*(last-first+1));
  360. }
  361. int ecosflash_protect(struct flash_bank_s *bank, int set, int first, int last)
  362. {
  363. return ERROR_OK;
  364. }
  365. int ecosflash_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
  366. {
  367. ecosflash_flash_bank_t *info = bank->driver_priv;
  368. struct flash_bank_s *c=bank;
  369. return eCosBoard_flash(info, buffer, c->base+offset, count);
  370. }
  371. int ecosflash_erase_check(struct flash_bank_s *bank)
  372. {
  373. return ERROR_OK;
  374. }
  375. int ecosflash_protect_check(struct flash_bank_s *bank)
  376. {
  377. return ERROR_OK;
  378. }
  379. int ecosflash_info(struct flash_bank_s *bank, char *buf, int buf_size)
  380. {
  381. ecosflash_flash_bank_t *info = bank->driver_priv;
  382. snprintf(buf, buf_size, "eCos flash driver: %s", info->driverPath);
  383. return ERROR_OK;
  384. }
  385. u32 ecosflash_get_flash_status(flash_bank_t *bank)
  386. {
  387. return ERROR_OK;
  388. }
  389. void ecosflash_set_flash_mode(flash_bank_t *bank,int mode)
  390. {
  391. }
  392. u32 ecosflash_wait_status_busy(flash_bank_t *bank, u32 waitbits, int timeout)
  393. {
  394. return ERROR_OK;
  395. }
  396. int ecosflash_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  397. {
  398. return ERROR_OK;
  399. }