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.
 
 
 
 
 
 

1252 lines
39 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 "cfi.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 "types.h"
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #include <unistd.h>
  35. int cfi_register_commands(struct command_context_s *cmd_ctx);
  36. int cfi_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
  37. int cfi_erase(struct flash_bank_s *bank, int first, int last);
  38. int cfi_protect(struct flash_bank_s *bank, int set, int first, int last);
  39. int cfi_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
  40. int cfi_probe(struct flash_bank_s *bank);
  41. int cfi_erase_check(struct flash_bank_s *bank);
  42. int cfi_protect_check(struct flash_bank_s *bank);
  43. int cfi_info(struct flash_bank_s *bank, char *buf, int buf_size);
  44. int cfi_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
  45. #define CFI_MAX_BUS_WIDTH 4
  46. #define CFI_MAX_CHIP_WIDTH 4
  47. flash_driver_t cfi_flash =
  48. {
  49. .name = "cfi",
  50. .register_commands = cfi_register_commands,
  51. .flash_bank_command = cfi_flash_bank_command,
  52. .erase = cfi_erase,
  53. .protect = cfi_protect,
  54. .write = cfi_write,
  55. .probe = cfi_probe,
  56. .erase_check = cfi_erase_check,
  57. .protect_check = cfi_protect_check,
  58. .info = cfi_info
  59. };
  60. inline u32 flash_address(flash_bank_t *bank, int sector, u32 offset)
  61. {
  62. /* while the sector list isn't built, only accesses to sector 0 work */
  63. if (sector == 0)
  64. return bank->base + offset * bank->bus_width;
  65. else
  66. {
  67. if (!bank->sectors)
  68. {
  69. ERROR("BUG: sector list not yet built");
  70. exit(-1);
  71. }
  72. return bank->base + bank->sectors[sector].offset + offset * bank->bus_width;
  73. }
  74. }
  75. void cfi_command(flash_bank_t *bank, u8 cmd, u8 *cmd_buf)
  76. {
  77. cfi_flash_bank_t *cfi_info = bank->driver_priv;
  78. int i;
  79. if (cfi_info->target->endianness == TARGET_LITTLE_ENDIAN)
  80. {
  81. for (i = bank->bus_width; i > 0; i--)
  82. {
  83. *cmd_buf++ = (i & (bank->chip_width - 1)) ? 0x0 : cmd;
  84. }
  85. }
  86. else
  87. {
  88. for (i = 1; i <= bank->bus_width; i++)
  89. {
  90. *cmd_buf++ = (i & (bank->chip_width - 1)) ? 0x0 : cmd;
  91. }
  92. }
  93. }
  94. /* read unsigned 8-bit value from the bank
  95. * flash banks are expected to be made of similar chips
  96. * the query result should be the same for all
  97. */
  98. u8 cfi_query_u8(flash_bank_t *bank, int sector, u32 offset)
  99. {
  100. cfi_flash_bank_t *cfi_info = bank->driver_priv;
  101. target_t *target = cfi_info->target;
  102. u8 data[CFI_MAX_BUS_WIDTH];
  103. target->type->read_memory(target, flash_address(bank, sector, offset), bank->bus_width, 1, data);
  104. if (cfi_info->target->endianness == TARGET_LITTLE_ENDIAN)
  105. return data[0];
  106. else
  107. return data[bank->bus_width - 1];
  108. }
  109. /* read unsigned 8-bit value from the bank
  110. * in case of a bank made of multiple chips,
  111. * the individual values are ORed
  112. */
  113. u8 cfi_get_u8(flash_bank_t *bank, int sector, u32 offset)
  114. {
  115. cfi_flash_bank_t *cfi_info = bank->driver_priv;
  116. target_t *target = cfi_info->target;
  117. u8 data[CFI_MAX_BUS_WIDTH];
  118. int i;
  119. target->type->read_memory(target, flash_address(bank, sector, offset), bank->bus_width, 1, data);
  120. if (cfi_info->target->endianness == TARGET_LITTLE_ENDIAN)
  121. {
  122. for (i = 0; i < bank->bus_width / bank->chip_width; i++)
  123. data[0] |= data[i];
  124. return data[0];
  125. }
  126. else
  127. {
  128. u8 value = 0;
  129. for (i = 0; i < bank->bus_width / bank->chip_width; i++)
  130. value |= data[bank->bus_width - 1 - i];
  131. return value;
  132. }
  133. }
  134. u16 cfi_query_u16(flash_bank_t *bank, int sector, u32 offset)
  135. {
  136. cfi_flash_bank_t *cfi_info = bank->driver_priv;
  137. target_t *target = cfi_info->target;
  138. u8 data[CFI_MAX_BUS_WIDTH * 2];
  139. target->type->read_memory(target, flash_address(bank, sector, offset), bank->bus_width, 2, data);
  140. if (cfi_info->target->endianness == TARGET_LITTLE_ENDIAN)
  141. return data[0] | data[bank->bus_width] << 8;
  142. else
  143. return data[bank->bus_width - 1] | data[(2 * bank->bus_width) - 1] << 8;
  144. }
  145. u32 cfi_query_u32(flash_bank_t *bank, int sector, u32 offset)
  146. {
  147. cfi_flash_bank_t *cfi_info = bank->driver_priv;
  148. target_t *target = cfi_info->target;
  149. u8 data[CFI_MAX_BUS_WIDTH * 4];
  150. target->type->read_memory(target, flash_address(bank, sector, offset), bank->bus_width, 4, data);
  151. if (cfi_info->target->endianness == TARGET_LITTLE_ENDIAN)
  152. return data[0] | data[bank->bus_width] << 8 | data[bank->bus_width * 2] << 16 | data[bank->bus_width * 3] << 24;
  153. else
  154. return data[bank->bus_width - 1] | data[(2* bank->bus_width) - 1] << 8 |
  155. data[(3 * bank->bus_width) - 1] << 16 | data[(4 * bank->bus_width) - 1] << 24;
  156. }
  157. void cfi_intel_clear_status_register(flash_bank_t *bank)
  158. {
  159. cfi_flash_bank_t *cfi_info = bank->driver_priv;
  160. target_t *target = cfi_info->target;
  161. u8 command[8];
  162. if (target->state != TARGET_HALTED)
  163. {
  164. ERROR("BUG: attempted to clear status register while target wasn't halted");
  165. exit(-1);
  166. }
  167. cfi_command(bank, 0x50, command);
  168. target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
  169. }
  170. u8 cfi_intel_wait_status_busy(flash_bank_t *bank, int timeout)
  171. {
  172. u8 status;
  173. while ((!((status = cfi_get_u8(bank, 0, 0x0)) & 0x80)) && (timeout-- > 0))
  174. {
  175. DEBUG("status: 0x%x", status);
  176. usleep(1000);
  177. }
  178. DEBUG("status: 0x%x", status);
  179. if ((status & 0x80) != 0x80)
  180. {
  181. ERROR("timeout while waiting for WSM to become ready");
  182. }
  183. else if (status != 0x80)
  184. {
  185. ERROR("status register: 0x%x", status);
  186. if (status & 0x2)
  187. ERROR("Block Lock-Bit Detected, Operation Abort");
  188. if (status & 0x4)
  189. ERROR("Program suspended");
  190. if (status & 0x8)
  191. ERROR("Low Programming Voltage Detected, Operation Aborted");
  192. if (status & 0x10)
  193. ERROR("Program Error / Error in Setting Lock-Bit");
  194. if (status & 0x20)
  195. ERROR("Error in Block Erasure or Clear Lock-Bits");
  196. if (status & 0x40)
  197. ERROR("Block Erase Suspended");
  198. cfi_intel_clear_status_register(bank);
  199. }
  200. return status;
  201. }
  202. int cfi_read_intel_pri_ext(flash_bank_t *bank)
  203. {
  204. cfi_flash_bank_t *cfi_info = bank->driver_priv;
  205. cfi_intel_pri_ext_t *pri_ext = malloc(sizeof(cfi_intel_pri_ext_t));
  206. target_t *target = cfi_info->target;
  207. u8 command[8];
  208. cfi_info->pri_ext = pri_ext;
  209. pri_ext->pri[0] = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0);
  210. pri_ext->pri[1] = cfi_query_u8(bank, 0, cfi_info->pri_addr + 1);
  211. pri_ext->pri[2] = cfi_query_u8(bank, 0, cfi_info->pri_addr + 2);
  212. if ((pri_ext->pri[0] != 'P') || (pri_ext->pri[1] != 'R') || (pri_ext->pri[2] != 'I'))
  213. {
  214. cfi_command(bank, 0xf0, command);
  215. target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
  216. cfi_command(bank, 0xff, command);
  217. target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
  218. return ERROR_FLASH_BANK_INVALID;
  219. }
  220. pri_ext->major_version = cfi_query_u8(bank, 0, cfi_info->pri_addr + 3);
  221. pri_ext->minor_version = cfi_query_u8(bank, 0, cfi_info->pri_addr + 4);
  222. DEBUG("pri: '%c%c%c', version: %c.%c", pri_ext->pri[0], pri_ext->pri[1], pri_ext->pri[2], pri_ext->major_version, pri_ext->minor_version);
  223. pri_ext->feature_support = cfi_query_u32(bank, 0, cfi_info->pri_addr + 5);
  224. pri_ext->suspend_cmd_support = cfi_query_u8(bank, 0, cfi_info->pri_addr + 9);
  225. pri_ext->blk_status_reg_mask = cfi_query_u16(bank, 0, cfi_info->pri_addr + 0xa);
  226. DEBUG("feature_support: 0x%x, suspend_cmd_support: 0x%x, blk_status_reg_mask: 0x%x", pri_ext->feature_support, pri_ext->suspend_cmd_support, pri_ext->blk_status_reg_mask);
  227. pri_ext->vcc_optimal = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0xc);
  228. pri_ext->vpp_optimal = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0xd);
  229. DEBUG("Vcc opt: %1.1x.%1.1x, Vpp opt: %1.1x.%1.1x",
  230. (pri_ext->vcc_optimal & 0xf0) >> 4, pri_ext->vcc_optimal & 0x0f,
  231. (pri_ext->vpp_optimal & 0xf0) >> 4, pri_ext->vpp_optimal & 0x0f);
  232. pri_ext->num_protection_fields = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0xe);
  233. if (pri_ext->num_protection_fields != 1)
  234. {
  235. WARNING("expected one protection register field, but found %i", pri_ext->num_protection_fields);
  236. }
  237. pri_ext->prot_reg_addr = cfi_query_u16(bank, 0, cfi_info->pri_addr + 0xf);
  238. pri_ext->fact_prot_reg_size = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0x11);
  239. pri_ext->user_prot_reg_size = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0x12);
  240. DEBUG("protection_fields: %i, prot_reg_addr: 0x%x, factory pre-programmed: %i, user programmable: %i", pri_ext->num_protection_fields, pri_ext->prot_reg_addr, 1 << pri_ext->fact_prot_reg_size, 1 << pri_ext->user_prot_reg_size);
  241. return ERROR_OK;
  242. }
  243. int cfi_intel_info(struct flash_bank_s *bank, char *buf, int buf_size)
  244. {
  245. int printed;
  246. cfi_flash_bank_t *cfi_info = bank->driver_priv;
  247. cfi_intel_pri_ext_t *pri_ext = cfi_info->pri_ext;
  248. printed = snprintf(buf, buf_size, "\nintel primary algorithm extend information:\n");
  249. buf += printed;
  250. buf_size -= printed;
  251. printed = snprintf(buf, buf_size, "pri: '%c%c%c', version: %c.%c\n", pri_ext->pri[0], pri_ext->pri[1], pri_ext->pri[2], pri_ext->major_version, pri_ext->minor_version);
  252. buf += printed;
  253. buf_size -= printed;
  254. printed = snprintf(buf, buf_size, "feature_support: 0x%x, suspend_cmd_support: 0x%x, blk_status_reg_mask: 0x%x\n", pri_ext->feature_support, pri_ext->suspend_cmd_support, pri_ext->blk_status_reg_mask);
  255. buf += printed;
  256. buf_size -= printed;
  257. printed = snprintf(buf, buf_size, "Vcc opt: %1.1x.%1.1x, Vpp opt: %1.1x.%1.1x\n",
  258. (pri_ext->vcc_optimal & 0xf0) >> 4, pri_ext->vcc_optimal & 0x0f,
  259. (pri_ext->vpp_optimal & 0xf0) >> 4, pri_ext->vpp_optimal & 0x0f);
  260. buf += printed;
  261. buf_size -= printed;
  262. printed = snprintf(buf, buf_size, "protection_fields: %i, prot_reg_addr: 0x%x, factory pre-programmed: %i, user programmable: %i\n", pri_ext->num_protection_fields, pri_ext->prot_reg_addr, 1 << pri_ext->fact_prot_reg_size, 1 << pri_ext->user_prot_reg_size);
  263. return ERROR_OK;
  264. }
  265. int cfi_register_commands(struct command_context_s *cmd_ctx)
  266. {
  267. command_t *cfi_cmd = register_command(cmd_ctx, NULL, "cfi", NULL, COMMAND_ANY, NULL);
  268. /*
  269. register_command(cmd_ctx, cfi_cmd, "part_id", cfi_handle_part_id_command, COMMAND_EXEC,
  270. "print part id of cfi flash bank <num>");
  271. */
  272. return ERROR_OK;
  273. }
  274. /* flash_bank cfi <base> <size> <chip_width> <bus_width> <target#>
  275. */
  276. int cfi_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
  277. {
  278. cfi_flash_bank_t *cfi_info;
  279. if (argc < 6)
  280. {
  281. WARNING("incomplete flash_bank cfi configuration");
  282. return ERROR_FLASH_BANK_INVALID;
  283. }
  284. if ((strtoul(args[4], NULL, 0) > CFI_MAX_CHIP_WIDTH)
  285. || (strtoul(args[3], NULL, 0) > CFI_MAX_BUS_WIDTH))
  286. {
  287. ERROR("chip and bus width have to specified in byte");
  288. return ERROR_FLASH_BANK_INVALID;
  289. }
  290. cfi_info = malloc(sizeof(cfi_flash_bank_t));
  291. bank->driver_priv = cfi_info;
  292. cfi_info->target = get_target_by_num(strtoul(args[5], NULL, 0));
  293. if (!cfi_info->target)
  294. {
  295. ERROR("no target '%i' configured", args[5]);
  296. exit(-1);
  297. }
  298. cfi_info->write_algorithm = NULL;
  299. /* bank wasn't probed yet */
  300. cfi_info->qry[0] = -1;
  301. return ERROR_OK;
  302. }
  303. int cfi_intel_erase(struct flash_bank_s *bank, int first, int last)
  304. {
  305. cfi_flash_bank_t *cfi_info = bank->driver_priv;
  306. cfi_intel_pri_ext_t *pri_ext = cfi_info->pri_ext;
  307. target_t *target = cfi_info->target;
  308. u8 command[8];
  309. int i;
  310. cfi_intel_clear_status_register(bank);
  311. for (i = first; i <= last; i++)
  312. {
  313. cfi_command(bank, 0x20, command);
  314. target->type->write_memory(target, flash_address(bank, i, 0x0), bank->bus_width, 1, command);
  315. cfi_command(bank, 0xd0, command);
  316. target->type->write_memory(target, flash_address(bank, i, 0x0), bank->bus_width, 1, command);
  317. if (cfi_intel_wait_status_busy(bank, 1000 * (1 << cfi_info->block_erase_timeout_typ)) == 0x80)
  318. bank->sectors[i].is_erased = 1;
  319. else
  320. {
  321. cfi_command(bank, 0xff, command);
  322. target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
  323. ERROR("couldn't erase block %i of flash bank at base 0x%x", i, bank->base);
  324. return ERROR_FLASH_OPERATION_FAILED;
  325. }
  326. }
  327. cfi_command(bank, 0xff, command);
  328. target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
  329. return ERROR_OK;
  330. }
  331. int cfi_erase(struct flash_bank_s *bank, int first, int last)
  332. {
  333. cfi_flash_bank_t *cfi_info = bank->driver_priv;
  334. if (cfi_info->target->state != TARGET_HALTED)
  335. {
  336. return ERROR_TARGET_NOT_HALTED;
  337. }
  338. if ((first < 0) || (last < first) || (last >= bank->num_sectors))
  339. {
  340. return ERROR_FLASH_SECTOR_INVALID;
  341. }
  342. if (cfi_info->qry[0] != 'Q')
  343. return ERROR_FLASH_BANK_NOT_PROBED;
  344. switch(cfi_info->pri_id)
  345. {
  346. case 1:
  347. case 3:
  348. return cfi_intel_erase(bank, first, last);
  349. break;
  350. default:
  351. ERROR("cfi primary command set %i unsupported", cfi_info->pri_id);
  352. break;
  353. }
  354. return ERROR_OK;
  355. }
  356. int cfi_intel_protect(struct flash_bank_s *bank, int set, int first, int last)
  357. {
  358. cfi_flash_bank_t *cfi_info = bank->driver_priv;
  359. cfi_intel_pri_ext_t *pri_ext = cfi_info->pri_ext;
  360. target_t *target = cfi_info->target;
  361. u8 command[8];
  362. int i;
  363. /* if the device supports neither legacy lock/unlock (bit 3) nor
  364. * instant individual block locking (bit 5).
  365. */
  366. if (!(pri_ext->feature_support & 0x28))
  367. return ERROR_FLASH_OPERATION_FAILED;
  368. cfi_intel_clear_status_register(bank);
  369. for (i = first; i <= last; i++)
  370. {
  371. cfi_command(bank, 0x60, command);
  372. target->type->write_memory(target, flash_address(bank, i, 0x0), bank->bus_width, 1, command);
  373. if (set)
  374. {
  375. cfi_command(bank, 0x01, command);
  376. target->type->write_memory(target, flash_address(bank, i, 0x0), bank->bus_width, 1, command);
  377. bank->sectors[i].is_protected = 1;
  378. }
  379. else
  380. {
  381. cfi_command(bank, 0xd0, command);
  382. target->type->write_memory(target, flash_address(bank, i, 0x0), bank->bus_width, 1, command);
  383. bank->sectors[i].is_protected = 0;
  384. }
  385. /* Clear lock bits operation may take up to 1.4s */
  386. cfi_intel_wait_status_busy(bank, 1400);
  387. }
  388. /* if the device doesn't support individual block lock bits set/clear,
  389. * all blocks have been unlocked in parallel, so we set those that should be protected
  390. */
  391. if ((!set) && (!(pri_ext->feature_support & 0x20)))
  392. {
  393. for (i = 0; i < bank->num_sectors; i++)
  394. {
  395. cfi_intel_clear_status_register(bank);
  396. cfi_command(bank, 0x60, command);
  397. target->type->write_memory(target, flash_address(bank, i, 0x0), bank->bus_width, 1, command);
  398. if (bank->sectors[i].is_protected == 1)
  399. {
  400. cfi_command(bank, 0x01, command);
  401. target->type->write_memory(target, flash_address(bank, i, 0x0), bank->bus_width, 1, command);
  402. }
  403. cfi_intel_wait_status_busy(bank, 100);
  404. }
  405. }
  406. cfi_command(bank, 0xff, command);
  407. target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
  408. return ERROR_OK;
  409. }
  410. int cfi_protect(struct flash_bank_s *bank, int set, int first, int last)
  411. {
  412. cfi_flash_bank_t *cfi_info = bank->driver_priv;
  413. if (cfi_info->target->state != TARGET_HALTED)
  414. {
  415. return ERROR_TARGET_NOT_HALTED;
  416. }
  417. if ((first < 0) || (last < first) || (last >= bank->num_sectors))
  418. {
  419. return ERROR_FLASH_SECTOR_INVALID;
  420. }
  421. if (cfi_info->qry[0] != 'Q')
  422. return ERROR_FLASH_BANK_NOT_PROBED;
  423. switch(cfi_info->pri_id)
  424. {
  425. case 1:
  426. case 3:
  427. cfi_intel_protect(bank, set, first, last);
  428. break;
  429. default:
  430. ERROR("cfi primary command set %i unsupported", cfi_info->pri_id);
  431. break;
  432. }
  433. return ERROR_OK;
  434. }
  435. void cfi_add_byte(struct flash_bank_s *bank, u8 *word, u8 byte)
  436. {
  437. cfi_flash_bank_t *cfi_info = bank->driver_priv;
  438. target_t *target = cfi_info->target;
  439. int i;
  440. if (target->endianness == TARGET_LITTLE_ENDIAN)
  441. {
  442. /* shift bytes */
  443. for (i = 0; i < bank->bus_width - 1; i++)
  444. word[i] = word[i + 1];
  445. word[bank->bus_width - 1] = byte;
  446. }
  447. else
  448. {
  449. /* shift bytes */
  450. for (i = bank->bus_width - 1; i > 0; i--)
  451. word[i] = word[i - 1];
  452. word[0] = byte;
  453. }
  454. }
  455. int cfi_intel_write_block(struct flash_bank_s *bank, u8 *buffer, u32 address, u32 count)
  456. {
  457. cfi_flash_bank_t *cfi_info = bank->driver_priv;
  458. cfi_intel_pri_ext_t *pri_ext = cfi_info->pri_ext;
  459. target_t *target = cfi_info->target;
  460. reg_param_t reg_params[7];
  461. armv4_5_algorithm_t armv4_5_info;
  462. working_area_t *source;
  463. u32 buffer_size = 32768;
  464. u8 write_command[CFI_MAX_BUS_WIDTH];
  465. u8 busy_pattern[CFI_MAX_BUS_WIDTH];
  466. u8 error_pattern[CFI_MAX_BUS_WIDTH];
  467. int i;
  468. int retval;
  469. /* algorithm register usage:
  470. * r0: source address (in RAM)
  471. * r1: target address (in Flash)
  472. * r2: count
  473. * r3: flash write command
  474. * r4: status byte (returned to host)
  475. * r5: busy test pattern
  476. * r6: error test pattern
  477. */
  478. u32 word_32_code[] = {
  479. 0xe4904004, /* loop: ldr r4, [r0], #4 */
  480. 0xe5813000, /* str r3, [r1] */
  481. 0xe5814000, /* str r4, [r1] */
  482. 0xe5914000, /* busy: ldr r4, [r1] */
  483. 0xe0047005, /* and r7, r4, r5 */
  484. 0xe1570005, /* cmp r7, r5 */
  485. 0x1afffffb, /* bne busy */
  486. 0xe1140006, /* tst r4, r6 */
  487. 0x1a000003, /* bne done */
  488. 0xe2522001, /* subs r2, r2, #1 */
  489. 0x0a000001, /* beq done */
  490. 0xe2811004, /* add r1, r1 #4 */
  491. 0xeafffff2, /* b loop */
  492. 0xeafffffe, /* done: b -2 */
  493. };
  494. u32 word_16_code[] = {
  495. 0xe0d040b2, /* loop: ldrh r4, [r0], #2 */
  496. 0xe1c130b0, /* strh r3, [r1] */
  497. 0xe1c140b0, /* strh r4, [r1] */
  498. 0xe1d140b0, /* busy ldrh r4, [r1] */
  499. 0xe0047005, /* and r7, r4, r5 */
  500. 0xe1570005, /* cmp r7, r5 */
  501. 0x1afffffb, /* bne busy */
  502. 0xe1140006, /* tst r4, r6 */
  503. 0x1a000003, /* bne done */
  504. 0xe2522001, /* subs r2, r2, #1 */
  505. 0x0a000001, /* beq done */
  506. 0xe2811002, /* add r1, r1 #2 */
  507. 0xeafffff2, /* b loop */
  508. 0xeafffffe, /* done: b -2 */
  509. };
  510. u32 word_8_code[] = {
  511. 0xe4d04001, /* loop: ldrb r4, [r0], #1 */
  512. 0xe5c13000, /* strb r3, [r1] */
  513. 0xe5c14000, /* strb r4, [r1] */
  514. 0xe5d14000, /* busy ldrb r4, [r1] */
  515. 0xe0047005, /* and r7, r4, r5 */
  516. 0xe1570005, /* cmp r7, r5 */
  517. 0x1afffffb, /* bne busy */
  518. 0xe1140006, /* tst r4, r6 */
  519. 0x1a000003, /* bne done */
  520. 0xe2522001, /* subs r2, r2, #1 */
  521. 0x0a000001, /* beq done */
  522. 0xe2811001, /* add r1, r1 #1 */
  523. 0xeafffff2, /* b loop */
  524. 0xeafffffe, /* done: b -2 */
  525. };
  526. cfi_intel_clear_status_register(bank);
  527. armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
  528. armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
  529. armv4_5_info.core_state = ARMV4_5_STATE_ARM;
  530. /* flash write code */
  531. if (!cfi_info->write_algorithm)
  532. {
  533. if (target_alloc_working_area(target, 4 * 14, &cfi_info->write_algorithm) != ERROR_OK)
  534. {
  535. WARNING("no working area available, can't do block memory writes");
  536. return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
  537. };
  538. /* write algorithm code to working area */
  539. if (bank->bus_width == 1)
  540. {
  541. target_write_buffer(target, cfi_info->write_algorithm->address, 14 * 4, (u8*)word_8_code);
  542. }
  543. else if (bank->bus_width == 2)
  544. {
  545. target_write_buffer(target, cfi_info->write_algorithm->address, 14 * 4, (u8*)word_16_code);
  546. }
  547. else if (bank->bus_width == 4)
  548. {
  549. target_write_buffer(target, cfi_info->write_algorithm->address, 14 * 4, (u8*)word_32_code);
  550. }
  551. else
  552. {
  553. return ERROR_FLASH_OPERATION_FAILED;
  554. }
  555. }
  556. while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
  557. {
  558. buffer_size /= 2;
  559. if (buffer_size <= 256)
  560. {
  561. /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
  562. if (cfi_info->write_algorithm)
  563. target_free_working_area(target, cfi_info->write_algorithm);
  564. WARNING("no large enough working area available, can't do block memory writes");
  565. return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
  566. }
  567. };
  568. init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
  569. init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
  570. init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
  571. init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
  572. init_reg_param(&reg_params[4], "r4", 32, PARAM_IN);
  573. init_reg_param(&reg_params[5], "r5", 32, PARAM_OUT);
  574. init_reg_param(&reg_params[6], "r6", 32, PARAM_OUT);
  575. cfi_command(bank, 0x40, write_command);
  576. cfi_command(bank, 0x80, busy_pattern);
  577. cfi_command(bank, 0x7f, error_pattern);
  578. while (count > 0)
  579. {
  580. u32 thisrun_count = (count > buffer_size) ? buffer_size : count;
  581. target_write_buffer(target, source->address, thisrun_count, buffer);
  582. buf_set_u32(reg_params[0].value, 0, 32, source->address);
  583. buf_set_u32(reg_params[1].value, 0, 32, address);
  584. buf_set_u32(reg_params[2].value, 0, 32, thisrun_count / bank->bus_width);
  585. buf_set_u32(reg_params[3].value, 0, 32, buf_get_u32(write_command, 0, 32));
  586. buf_set_u32(reg_params[5].value, 0, 32, buf_get_u32(busy_pattern, 0, 32));
  587. buf_set_u32(reg_params[6].value, 0, 32, buf_get_u32(error_pattern, 0, 32));
  588. if ((retval = target->type->run_algorithm(target, 0, NULL, 7, reg_params, cfi_info->write_algorithm->address, cfi_info->write_algorithm->address + (13 * 4), 10000, &armv4_5_info)) != ERROR_OK)
  589. {
  590. cfi_intel_clear_status_register(bank);
  591. return ERROR_FLASH_OPERATION_FAILED;
  592. }
  593. if (buf_get_u32(reg_params[4].value, 0, 32) & target_buffer_get_u32(target, error_pattern))
  594. {
  595. /* read status register (outputs debug inforation) */
  596. cfi_intel_wait_status_busy(bank, 100);
  597. cfi_intel_clear_status_register(bank);
  598. return ERROR_FLASH_OPERATION_FAILED;
  599. }
  600. buffer += thisrun_count;
  601. address += thisrun_count;
  602. count -= thisrun_count;
  603. }
  604. target_free_working_area(target, source);
  605. destroy_reg_param(&reg_params[0]);
  606. destroy_reg_param(&reg_params[1]);
  607. destroy_reg_param(&reg_params[2]);
  608. destroy_reg_param(&reg_params[3]);
  609. destroy_reg_param(&reg_params[4]);
  610. destroy_reg_param(&reg_params[5]);
  611. destroy_reg_param(&reg_params[6]);
  612. return ERROR_OK;
  613. }
  614. int cfi_intel_write_word(struct flash_bank_s *bank, u8 *word, u32 address)
  615. {
  616. cfi_flash_bank_t *cfi_info = bank->driver_priv;
  617. cfi_intel_pri_ext_t *pri_ext = cfi_info->pri_ext;
  618. target_t *target = cfi_info->target;
  619. u8 command[8];
  620. cfi_intel_clear_status_register(bank);
  621. cfi_command(bank, 0x40, command);
  622. target->type->write_memory(target, address, bank->bus_width, 1, command);
  623. target->type->write_memory(target, address, bank->bus_width, 1, word);
  624. if (cfi_intel_wait_status_busy(bank, 1000 * (1 << cfi_info->word_write_timeout_max)) != 0x80)
  625. {
  626. cfi_command(bank, 0xff, command);
  627. target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
  628. ERROR("couldn't write word at base 0x%x, address %x", bank->base, address);
  629. return ERROR_FLASH_OPERATION_FAILED;
  630. }
  631. return ERROR_OK;
  632. }
  633. int cfi_write_word(struct flash_bank_s *bank, u8 *word, u32 address)
  634. {
  635. cfi_flash_bank_t *cfi_info = bank->driver_priv;
  636. target_t *target = cfi_info->target;
  637. switch(cfi_info->pri_id)
  638. {
  639. case 1:
  640. case 3:
  641. return cfi_intel_write_word(bank, word, address);
  642. break;
  643. default:
  644. ERROR("cfi primary command set %i unsupported", cfi_info->pri_id);
  645. break;
  646. }
  647. return ERROR_FLASH_OPERATION_FAILED;
  648. }
  649. int cfi_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
  650. {
  651. cfi_flash_bank_t *cfi_info = bank->driver_priv;
  652. target_t *target = cfi_info->target;
  653. u32 address = bank->base + offset; /* address of first byte to be programmed */
  654. u32 write_p, copy_p;
  655. int align; /* number of unaligned bytes */
  656. u8 current_word[CFI_MAX_BUS_WIDTH * 4]; /* word (bus_width size) currently being programmed */
  657. int i;
  658. int retval;
  659. if (cfi_info->target->state != TARGET_HALTED)
  660. {
  661. return ERROR_TARGET_NOT_HALTED;
  662. }
  663. if (offset + count > bank->size)
  664. return ERROR_FLASH_DST_OUT_OF_BANK;
  665. if (cfi_info->qry[0] != 'Q')
  666. return ERROR_FLASH_BANK_NOT_PROBED;
  667. /* start at the first byte of the first word (bus_width size) */
  668. write_p = address & ~(bank->bus_width - 1);
  669. if ((align = address - write_p) != 0)
  670. {
  671. for (i = 0; i < bank->bus_width; i++)
  672. current_word[i] = 0;
  673. copy_p = write_p;
  674. /* copy bytes before the first write address */
  675. for (i = 0; i < align; ++i, ++copy_p)
  676. {
  677. u8 byte;
  678. target->type->read_memory(target, copy_p, 1, 1, &byte);
  679. cfi_add_byte(bank, current_word, byte);
  680. }
  681. /* add bytes from the buffer */
  682. for (; (i < bank->bus_width) && (count > 0); i++)
  683. {
  684. cfi_add_byte(bank, current_word, *buffer++);
  685. count--;
  686. copy_p++;
  687. }
  688. /* if the buffer is already finished, copy bytes after the last write address */
  689. for (; (count == 0) && (i < bank->bus_width); ++i, ++copy_p)
  690. {
  691. u8 byte;
  692. target->type->read_memory(target, copy_p, 1, 1, &byte);
  693. cfi_add_byte(bank, current_word, byte);
  694. }
  695. retval = cfi_write_word(bank, current_word, write_p);
  696. if (retval != ERROR_OK)
  697. return retval;
  698. write_p = copy_p;
  699. }
  700. /* handle blocks of bus_size aligned bytes */
  701. switch(cfi_info->pri_id)
  702. {
  703. /* try block writes (fails without working area) */
  704. case 1:
  705. case 3:
  706. retval = cfi_intel_write_block(bank, buffer, write_p, count);
  707. break;
  708. default:
  709. ERROR("cfi primary command set %i unsupported", cfi_info->pri_id);
  710. break;
  711. }
  712. if (retval != ERROR_OK)
  713. {
  714. if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
  715. {
  716. /* fall back to memory writes */
  717. while (count > bank->bus_width)
  718. {
  719. for (i = 0; i < bank->bus_width; i++)
  720. current_word[i] = 0;
  721. for (i = 0; i < bank->bus_width; i++)
  722. {
  723. cfi_add_byte(bank, current_word, *buffer++);
  724. }
  725. retval = cfi_write_word(bank, current_word, write_p);
  726. if (retval != ERROR_OK)
  727. return retval;
  728. write_p += bank->bus_width;
  729. count -= bank->bus_width;
  730. }
  731. }
  732. else
  733. return retval;
  734. }
  735. /* handle unaligned tail bytes */
  736. if (count > 0)
  737. {
  738. copy_p = write_p;
  739. for (i = 0; i < bank->bus_width; i++)
  740. current_word[i] = 0;
  741. for (i = 0; (i < bank->bus_width) && (count > 0); ++i, ++copy_p)
  742. {
  743. cfi_add_byte(bank, current_word, *buffer++);
  744. count--;
  745. }
  746. for (; i < bank->bus_width; ++i, ++copy_p)
  747. {
  748. u8 byte;
  749. target->type->read_memory(target, copy_p, 1, 1, &byte);
  750. cfi_add_byte(bank, current_word, byte);
  751. }
  752. retval = cfi_write_word(bank, current_word, write_p);
  753. if (retval != ERROR_OK)
  754. return retval;
  755. }
  756. /* return to read array mode */
  757. cfi_command(bank, 0xf0, current_word);
  758. target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, current_word);
  759. cfi_command(bank, 0xff, current_word);
  760. target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, current_word);
  761. return ERROR_OK;
  762. }
  763. int cfi_probe(struct flash_bank_s *bank)
  764. {
  765. cfi_flash_bank_t *cfi_info = bank->driver_priv;
  766. target_t *target = cfi_info->target;
  767. u8 command[8];
  768. cfi_command(bank, 0x98, command);
  769. target->type->write_memory(target, flash_address(bank, 0, 0x55), bank->bus_width, 1, command);
  770. cfi_info->qry[0] = cfi_query_u8(bank, 0, 0x10);
  771. cfi_info->qry[1] = cfi_query_u8(bank, 0, 0x11);
  772. cfi_info->qry[2] = cfi_query_u8(bank, 0, 0x12);
  773. DEBUG("CFI qry returned: 0x%2.2x 0x%2.2x 0x%2.2x", cfi_info->qry[0], cfi_info->qry[1], cfi_info->qry[2]);
  774. if ((cfi_info->qry[0] != 'Q') || (cfi_info->qry[1] != 'R') || (cfi_info->qry[2] != 'Y'))
  775. {
  776. cfi_command(bank, 0xf0, command);
  777. target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
  778. cfi_command(bank, 0xff, command);
  779. target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
  780. return ERROR_FLASH_BANK_INVALID;
  781. }
  782. cfi_info->pri_id = cfi_query_u16(bank, 0, 0x13);
  783. cfi_info->pri_addr = cfi_query_u16(bank, 0, 0x15);
  784. cfi_info->alt_id = cfi_query_u16(bank, 0, 0x17);
  785. cfi_info->alt_addr = cfi_query_u16(bank, 0, 0x19);
  786. DEBUG("qry: '%c%c%c', pri_id: 0x%4.4x, pri_addr: 0x%4.4x, alt_id: 0x%4.4x, alt_addr: 0x%4.4x", cfi_info->qry[0], cfi_info->qry[1], cfi_info->qry[2], cfi_info->pri_id, cfi_info->pri_addr, cfi_info->alt_id, cfi_info->alt_addr);
  787. cfi_info->vcc_min = cfi_query_u8(bank, 0, 0x1b);
  788. cfi_info->vcc_max = cfi_query_u8(bank, 0, 0x1c);
  789. cfi_info->vpp_min = cfi_query_u8(bank, 0, 0x1d);
  790. cfi_info->vpp_max = cfi_query_u8(bank, 0, 0x1e);
  791. cfi_info->word_write_timeout_typ = cfi_query_u8(bank, 0, 0x1f);
  792. cfi_info->buf_write_timeout_typ = cfi_query_u8(bank, 0, 0x20);
  793. cfi_info->block_erase_timeout_typ = cfi_query_u8(bank, 0, 0x21);
  794. cfi_info->chip_erase_timeout_typ = cfi_query_u8(bank, 0, 0x22);
  795. cfi_info->word_write_timeout_max = cfi_query_u8(bank, 0, 0x23);
  796. cfi_info->buf_write_timeout_max = cfi_query_u8(bank, 0, 0x24);
  797. cfi_info->block_erase_timeout_max = cfi_query_u8(bank, 0, 0x25);
  798. cfi_info->chip_erase_timeout_max = cfi_query_u8(bank, 0, 0x26);
  799. DEBUG("Vcc min: %1.1x.%1.1x, Vcc max: %1.1x.%1.1x, Vpp min: %1.1x.%1.1x, Vpp max: %1.1x.%1.1x",
  800. (cfi_info->vcc_min & 0xf0) >> 4, cfi_info->vcc_min & 0x0f,
  801. (cfi_info->vcc_max & 0xf0) >> 4, cfi_info->vcc_max & 0x0f,
  802. (cfi_info->vpp_min & 0xf0) >> 4, cfi_info->vpp_min & 0x0f,
  803. (cfi_info->vpp_max & 0xf0) >> 4, cfi_info->vpp_max & 0x0f);
  804. DEBUG("typ. word write timeout: %u, typ. buf write timeout: %u, typ. block erase timeout: %u, typ. chip erase timeout: %u", 1 << cfi_info->word_write_timeout_typ, 1 << cfi_info->buf_write_timeout_typ,
  805. 1 << cfi_info->block_erase_timeout_typ, 1 << cfi_info->chip_erase_timeout_typ);
  806. DEBUG("max. word write timeout: %u, max. buf write timeout: %u, max. block erase timeout: %u, max. chip erase timeout: %u", (1 << cfi_info->word_write_timeout_max) * (1 << cfi_info->word_write_timeout_typ),
  807. (1 << cfi_info->buf_write_timeout_max) * (1 << cfi_info->buf_write_timeout_typ),
  808. (1 << cfi_info->block_erase_timeout_max) * (1 << cfi_info->block_erase_timeout_typ),
  809. (1 << cfi_info->chip_erase_timeout_max) * (1 << cfi_info->chip_erase_timeout_typ));
  810. cfi_info->dev_size = cfi_query_u8(bank, 0, 0x27);
  811. cfi_info->interface_desc = cfi_query_u16(bank, 0, 0x28);
  812. cfi_info->max_buf_write_size = cfi_query_u16(bank, 0, 0x2a);
  813. cfi_info->num_erase_regions = cfi_query_u8(bank, 0, 0x2c);
  814. DEBUG("size: 0x%x, interface desc: %i, max buffer write size: %x", 1 << cfi_info->dev_size, cfi_info->interface_desc, (1 << cfi_info->max_buf_write_size));
  815. if (((1 << cfi_info->dev_size) * bank->bus_width / bank->chip_width) != bank->size)
  816. {
  817. WARNING("configuration specifies 0x%x size, but a 0x%x size flash was found", bank->size, 1 << cfi_info->dev_size);
  818. }
  819. if (cfi_info->num_erase_regions)
  820. {
  821. int i;
  822. int num_sectors = 0;
  823. int sector = 0;
  824. u32 offset = 0;
  825. cfi_info->erase_region_info = malloc(4 * cfi_info->num_erase_regions);
  826. for (i = 0; i < cfi_info->num_erase_regions; i++)
  827. {
  828. cfi_info->erase_region_info[i] = cfi_query_u32(bank, 0, 0x2d + (4 * i));
  829. DEBUG("erase region[%i]: %i blocks of size 0x%x", i, (cfi_info->erase_region_info[i] & 0xffff) + 1, (cfi_info->erase_region_info[i] >> 16) * 256);
  830. num_sectors += (cfi_info->erase_region_info[i] & 0xffff) + 1;
  831. }
  832. bank->num_sectors = num_sectors;
  833. bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors);
  834. for (i = 0; i < cfi_info->num_erase_regions; i++)
  835. {
  836. int j;
  837. for (j = 0; j < (cfi_info->erase_region_info[i] & 0xffff) + 1; j++)
  838. {
  839. bank->sectors[sector].offset = offset;
  840. bank->sectors[sector].size = ((cfi_info->erase_region_info[i] >> 16) * 256) * bank->bus_width / bank->chip_width;
  841. offset += bank->sectors[sector].size;
  842. bank->sectors[sector].is_erased = -1;
  843. bank->sectors[sector].is_protected = -1;
  844. sector++;
  845. }
  846. }
  847. }
  848. else
  849. {
  850. cfi_info->erase_region_info = NULL;
  851. }
  852. switch(cfi_info->pri_id)
  853. {
  854. case 1:
  855. case 3:
  856. cfi_read_intel_pri_ext(bank);
  857. break;
  858. default:
  859. ERROR("cfi primary command set %i unsupported", cfi_info->pri_id);
  860. break;
  861. }
  862. /* return to read array mode */
  863. cfi_command(bank, 0xf0, command);
  864. target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
  865. cfi_command(bank, 0xff, command);
  866. target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
  867. return ERROR_OK;
  868. }
  869. int cfi_erase_check(struct flash_bank_s *bank)
  870. {
  871. cfi_flash_bank_t *cfi_info = bank->driver_priv;
  872. target_t *target = cfi_info->target;
  873. int i;
  874. int retval;
  875. if (!cfi_info->erase_check_algorithm)
  876. {
  877. u32 erase_check_code[] =
  878. {
  879. 0xe4d03001, /* ldrb r3, [r0], #1 */
  880. 0xe0022003, /* and r2, r2, r3 */
  881. 0xe2511001, /* subs r1, r1, #1 */
  882. 0x1afffffb, /* b -4 */
  883. 0xeafffffe /* b 0 */
  884. };
  885. /* make sure we have a working area */
  886. if (target_alloc_working_area(target, 20, &cfi_info->erase_check_algorithm) != ERROR_OK)
  887. {
  888. WARNING("no working area available, falling back to slow memory reads");
  889. }
  890. else
  891. {
  892. u8 erase_check_code_buf[5 * 4];
  893. for (i = 0; i < 5; i++)
  894. target_buffer_set_u32(target, erase_check_code_buf + (i*4), erase_check_code[i]);
  895. /* write algorithm code to working area */
  896. target->type->write_memory(target, cfi_info->erase_check_algorithm->address, 4, 5, erase_check_code_buf);
  897. }
  898. }
  899. if (!cfi_info->erase_check_algorithm)
  900. {
  901. u32 *buffer = malloc(4096);
  902. for (i = 0; i < bank->num_sectors; i++)
  903. {
  904. u32 address = bank->base + bank->sectors[i].offset;
  905. u32 size = bank->sectors[i].size;
  906. u32 check = 0xffffffffU;
  907. int erased = 1;
  908. while (size > 0)
  909. {
  910. u32 thisrun_size = (size > 4096) ? 4096 : size;
  911. int j;
  912. target->type->read_memory(target, address, 4, thisrun_size / 4, (u8*)buffer);
  913. for (j = 0; j < thisrun_size / 4; j++)
  914. check &= buffer[j];
  915. if (check != 0xffffffff)
  916. {
  917. erased = 0;
  918. break;
  919. }
  920. size -= thisrun_size;
  921. address += thisrun_size;
  922. }
  923. bank->sectors[i].is_erased = erased;
  924. }
  925. free(buffer);
  926. }
  927. else
  928. {
  929. for (i = 0; i < bank->num_sectors; i++)
  930. {
  931. u32 address = bank->base + bank->sectors[i].offset;
  932. u32 size = bank->sectors[i].size;
  933. reg_param_t reg_params[3];
  934. armv4_5_algorithm_t armv4_5_info;
  935. armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
  936. armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
  937. armv4_5_info.core_state = ARMV4_5_STATE_ARM;
  938. init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
  939. buf_set_u32(reg_params[0].value, 0, 32, address);
  940. init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
  941. buf_set_u32(reg_params[1].value, 0, 32, size);
  942. init_reg_param(&reg_params[2], "r2", 32, PARAM_IN_OUT);
  943. buf_set_u32(reg_params[2].value, 0, 32, 0xff);
  944. if ((retval = target->type->run_algorithm(target, 0, NULL, 3, reg_params, cfi_info->erase_check_algorithm->address, cfi_info->erase_check_algorithm->address + 0x10, 10000, &armv4_5_info)) != ERROR_OK)
  945. return ERROR_FLASH_OPERATION_FAILED;
  946. if (buf_get_u32(reg_params[2].value, 0, 32) == 0xff)
  947. bank->sectors[i].is_erased = 1;
  948. else
  949. bank->sectors[i].is_erased = 0;
  950. destroy_reg_param(&reg_params[0]);
  951. destroy_reg_param(&reg_params[1]);
  952. destroy_reg_param(&reg_params[2]);
  953. }
  954. }
  955. return ERROR_OK;
  956. }
  957. int cfi_intel_protect_check(struct flash_bank_s *bank)
  958. {
  959. cfi_flash_bank_t *cfi_info = bank->driver_priv;
  960. cfi_intel_pri_ext_t *pri_ext = cfi_info->pri_ext;
  961. target_t *target = cfi_info->target;
  962. u8 command[CFI_MAX_BUS_WIDTH];
  963. int i;
  964. /* check if block lock bits are supported on this device */
  965. if (!(pri_ext->blk_status_reg_mask & 0x1))
  966. return ERROR_FLASH_OPERATION_FAILED;
  967. cfi_command(bank, 0x90, command);
  968. target->type->write_memory(target, flash_address(bank, 0, 0x55), bank->bus_width, 1, command);
  969. for (i = 0; i < bank->num_sectors; i++)
  970. {
  971. u8 block_status = cfi_get_u8(bank, i, 0x2);
  972. if (block_status & 1)
  973. bank->sectors[i].is_protected = 1;
  974. else
  975. bank->sectors[i].is_protected = 0;
  976. }
  977. cfi_command(bank, 0xff, command);
  978. target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
  979. return ERROR_OK;
  980. }
  981. int cfi_protect_check(struct flash_bank_s *bank)
  982. {
  983. cfi_flash_bank_t *cfi_info = bank->driver_priv;
  984. target_t *target = cfi_info->target;
  985. if (cfi_info->qry[0] != 'Q')
  986. return ERROR_FLASH_BANK_NOT_PROBED;
  987. switch(cfi_info->pri_id)
  988. {
  989. case 1:
  990. case 3:
  991. return cfi_intel_protect_check(bank);
  992. break;
  993. default:
  994. ERROR("cfi primary command set %i unsupported", cfi_info->pri_id);
  995. break;
  996. }
  997. return ERROR_OK;
  998. }
  999. int cfi_info(struct flash_bank_s *bank, char *buf, int buf_size)
  1000. {
  1001. int printed;
  1002. cfi_flash_bank_t *cfi_info = bank->driver_priv;
  1003. if (cfi_info->qry[0] == -1)
  1004. {
  1005. printed = snprintf(buf, buf_size, "\ncfi flash bank not probed yet\n");
  1006. return ERROR_OK;
  1007. }
  1008. printed = snprintf(buf, buf_size, "\ncfi information:\n");
  1009. buf += printed;
  1010. buf_size -= printed;
  1011. printed = snprintf(buf, buf_size, "qry: '%c%c%c', pri_id: 0x%4.4x, pri_addr: 0x%4.4x, alt_id: 0x%4.4x, alt_addr: 0x%4.4x\n", cfi_info->qry[0], cfi_info->qry[1], cfi_info->qry[2], cfi_info->pri_id, cfi_info->pri_addr, cfi_info->alt_id, cfi_info->alt_addr);
  1012. buf += printed;
  1013. buf_size -= printed;
  1014. printed = snprintf(buf, buf_size, "Vcc min: %1.1x.%1.1x, Vcc max: %1.1x.%1.1x, Vpp min: %1.1x.%1.1x, Vpp max: %1.1x.%1.1x\n", (cfi_info->vcc_min & 0xf0) >> 4, cfi_info->vcc_min & 0x0f,
  1015. (cfi_info->vcc_max & 0xf0) >> 4, cfi_info->vcc_max & 0x0f,
  1016. (cfi_info->vpp_min & 0xf0) >> 4, cfi_info->vpp_min & 0x0f,
  1017. (cfi_info->vpp_max & 0xf0) >> 4, cfi_info->vpp_max & 0x0f);
  1018. buf += printed;
  1019. buf_size -= printed;
  1020. printed = snprintf(buf, buf_size, "typ. word write timeout: %u, typ. buf write timeout: %u, typ. block erase timeout: %u, typ. chip erase timeout: %u\n", 1 << cfi_info->word_write_timeout_typ, 1 << cfi_info->buf_write_timeout_typ,
  1021. 1 << cfi_info->block_erase_timeout_typ, 1 << cfi_info->chip_erase_timeout_typ);
  1022. buf += printed;
  1023. buf_size -= printed;
  1024. printed = snprintf(buf, buf_size, "max. word write timeout: %u, max. buf write timeout: %u, max. block erase timeout: %u, max. chip erase timeout: %u\n", (1 << cfi_info->word_write_timeout_max) * (1 << cfi_info->word_write_timeout_typ),
  1025. (1 << cfi_info->buf_write_timeout_max) * (1 << cfi_info->buf_write_timeout_typ),
  1026. (1 << cfi_info->block_erase_timeout_max) * (1 << cfi_info->block_erase_timeout_typ),
  1027. (1 << cfi_info->chip_erase_timeout_max) * (1 << cfi_info->chip_erase_timeout_typ));
  1028. buf += printed;
  1029. buf_size -= printed;
  1030. printed = snprintf(buf, buf_size, "size: 0x%x, interface desc: %i, max buffer write size: %x\n", 1 << cfi_info->dev_size, cfi_info->interface_desc, cfi_info->max_buf_write_size);
  1031. buf += printed;
  1032. buf_size -= printed;
  1033. switch(cfi_info->pri_id)
  1034. {
  1035. case 1:
  1036. case 3:
  1037. cfi_intel_info(bank, buf, buf_size);
  1038. break;
  1039. default:
  1040. ERROR("cfi primary command set %i unsupported", cfi_info->pri_id);
  1041. break;
  1042. }
  1043. return ERROR_OK;
  1044. }