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.
 
 
 
 
 
 

636 lines
17 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2005 by Dominic Rath *
  3. * Dominic.Rath@gmx.de *
  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 "str9x.h"
  25. #include "flash.h"
  26. #include "target.h"
  27. #include "log.h"
  28. #include "armv4_5.h"
  29. #include "algorithm.h"
  30. #include "binarybuffer.h"
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include <unistd.h>
  34. str9x_mem_layout_t mem_layout_str9[] = {
  35. {0x00000000, 0x10000, 0x01},
  36. {0x00010000, 0x10000, 0x02},
  37. {0x00020000, 0x10000, 0x04},
  38. {0x00030000, 0x10000, 0x08},
  39. {0x00040000, 0x10000, 0x10},
  40. {0x00050000, 0x10000, 0x20},
  41. {0x00060000, 0x10000, 0x40},
  42. {0x00070000, 0x10000, 0x80},
  43. {0x00080000, 0x02000, 0x100},
  44. {0x00082000, 0x02000, 0x200},
  45. {0x00084000, 0x02000, 0x400},
  46. {0x00086000, 0x02000, 0x800}
  47. };
  48. int str9x_register_commands(struct command_context_s *cmd_ctx);
  49. int str9x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
  50. int str9x_erase(struct flash_bank_s *bank, int first, int last);
  51. int str9x_protect(struct flash_bank_s *bank, int set, int first, int last);
  52. int str9x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
  53. int str9x_probe(struct flash_bank_s *bank);
  54. int str9x_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
  55. int str9x_protect_check(struct flash_bank_s *bank);
  56. int str9x_erase_check(struct flash_bank_s *bank);
  57. int str9x_info(struct flash_bank_s *bank, char *buf, int buf_size);
  58. int str9x_handle_flash_config_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
  59. flash_driver_t str9x_flash =
  60. {
  61. .name = "str9x",
  62. .register_commands = str9x_register_commands,
  63. .flash_bank_command = str9x_flash_bank_command,
  64. .erase = str9x_erase,
  65. .protect = str9x_protect,
  66. .write = str9x_write,
  67. .probe = str9x_probe,
  68. .erase_check = str9x_erase_check,
  69. .protect_check = str9x_protect_check,
  70. .info = str9x_info
  71. };
  72. int str9x_register_commands(struct command_context_s *cmd_ctx)
  73. {
  74. command_t *str9x_cmd = register_command(cmd_ctx, NULL, "str9x", NULL, COMMAND_ANY, NULL);
  75. register_command(cmd_ctx, str9x_cmd, "flash_config", str9x_handle_flash_config_command, COMMAND_EXEC,
  76. "configure str9 flash controller");
  77. return ERROR_OK;
  78. }
  79. int str9x_build_block_list(struct flash_bank_s *bank)
  80. {
  81. str9x_flash_bank_t *str9x_info = bank->driver_priv;
  82. int i;
  83. int num_sectors = 0, b0_sectors = 0;
  84. switch (bank->size)
  85. {
  86. case 256 * 1024:
  87. b0_sectors = 4;
  88. break;
  89. case 512 * 1024:
  90. b0_sectors = 8;
  91. break;
  92. default:
  93. ERROR("BUG: unknown bank->size encountered");
  94. exit(-1);
  95. }
  96. num_sectors = b0_sectors + 4;
  97. bank->num_sectors = num_sectors;
  98. bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors);
  99. str9x_info->sector_bits = malloc(sizeof(u32) * num_sectors);
  100. num_sectors = 0;
  101. for (i = 0; i < b0_sectors; i++)
  102. {
  103. bank->sectors[num_sectors].offset = mem_layout_str9[i].sector_start;
  104. bank->sectors[num_sectors].size = mem_layout_str9[i].sector_size;
  105. bank->sectors[num_sectors].is_erased = -1;
  106. bank->sectors[num_sectors].is_protected = 1;
  107. str9x_info->sector_bits[num_sectors++] = mem_layout_str9[i].sector_bit;
  108. }
  109. for (i = 8; i < 12; i++)
  110. {
  111. bank->sectors[num_sectors].offset = mem_layout_str9[i].sector_start;
  112. bank->sectors[num_sectors].size = mem_layout_str9[i].sector_size;
  113. bank->sectors[num_sectors].is_erased = -1;
  114. bank->sectors[num_sectors].is_protected = 1;
  115. str9x_info->sector_bits[num_sectors++] = mem_layout_str9[i].sector_bit;
  116. }
  117. return ERROR_OK;
  118. }
  119. /* flash bank str9x <base> <size> 0 0 <target#>
  120. */
  121. int str9x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
  122. {
  123. str9x_flash_bank_t *str9x_info;
  124. if (argc < 6)
  125. {
  126. WARNING("incomplete flash_bank str9x configuration");
  127. return ERROR_FLASH_BANK_INVALID;
  128. }
  129. str9x_info = malloc(sizeof(str9x_flash_bank_t));
  130. bank->driver_priv = str9x_info;
  131. if (bank->base != 0x00000000)
  132. {
  133. WARNING("overriding flash base address for STR91x device with 0x00000000");
  134. bank->base = 0x00000000;
  135. }
  136. str9x_info->target = get_target_by_num(strtoul(args[5], NULL, 0));
  137. if (!str9x_info->target)
  138. {
  139. ERROR("no target '%s' configured", args[5]);
  140. exit(-1);
  141. }
  142. str9x_build_block_list(bank);
  143. str9x_info->write_algorithm = NULL;
  144. return ERROR_OK;
  145. }
  146. int str9x_blank_check(struct flash_bank_s *bank, int first, int last)
  147. {
  148. str9x_flash_bank_t *str9x_info = bank->driver_priv;
  149. target_t *target = str9x_info->target;
  150. u8 *buffer;
  151. int i;
  152. int nBytes;
  153. if ((first < 0) || (last > bank->num_sectors))
  154. return ERROR_FLASH_SECTOR_INVALID;
  155. if (str9x_info->target->state != TARGET_HALTED)
  156. {
  157. return ERROR_TARGET_NOT_HALTED;
  158. }
  159. buffer = malloc(256);
  160. for (i = first; i <= last; i++)
  161. {
  162. bank->sectors[i].is_erased = 1;
  163. target->type->read_memory(target, bank->base + bank->sectors[i].offset, 4, 256/4, buffer);
  164. for (nBytes = 0; nBytes < 256; nBytes++)
  165. {
  166. if (buffer[nBytes] != 0xFF)
  167. {
  168. bank->sectors[i].is_erased = 0;
  169. break;
  170. }
  171. }
  172. }
  173. free(buffer);
  174. return ERROR_OK;
  175. }
  176. int str9x_protect_check(struct flash_bank_s *bank)
  177. {
  178. str9x_flash_bank_t *str9x_info = bank->driver_priv;
  179. target_t *target = str9x_info->target;
  180. int i;
  181. u32 adr;
  182. u16 status;
  183. if (str9x_info->target->state != TARGET_HALTED)
  184. {
  185. return ERROR_TARGET_NOT_HALTED;
  186. }
  187. /* read level one protection */
  188. adr = mem_layout_str9[10].sector_start + 4;
  189. target_write_u32(target, adr, 0x90);
  190. target_read_u16(target, adr, &status);
  191. target_write_u32(target, adr, 0xFF);
  192. for (i = 0; i < bank->num_sectors; i++)
  193. {
  194. if (status & str9x_info->sector_bits[i])
  195. bank->sectors[i].is_protected = 1;
  196. else
  197. bank->sectors[i].is_protected = 0;
  198. }
  199. return ERROR_OK;
  200. }
  201. int str9x_erase(struct flash_bank_s *bank, int first, int last)
  202. {
  203. str9x_flash_bank_t *str9x_info = bank->driver_priv;
  204. target_t *target = str9x_info->target;
  205. int i;
  206. u32 adr;
  207. u8 status;
  208. if (str9x_info->target->state != TARGET_HALTED)
  209. {
  210. return ERROR_TARGET_NOT_HALTED;
  211. }
  212. for (i = first; i <= last; i++)
  213. {
  214. adr = bank->sectors[i].offset;
  215. /* erase sectors */
  216. target_write_u16(target, adr, 0x20);
  217. target_write_u16(target, adr, 0xD0);
  218. /* get status */
  219. target_write_u16(target, adr, 0x70);
  220. while (1) {
  221. target_read_u8(target, adr, &status);
  222. if( status & 0x80 )
  223. break;
  224. usleep(1000);
  225. }
  226. /* clear status, also clear read array */
  227. target_write_u16(target, adr, 0x50);
  228. /* read array command */
  229. target_write_u16(target, adr, 0xFF);
  230. if( status & 0x22 )
  231. {
  232. ERROR("error erasing flash bank, status: 0x%x", status);
  233. return ERROR_FLASH_OPERATION_FAILED;
  234. }
  235. }
  236. for (i = first; i <= last; i++)
  237. bank->sectors[i].is_erased = 1;
  238. return ERROR_OK;
  239. }
  240. int str9x_protect(struct flash_bank_s *bank, int set, int first, int last)
  241. {
  242. str9x_flash_bank_t *str9x_info = bank->driver_priv;
  243. target_t *target = str9x_info->target;
  244. int i;
  245. u32 adr;
  246. u8 status;
  247. if (str9x_info->target->state != TARGET_HALTED)
  248. {
  249. return ERROR_TARGET_NOT_HALTED;
  250. }
  251. for (i = first; i <= last; i++)
  252. {
  253. /* Level One Protection */
  254. adr = bank->sectors[i].offset;
  255. target_write_u16(target, adr, 0x60);
  256. if( set )
  257. target_write_u16(target, adr, 0x01);
  258. else
  259. target_write_u16(target, adr, 0xD0);
  260. /* query status */
  261. target_read_u8(target, adr, &status);
  262. }
  263. return ERROR_OK;
  264. }
  265. int str9x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
  266. {
  267. str9x_flash_bank_t *str9x_info = bank->driver_priv;
  268. target_t *target = str9x_info->target;
  269. u32 buffer_size = 8192;
  270. working_area_t *source;
  271. u32 address = bank->base + offset;
  272. reg_param_t reg_params[4];
  273. armv4_5_algorithm_t armv4_5_info;
  274. int retval;
  275. u32 str9x_flash_write_code[] = {
  276. /* write: */
  277. 0xe3c14003, /* bic r4, r1, #3 */
  278. 0xe3a03040, /* mov r3, #0x40 */
  279. 0xe1c430b0, /* strh r3, [r4, #0] */
  280. 0xe0d030b2, /* ldrh r3, [r0], #2 */
  281. 0xe0c130b2, /* strh r3, [r1], #2 */
  282. 0xe3a03070, /* mov r3, #0x70 */
  283. 0xe1c430b0, /* strh r3, [r4, #0] */
  284. /* busy: */
  285. 0xe5d43000, /* ldrb r3, [r4, #0] */
  286. 0xe3130080, /* tst r3, #0x80 */
  287. 0x0afffffc, /* beq busy */
  288. 0xe3a05050, /* mov r5, #0x50 */
  289. 0xe1c450b0, /* strh r5, [r4, #0] */
  290. 0xe3a050ff, /* mov r5, #0xFF */
  291. 0xe1c450b0, /* strh r5, [r4, #0] */
  292. 0xe3130012, /* tst r3, #0x12 */
  293. 0x1a000001, /* bne exit */
  294. 0xe2522001, /* subs r2, r2, #1 */
  295. 0x1affffed, /* bne write */
  296. /* exit: */
  297. 0xeafffffe, /* b exit */
  298. };
  299. u8 str9x_flash_write_code_buf[76];
  300. int i;
  301. /* flash write code */
  302. if (!str9x_info->write_algorithm)
  303. {
  304. if (target_alloc_working_area(target, 4 * 19, &str9x_info->write_algorithm) != ERROR_OK)
  305. {
  306. WARNING("no working area available, can't do block memory writes");
  307. return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
  308. };
  309. /* convert flash writing code into a buffer in target endianness */
  310. for (i = 0; i < 19; i++)
  311. target_buffer_set_u32(target, str9x_flash_write_code_buf + i*4, str9x_flash_write_code[i]);
  312. target_write_buffer(target, str9x_info->write_algorithm->address, 19 * 4, str9x_flash_write_code_buf);
  313. }
  314. /* memory buffer */
  315. while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
  316. {
  317. buffer_size /= 2;
  318. if (buffer_size <= 256)
  319. {
  320. /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
  321. if (str9x_info->write_algorithm)
  322. target_free_working_area(target, str9x_info->write_algorithm);
  323. WARNING("no large enough working area available, can't do block memory writes");
  324. return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
  325. }
  326. };
  327. armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
  328. armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
  329. armv4_5_info.core_state = ARMV4_5_STATE_ARM;
  330. init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
  331. init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
  332. init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
  333. init_reg_param(&reg_params[3], "r3", 32, PARAM_IN);
  334. while (count > 0)
  335. {
  336. u32 thisrun_count = (count > (buffer_size / 2)) ? (buffer_size / 2) : count;
  337. target_write_buffer(target, source->address, thisrun_count * 2, buffer);
  338. buf_set_u32(reg_params[0].value, 0, 32, source->address);
  339. buf_set_u32(reg_params[1].value, 0, 32, address);
  340. buf_set_u32(reg_params[2].value, 0, 32, thisrun_count);
  341. if ((retval = target->type->run_algorithm(target, 0, NULL, 4, reg_params, str9x_info->write_algorithm->address, str9x_info->write_algorithm->address + (18 * 4), 10000, &armv4_5_info)) != ERROR_OK)
  342. {
  343. ERROR("error executing str9x flash write algorithm");
  344. return ERROR_FLASH_OPERATION_FAILED;
  345. }
  346. if (buf_get_u32(reg_params[3].value, 0, 32) != 0x80)
  347. {
  348. return ERROR_FLASH_OPERATION_FAILED;
  349. }
  350. buffer += thisrun_count * 2;
  351. address += thisrun_count * 2;
  352. count -= thisrun_count;
  353. }
  354. destroy_reg_param(&reg_params[0]);
  355. destroy_reg_param(&reg_params[1]);
  356. destroy_reg_param(&reg_params[2]);
  357. destroy_reg_param(&reg_params[3]);
  358. return ERROR_OK;
  359. }
  360. int str9x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
  361. {
  362. str9x_flash_bank_t *str9x_info = bank->driver_priv;
  363. target_t *target = str9x_info->target;
  364. u32 words_remaining = (count / 2);
  365. u32 bytes_remaining = (count & 0x00000001);
  366. u32 address = bank->base + offset;
  367. u32 bytes_written = 0;
  368. u8 status;
  369. u32 retval;
  370. u32 check_address = offset;
  371. u32 bank_adr;
  372. int i;
  373. if (str9x_info->target->state != TARGET_HALTED)
  374. {
  375. return ERROR_TARGET_NOT_HALTED;
  376. }
  377. if (offset & 0x1)
  378. {
  379. WARNING("offset 0x%x breaks required 2-byte alignment", offset);
  380. return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
  381. }
  382. for (i = 0; i < bank->num_sectors; i++)
  383. {
  384. u32 sec_start = bank->sectors[i].offset;
  385. u32 sec_end = sec_start + bank->sectors[i].size;
  386. /* check if destination falls within the current sector */
  387. if ((check_address >= sec_start) && (check_address < sec_end))
  388. {
  389. /* check if destination ends in the current sector */
  390. if (offset + count < sec_end)
  391. check_address = offset + count;
  392. else
  393. check_address = sec_end;
  394. }
  395. }
  396. if (check_address != offset + count)
  397. return ERROR_FLASH_DST_OUT_OF_BANK;
  398. /* multiple half words (2-byte) to be programmed? */
  399. if (words_remaining > 0)
  400. {
  401. /* try using a block write */
  402. if ((retval = str9x_write_block(bank, buffer, offset, words_remaining)) != ERROR_OK)
  403. {
  404. if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
  405. {
  406. /* if block write failed (no sufficient working area),
  407. * we use normal (slow) single dword accesses */
  408. WARNING("couldn't use block writes, falling back to single memory accesses");
  409. }
  410. else if (retval == ERROR_FLASH_OPERATION_FAILED)
  411. {
  412. ERROR("flash writing failed with error code: 0x%x", retval);
  413. return ERROR_FLASH_OPERATION_FAILED;
  414. }
  415. }
  416. else
  417. {
  418. buffer += words_remaining * 2;
  419. address += words_remaining * 2;
  420. words_remaining = 0;
  421. }
  422. }
  423. while (words_remaining > 0)
  424. {
  425. bank_adr = address & ~0x03;
  426. /* write data command */
  427. target_write_u16(target, bank_adr, 0x40);
  428. target->type->write_memory(target, address, 2, 1, buffer + bytes_written);
  429. /* get status command */
  430. target_write_u16(target, bank_adr, 0x70);
  431. while (1) {
  432. target_read_u8(target, bank_adr, &status);
  433. if( status & 0x80 )
  434. break;
  435. usleep(1000);
  436. }
  437. /* clear status reg and read array */
  438. target_write_u16(target, bank_adr, 0x50);
  439. target_write_u16(target, bank_adr, 0xFF);
  440. if (status & 0x10)
  441. return ERROR_FLASH_OPERATION_FAILED;
  442. else if (status & 0x02)
  443. return ERROR_FLASH_OPERATION_FAILED;
  444. bytes_written += 2;
  445. words_remaining--;
  446. address += 2;
  447. }
  448. if (bytes_remaining)
  449. {
  450. u8 last_halfword[2] = {0xff, 0xff};
  451. int i = 0;
  452. while(bytes_remaining > 0)
  453. {
  454. last_halfword[i++] = *(buffer + bytes_written);
  455. bytes_remaining--;
  456. bytes_written++;
  457. }
  458. bank_adr = address & ~0x03;
  459. /* write data comamnd */
  460. target_write_u16(target, bank_adr, 0x40);
  461. target->type->write_memory(target, address, 2, 1, last_halfword);
  462. /* query status command */
  463. target_write_u16(target, bank_adr, 0x70);
  464. while (1) {
  465. target_read_u8(target, bank_adr, &status);
  466. if( status & 0x80 )
  467. break;
  468. usleep(1000);
  469. }
  470. /* clear status reg and read array */
  471. target_write_u16(target, bank_adr, 0x50);
  472. target_write_u16(target, bank_adr, 0xFF);
  473. if (status & 0x10)
  474. return ERROR_FLASH_OPERATION_FAILED;
  475. else if (status & 0x02)
  476. return ERROR_FLASH_OPERATION_FAILED;
  477. }
  478. return ERROR_OK;
  479. }
  480. int str9x_probe(struct flash_bank_s *bank)
  481. {
  482. return ERROR_OK;
  483. }
  484. int str9x_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  485. {
  486. return ERROR_OK;
  487. }
  488. int str9x_erase_check(struct flash_bank_s *bank)
  489. {
  490. return str9x_blank_check(bank, 0, bank->num_sectors - 1);
  491. }
  492. int str9x_info(struct flash_bank_s *bank, char *buf, int buf_size)
  493. {
  494. snprintf(buf, buf_size, "str9x flash driver info" );
  495. return ERROR_OK;
  496. }
  497. int str9x_handle_flash_config_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  498. {
  499. str9x_flash_bank_t *str9x_info;
  500. flash_bank_t *bank;
  501. target_t *target = NULL;
  502. if (argc < 4)
  503. {
  504. command_print(cmd_ctx, "usage: str9x flash_config b0size b1size b0start b1start");
  505. return ERROR_OK;
  506. }
  507. bank = get_flash_bank_by_num(0);
  508. str9x_info = bank->driver_priv;
  509. target = str9x_info->target;
  510. if (str9x_info->target->state != TARGET_HALTED)
  511. {
  512. return ERROR_TARGET_NOT_HALTED;
  513. }
  514. /* config flash controller */
  515. target_write_u32(target, FLASH_BBSR, strtoul(args[0], NULL, 0));
  516. target_write_u32(target, FLASH_NBBSR, strtoul(args[1], NULL, 0));
  517. target_write_u32(target, FLASH_BBADR, (strtoul(args[2], NULL, 0) >> 2));
  518. target_write_u32(target, FLASH_NBBADR, (strtoul(args[3], NULL, 0) >> 2));
  519. /* enable flash bank 1 */
  520. target_write_u32(target, FLASH_CR, 0x18);
  521. return ERROR_OK;
  522. }