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.
 
 
 
 
 
 

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