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.
 
 
 
 
 
 

713 lines
20 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2005 by Dominic Rath *
  3. * Dominic.Rath@gmx.de *
  4. * *
  5. * Copyright (C) 2008 by Spencer Oliver *
  6. * spen@spen-soft.co.uk *
  7. * *
  8. * This program is free software; you can redistribute it and/or modify *
  9. * it under the terms of the GNU General Public License as published by *
  10. * the Free Software Foundation; either version 2 of the License, or *
  11. * (at your option) any later version. *
  12. * *
  13. * This program is distributed in the hope that it will be useful, *
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  16. * GNU General Public License for more details. *
  17. * *
  18. * You should have received a copy of the GNU General Public License *
  19. * along with this program; if not, write to the *
  20. * Free Software Foundation, Inc., *
  21. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  22. ***************************************************************************/
  23. #ifdef HAVE_CONFIG_H
  24. #include "config.h"
  25. #endif
  26. #include "str7x.h"
  27. #include "armv4_5.h"
  28. #include "binarybuffer.h"
  29. str7x_mem_layout_t mem_layout_str7bank0[] = {
  30. {0x00000000, 0x02000, 0x01},
  31. {0x00002000, 0x02000, 0x02},
  32. {0x00004000, 0x02000, 0x04},
  33. {0x00006000, 0x02000, 0x08},
  34. {0x00008000, 0x08000, 0x10},
  35. {0x00010000, 0x10000, 0x20},
  36. {0x00020000, 0x10000, 0x40},
  37. {0x00030000, 0x10000, 0x80}
  38. };
  39. str7x_mem_layout_t mem_layout_str7bank1[] = {
  40. {0x00000000, 0x02000, 0x10000},
  41. {0x00002000, 0x02000, 0x20000}
  42. };
  43. static int str7x_register_commands(struct command_context_s *cmd_ctx);
  44. static int str7x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
  45. static int str7x_erase(struct flash_bank_s *bank, int first, int last);
  46. static int str7x_protect(struct flash_bank_s *bank, int set, int first, int last);
  47. static int str7x_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count);
  48. static int str7x_probe(struct flash_bank_s *bank);
  49. //static int str7x_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
  50. static int str7x_protect_check(struct flash_bank_s *bank);
  51. static int str7x_info(struct flash_bank_s *bank, char *buf, int buf_size);
  52. static int str7x_handle_disable_jtag_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
  53. flash_driver_t str7x_flash =
  54. {
  55. .name = "str7x",
  56. .register_commands = str7x_register_commands,
  57. .flash_bank_command = str7x_flash_bank_command,
  58. .erase = str7x_erase,
  59. .protect = str7x_protect,
  60. .write = str7x_write,
  61. .probe = str7x_probe,
  62. .auto_probe = str7x_probe,
  63. .erase_check = default_flash_blank_check,
  64. .protect_check = str7x_protect_check,
  65. .info = str7x_info
  66. };
  67. static int str7x_register_commands(struct command_context_s *cmd_ctx)
  68. {
  69. command_t *str7x_cmd = register_command(cmd_ctx, NULL, "str7x", NULL, COMMAND_ANY, NULL);
  70. register_command(cmd_ctx, str7x_cmd, "disable_jtag", str7x_handle_disable_jtag_command, COMMAND_EXEC,
  71. "disable jtag access");
  72. return ERROR_OK;
  73. }
  74. static int str7x_get_flash_adr(struct flash_bank_s *bank, uint32_t reg)
  75. {
  76. str7x_flash_bank_t *str7x_info = bank->driver_priv;
  77. return (str7x_info->register_base | reg);
  78. }
  79. static int str7x_build_block_list(struct flash_bank_s *bank)
  80. {
  81. str7x_flash_bank_t *str7x_info = bank->driver_priv;
  82. int i;
  83. int num_sectors;
  84. int b0_sectors = 0, b1_sectors = 0;
  85. switch (bank->size)
  86. {
  87. case 16 * 1024:
  88. b1_sectors = 2;
  89. break;
  90. case 64 * 1024:
  91. b0_sectors = 5;
  92. break;
  93. case 128 * 1024:
  94. b0_sectors = 6;
  95. break;
  96. case 256 * 1024:
  97. b0_sectors = 8;
  98. break;
  99. default:
  100. LOG_ERROR("BUG: unknown bank->size encountered");
  101. exit(-1);
  102. }
  103. num_sectors = b0_sectors + b1_sectors;
  104. bank->num_sectors = num_sectors;
  105. bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors);
  106. str7x_info->sector_bits = malloc(sizeof(uint32_t) * num_sectors);
  107. num_sectors = 0;
  108. for (i = 0; i < b0_sectors; i++)
  109. {
  110. bank->sectors[num_sectors].offset = mem_layout_str7bank0[i].sector_start;
  111. bank->sectors[num_sectors].size = mem_layout_str7bank0[i].sector_size;
  112. bank->sectors[num_sectors].is_erased = -1;
  113. bank->sectors[num_sectors].is_protected = 1;
  114. str7x_info->sector_bits[num_sectors++] = mem_layout_str7bank0[i].sector_bit;
  115. }
  116. for (i = 0; i < b1_sectors; i++)
  117. {
  118. bank->sectors[num_sectors].offset = mem_layout_str7bank1[i].sector_start;
  119. bank->sectors[num_sectors].size = mem_layout_str7bank1[i].sector_size;
  120. bank->sectors[num_sectors].is_erased = -1;
  121. bank->sectors[num_sectors].is_protected = 1;
  122. str7x_info->sector_bits[num_sectors++] = mem_layout_str7bank1[i].sector_bit;
  123. }
  124. return ERROR_OK;
  125. }
  126. /* flash bank str7x <base> <size> 0 0 <target#> <str71_variant>
  127. */
  128. static int str7x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
  129. {
  130. str7x_flash_bank_t *str7x_info;
  131. if (argc < 7)
  132. {
  133. LOG_WARNING("incomplete flash_bank str7x configuration");
  134. return ERROR_FLASH_BANK_INVALID;
  135. }
  136. str7x_info = malloc(sizeof(str7x_flash_bank_t));
  137. bank->driver_priv = str7x_info;
  138. /* set default bits for str71x flash */
  139. str7x_info->busy_bits = (FLASH_LOCK | FLASH_BSYA1 | FLASH_BSYA0);
  140. str7x_info->disable_bit = (1 << 1);
  141. if (strcmp(args[6], "STR71x") == 0)
  142. {
  143. str7x_info->register_base = 0x40100000;
  144. }
  145. else if (strcmp(args[6], "STR73x") == 0)
  146. {
  147. str7x_info->register_base = 0x80100000;
  148. str7x_info->busy_bits = (FLASH_LOCK | FLASH_BSYA0);
  149. }
  150. else if (strcmp(args[6], "STR75x") == 0)
  151. {
  152. str7x_info->register_base = 0x20100000;
  153. str7x_info->disable_bit = (1 << 0);
  154. }
  155. else
  156. {
  157. LOG_ERROR("unknown STR7x variant: '%s'", args[6]);
  158. free(str7x_info);
  159. return ERROR_FLASH_BANK_INVALID;
  160. }
  161. str7x_build_block_list(bank);
  162. str7x_info->write_algorithm = NULL;
  163. return ERROR_OK;
  164. }
  165. static uint32_t str7x_status(struct flash_bank_s *bank)
  166. {
  167. target_t *target = bank->target;
  168. uint32_t retval;
  169. target_read_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), &retval);
  170. return retval;
  171. }
  172. static uint32_t str7x_result(struct flash_bank_s *bank)
  173. {
  174. target_t *target = bank->target;
  175. uint32_t retval;
  176. target_read_u32(target, str7x_get_flash_adr(bank, FLASH_ER), &retval);
  177. return retval;
  178. }
  179. static int str7x_protect_check(struct flash_bank_s *bank)
  180. {
  181. str7x_flash_bank_t *str7x_info = bank->driver_priv;
  182. target_t *target = bank->target;
  183. int i;
  184. uint32_t retval;
  185. if (bank->target->state != TARGET_HALTED)
  186. {
  187. LOG_ERROR("Target not halted");
  188. return ERROR_TARGET_NOT_HALTED;
  189. }
  190. target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVWPAR), &retval);
  191. for (i = 0; i < bank->num_sectors; i++)
  192. {
  193. if (retval & str7x_info->sector_bits[i])
  194. bank->sectors[i].is_protected = 0;
  195. else
  196. bank->sectors[i].is_protected = 1;
  197. }
  198. return ERROR_OK;
  199. }
  200. static int str7x_erase(struct flash_bank_s *bank, int first, int last)
  201. {
  202. str7x_flash_bank_t *str7x_info = bank->driver_priv;
  203. target_t *target = bank->target;
  204. int i;
  205. uint32_t cmd;
  206. uint32_t retval;
  207. uint32_t sectors = 0;
  208. if (bank->target->state != TARGET_HALTED)
  209. {
  210. LOG_ERROR("Target not halted");
  211. return ERROR_TARGET_NOT_HALTED;
  212. }
  213. for (i = first; i <= last; i++)
  214. {
  215. sectors |= str7x_info->sector_bits[i];
  216. }
  217. LOG_DEBUG("sectors: 0x%" PRIx32 "", sectors);
  218. /* clear FLASH_ER register */
  219. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
  220. cmd = FLASH_SER;
  221. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
  222. cmd = sectors;
  223. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR1), cmd);
  224. cmd = FLASH_SER | FLASH_WMS;
  225. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
  226. while (((retval = str7x_status(bank)) & str7x_info->busy_bits)) {
  227. alive_sleep(1);
  228. }
  229. retval = str7x_result(bank);
  230. if (retval)
  231. {
  232. LOG_ERROR("error erasing flash bank, FLASH_ER: 0x%" PRIx32 "", retval);
  233. return ERROR_FLASH_OPERATION_FAILED;
  234. }
  235. for (i = first; i <= last; i++)
  236. bank->sectors[i].is_erased = 1;
  237. return ERROR_OK;
  238. }
  239. static int str7x_protect(struct flash_bank_s *bank, int set, int first, int last)
  240. {
  241. str7x_flash_bank_t *str7x_info = bank->driver_priv;
  242. target_t *target = bank->target;
  243. int i;
  244. uint32_t cmd;
  245. uint32_t retval;
  246. uint32_t protect_blocks;
  247. if (bank->target->state != TARGET_HALTED)
  248. {
  249. LOG_ERROR("Target not halted");
  250. return ERROR_TARGET_NOT_HALTED;
  251. }
  252. protect_blocks = 0xFFFFFFFF;
  253. if (set)
  254. {
  255. for (i = first; i <= last; i++)
  256. protect_blocks &= ~(str7x_info->sector_bits[i]);
  257. }
  258. /* clear FLASH_ER register */
  259. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
  260. cmd = FLASH_SPR;
  261. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
  262. cmd = str7x_get_flash_adr(bank, FLASH_NVWPAR);
  263. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), cmd);
  264. cmd = protect_blocks;
  265. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), cmd);
  266. cmd = FLASH_SPR | FLASH_WMS;
  267. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
  268. while (((retval = str7x_status(bank)) & str7x_info->busy_bits)) {
  269. alive_sleep(1);
  270. }
  271. retval = str7x_result(bank);
  272. LOG_DEBUG("retval: 0x%8.8" PRIx32 "", retval);
  273. if (retval & FLASH_ERER)
  274. return ERROR_FLASH_SECTOR_NOT_ERASED;
  275. else if (retval & FLASH_WPF)
  276. return ERROR_FLASH_OPERATION_FAILED;
  277. return ERROR_OK;
  278. }
  279. static int str7x_write_block(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
  280. {
  281. str7x_flash_bank_t *str7x_info = bank->driver_priv;
  282. target_t *target = bank->target;
  283. uint32_t buffer_size = 8192;
  284. working_area_t *source;
  285. uint32_t address = bank->base + offset;
  286. reg_param_t reg_params[6];
  287. armv4_5_algorithm_t armv4_5_info;
  288. int retval = ERROR_OK;
  289. uint32_t str7x_flash_write_code[] = {
  290. /* write: */
  291. 0xe3a04201, /* mov r4, #0x10000000 */
  292. 0xe5824000, /* str r4, [r2, #0x0] */
  293. 0xe5821010, /* str r1, [r2, #0x10] */
  294. 0xe4904004, /* ldr r4, [r0], #4 */
  295. 0xe5824008, /* str r4, [r2, #0x8] */
  296. 0xe4904004, /* ldr r4, [r0], #4 */
  297. 0xe582400c, /* str r4, [r2, #0xc] */
  298. 0xe3a04209, /* mov r4, #0x90000000 */
  299. 0xe5824000, /* str r4, [r2, #0x0] */
  300. /* busy: */
  301. 0xe5924000, /* ldr r4, [r2, #0x0] */
  302. 0xe1140005, /* tst r4, r5 */
  303. 0x1afffffc, /* bne busy */
  304. 0xe5924014, /* ldr r4, [r2, #0x14] */
  305. 0xe31400ff, /* tst r4, #0xff */
  306. 0x03140c01, /* tsteq r4, #0x100 */
  307. 0x1a000002, /* bne exit */
  308. 0xe2811008, /* add r1, r1, #0x8 */
  309. 0xe2533001, /* subs r3, r3, #1 */
  310. 0x1affffec, /* bne write */
  311. /* exit: */
  312. 0xeafffffe, /* b exit */
  313. };
  314. /* flash write code */
  315. if (target_alloc_working_area(target, 4 * 20, &str7x_info->write_algorithm) != ERROR_OK)
  316. {
  317. LOG_WARNING("no working area available, can't do block memory writes");
  318. return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
  319. };
  320. target_write_buffer(target, str7x_info->write_algorithm->address, 20 * 4, (uint8_t*)str7x_flash_write_code);
  321. /* memory buffer */
  322. while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
  323. {
  324. buffer_size /= 2;
  325. if (buffer_size <= 256)
  326. {
  327. /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
  328. if (str7x_info->write_algorithm)
  329. target_free_working_area(target, str7x_info->write_algorithm);
  330. LOG_WARNING("no large enough working area available, can't do block memory writes");
  331. return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
  332. }
  333. }
  334. armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
  335. armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
  336. armv4_5_info.core_state = ARMV4_5_STATE_ARM;
  337. init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
  338. init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
  339. init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
  340. init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
  341. init_reg_param(&reg_params[4], "r4", 32, PARAM_IN);
  342. init_reg_param(&reg_params[5], "r5", 32, PARAM_OUT);
  343. while (count > 0)
  344. {
  345. uint32_t thisrun_count = (count > (buffer_size / 8)) ? (buffer_size / 8) : count;
  346. target_write_buffer(target, source->address, thisrun_count * 8, buffer);
  347. buf_set_u32(reg_params[0].value, 0, 32, source->address);
  348. buf_set_u32(reg_params[1].value, 0, 32, address);
  349. buf_set_u32(reg_params[2].value, 0, 32, str7x_get_flash_adr(bank, FLASH_CR0));
  350. buf_set_u32(reg_params[3].value, 0, 32, thisrun_count);
  351. buf_set_u32(reg_params[5].value, 0, 32, str7x_info->busy_bits);
  352. if ((retval = target_run_algorithm(target, 0, NULL, 6, reg_params, str7x_info->write_algorithm->address, str7x_info->write_algorithm->address + (19 * 4), 10000, &armv4_5_info)) != ERROR_OK)
  353. {
  354. LOG_ERROR("error executing str7x flash write algorithm");
  355. retval = ERROR_FLASH_OPERATION_FAILED;
  356. break;
  357. }
  358. if (buf_get_u32(reg_params[4].value, 0, 32) != 0x00)
  359. {
  360. retval = ERROR_FLASH_OPERATION_FAILED;
  361. break;
  362. }
  363. buffer += thisrun_count * 8;
  364. address += thisrun_count * 8;
  365. count -= thisrun_count;
  366. }
  367. target_free_working_area(target, source);
  368. target_free_working_area(target, str7x_info->write_algorithm);
  369. destroy_reg_param(&reg_params[0]);
  370. destroy_reg_param(&reg_params[1]);
  371. destroy_reg_param(&reg_params[2]);
  372. destroy_reg_param(&reg_params[3]);
  373. destroy_reg_param(&reg_params[4]);
  374. destroy_reg_param(&reg_params[5]);
  375. return retval;
  376. }
  377. static int str7x_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
  378. {
  379. target_t *target = bank->target;
  380. str7x_flash_bank_t *str7x_info = bank->driver_priv;
  381. uint32_t dwords_remaining = (count / 8);
  382. uint32_t bytes_remaining = (count & 0x00000007);
  383. uint32_t address = bank->base + offset;
  384. uint32_t bytes_written = 0;
  385. uint32_t cmd;
  386. int retval;
  387. uint32_t check_address = offset;
  388. int i;
  389. if (bank->target->state != TARGET_HALTED)
  390. {
  391. LOG_ERROR("Target not halted");
  392. return ERROR_TARGET_NOT_HALTED;
  393. }
  394. if (offset & 0x7)
  395. {
  396. LOG_WARNING("offset 0x%" PRIx32 " breaks required 8-byte alignment", offset);
  397. return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
  398. }
  399. for (i = 0; i < bank->num_sectors; i++)
  400. {
  401. uint32_t sec_start = bank->sectors[i].offset;
  402. uint32_t sec_end = sec_start + bank->sectors[i].size;
  403. /* check if destination falls within the current sector */
  404. if ((check_address >= sec_start) && (check_address < sec_end))
  405. {
  406. /* check if destination ends in the current sector */
  407. if (offset + count < sec_end)
  408. check_address = offset + count;
  409. else
  410. check_address = sec_end;
  411. }
  412. }
  413. if (check_address != offset + count)
  414. return ERROR_FLASH_DST_OUT_OF_BANK;
  415. /* clear FLASH_ER register */
  416. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
  417. /* multiple dwords (8-byte) to be programmed? */
  418. if (dwords_remaining > 0)
  419. {
  420. /* try using a block write */
  421. if ((retval = str7x_write_block(bank, buffer, offset, dwords_remaining)) != ERROR_OK)
  422. {
  423. if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
  424. {
  425. /* if block write failed (no sufficient working area),
  426. * we use normal (slow) single dword accesses */
  427. LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
  428. }
  429. else if (retval == ERROR_FLASH_OPERATION_FAILED)
  430. {
  431. /* if an error occured, we examine the reason, and quit */
  432. retval = str7x_result(bank);
  433. LOG_ERROR("flash writing failed with error code: 0x%x", retval);
  434. return ERROR_FLASH_OPERATION_FAILED;
  435. }
  436. }
  437. else
  438. {
  439. buffer += dwords_remaining * 8;
  440. address += dwords_remaining * 8;
  441. dwords_remaining = 0;
  442. }
  443. }
  444. while (dwords_remaining > 0)
  445. {
  446. /* command */
  447. cmd = FLASH_DWPG;
  448. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
  449. /* address */
  450. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);
  451. /* data word 1 */
  452. target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0), 4, 1, buffer + bytes_written);
  453. bytes_written += 4;
  454. /* data word 2 */
  455. target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1), 4, 1, buffer + bytes_written);
  456. bytes_written += 4;
  457. /* start programming cycle */
  458. cmd = FLASH_DWPG | FLASH_WMS;
  459. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
  460. while (((retval = str7x_status(bank)) & str7x_info->busy_bits))
  461. {
  462. alive_sleep(1);
  463. }
  464. retval = str7x_result(bank);
  465. if (retval & FLASH_PGER)
  466. return ERROR_FLASH_OPERATION_FAILED;
  467. else if (retval & FLASH_WPF)
  468. return ERROR_FLASH_OPERATION_FAILED;
  469. dwords_remaining--;
  470. address += 8;
  471. }
  472. if (bytes_remaining)
  473. {
  474. uint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
  475. int i = 0;
  476. while (bytes_remaining > 0)
  477. {
  478. last_dword[i++] = *(buffer + bytes_written);
  479. bytes_remaining--;
  480. bytes_written++;
  481. }
  482. /* command */
  483. cmd = FLASH_DWPG;
  484. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
  485. /* address */
  486. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);
  487. /* data word 1 */
  488. target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0), 4, 1, last_dword);
  489. bytes_written += 4;
  490. /* data word 2 */
  491. target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1), 4, 1, last_dword + 4);
  492. bytes_written += 4;
  493. /* start programming cycle */
  494. cmd = FLASH_DWPG | FLASH_WMS;
  495. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
  496. while (((retval = str7x_status(bank)) & str7x_info->busy_bits))
  497. {
  498. alive_sleep(1);
  499. }
  500. retval = str7x_result(bank);
  501. if (retval & FLASH_PGER)
  502. return ERROR_FLASH_OPERATION_FAILED;
  503. else if (retval & FLASH_WPF)
  504. return ERROR_FLASH_OPERATION_FAILED;
  505. }
  506. return ERROR_OK;
  507. }
  508. static int str7x_probe(struct flash_bank_s *bank)
  509. {
  510. return ERROR_OK;
  511. }
  512. #if 0
  513. static int str7x_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  514. {
  515. return ERROR_OK;
  516. }
  517. #endif
  518. static int str7x_info(struct flash_bank_s *bank, char *buf, int buf_size)
  519. {
  520. snprintf(buf, buf_size, "str7x flash driver info");
  521. return ERROR_OK;
  522. }
  523. static int str7x_handle_disable_jtag_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  524. {
  525. flash_bank_t *bank;
  526. target_t *target = NULL;
  527. str7x_flash_bank_t *str7x_info = NULL;
  528. uint32_t flash_cmd;
  529. uint32_t retval;
  530. uint16_t ProtectionLevel = 0;
  531. uint16_t ProtectionRegs;
  532. if (argc < 1)
  533. {
  534. command_print(cmd_ctx, "str7x disable_jtag <bank>");
  535. return ERROR_OK;
  536. }
  537. bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
  538. if (!bank)
  539. {
  540. command_print(cmd_ctx, "str7x disable_jtag <bank> ok");
  541. return ERROR_OK;
  542. }
  543. str7x_info = bank->driver_priv;
  544. target = bank->target;
  545. if (target->state != TARGET_HALTED)
  546. {
  547. LOG_ERROR("Target not halted");
  548. return ERROR_TARGET_NOT_HALTED;
  549. }
  550. /* first we get protection status */
  551. target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR0), &retval);
  552. if (!(retval & str7x_info->disable_bit))
  553. {
  554. ProtectionLevel = 1;
  555. }
  556. target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR1), &retval);
  557. ProtectionRegs = ~(retval >> 16);
  558. while (((ProtectionRegs) != 0) && (ProtectionLevel < 16))
  559. {
  560. ProtectionRegs >>= 1;
  561. ProtectionLevel++;
  562. }
  563. if (ProtectionLevel == 0)
  564. {
  565. flash_cmd = FLASH_SPR;
  566. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
  567. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFB8);
  568. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), 0xFFFFFFFD);
  569. flash_cmd = FLASH_SPR | FLASH_WMS;
  570. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
  571. }
  572. else
  573. {
  574. flash_cmd = FLASH_SPR;
  575. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
  576. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFBC);
  577. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), ~(1 << (15 + ProtectionLevel)));
  578. flash_cmd = FLASH_SPR | FLASH_WMS;
  579. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
  580. }
  581. return ERROR_OK;
  582. }