spi4ba.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921
  1. /*
  2. * This file is part of the flashrom project.
  3. *
  4. * Copyright (C) 2014 Boris Baykov
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; version 2 of the License.
  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 Free Software
  17. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18. */
  19. /*
  20. * SPI chip driver functions for 4-bytes addressing
  21. */
  22. #include <string.h>
  23. #include "flash.h"
  24. #include "chipdrivers.h"
  25. #include "spi.h"
  26. #include "programmer.h"
  27. #include "spi4ba.h"
  28. /* #define MSG_TRACE_4BA_FUNCS 1 */
  29. #ifdef MSG_TRACE_4BA_FUNCS
  30. #define msg_trace(...) print(MSG_DEBUG, __VA_ARGS__)
  31. #else
  32. #define msg_trace(...)
  33. #endif
  34. /* Enter 4-bytes addressing mode (without sending WREN before) */
  35. int spi_enter_4ba_b7(struct flashctx *flash)
  36. {
  37. const unsigned char cmd[JEDEC_ENTER_4_BYTE_ADDR_MODE_OUTSIZE] = { JEDEC_ENTER_4_BYTE_ADDR_MODE };
  38. msg_trace("-> %s\n", __func__);
  39. /* Switch to 4-bytes addressing mode */
  40. return spi_send_command(flash, sizeof(cmd), 0, cmd, NULL);
  41. }
  42. /* Enter 4-bytes addressing mode with sending WREN before */
  43. int spi_enter_4ba_b7_we(struct flashctx *flash)
  44. {
  45. int result;
  46. struct spi_command cmds[] = {
  47. {
  48. .writecnt = JEDEC_WREN_OUTSIZE,
  49. .writearr = (const unsigned char[]){ JEDEC_WREN },
  50. .readcnt = 0,
  51. .readarr = NULL,
  52. }, {
  53. .writecnt = JEDEC_ENTER_4_BYTE_ADDR_MODE_OUTSIZE,
  54. .writearr = (const unsigned char[]){ JEDEC_ENTER_4_BYTE_ADDR_MODE },
  55. .readcnt = 0,
  56. .readarr = NULL,
  57. }, {
  58. .writecnt = 0,
  59. .writearr = NULL,
  60. .readcnt = 0,
  61. .readarr = NULL,
  62. }};
  63. msg_trace("-> %s\n", __func__);
  64. /* Switch to 4-bytes addressing mode */
  65. result = spi_send_multicommand(flash, cmds);
  66. if (result) {
  67. msg_cerr("%s failed during command execution\n", __func__);
  68. }
  69. return result;
  70. }
  71. /* Program one flash byte from 4-bytes addressing mode */
  72. int spi_byte_program_4ba(struct flashctx *flash, unsigned int addr,
  73. uint8_t databyte)
  74. {
  75. int result;
  76. struct spi_command cmds[] = {
  77. {
  78. .writecnt = JEDEC_WREN_OUTSIZE,
  79. .writearr = (const unsigned char[]){ JEDEC_WREN },
  80. .readcnt = 0,
  81. .readarr = NULL,
  82. }, {
  83. .writecnt = JEDEC_BYTE_PROGRAM_OUTSIZE + 1,
  84. .writearr = (const unsigned char[]){
  85. JEDEC_BYTE_PROGRAM,
  86. (addr >> 24) & 0xff,
  87. (addr >> 16) & 0xff,
  88. (addr >> 8) & 0xff,
  89. (addr & 0xff),
  90. databyte
  91. },
  92. .readcnt = 0,
  93. .readarr = NULL,
  94. }, {
  95. .writecnt = 0,
  96. .writearr = NULL,
  97. .readcnt = 0,
  98. .readarr = NULL,
  99. }};
  100. msg_trace("-> %s (0x%08X)\n", __func__, addr);
  101. result = spi_send_multicommand(flash, cmds);
  102. if (result) {
  103. msg_cerr("%s failed during command execution at address 0x%x\n",
  104. __func__, addr);
  105. }
  106. return result;
  107. }
  108. /* Program flash bytes from 4-bytes addressing mode */
  109. int spi_nbyte_program_4ba(struct flashctx *flash, unsigned int addr,
  110. const uint8_t *bytes, unsigned int len)
  111. {
  112. int result;
  113. unsigned char cmd[(JEDEC_BYTE_PROGRAM_OUTSIZE + 1) - 1 + 256] = {
  114. JEDEC_BYTE_PROGRAM,
  115. (addr >> 24) & 0xff,
  116. (addr >> 16) & 0xff,
  117. (addr >> 8) & 0xff,
  118. (addr >> 0) & 0xff
  119. };
  120. struct spi_command cmds[] = {
  121. {
  122. .writecnt = JEDEC_WREN_OUTSIZE,
  123. .writearr = (const unsigned char[]){ JEDEC_WREN },
  124. .readcnt = 0,
  125. .readarr = NULL,
  126. }, {
  127. .writecnt = (JEDEC_BYTE_PROGRAM_OUTSIZE + 1) - 1 + len,
  128. .writearr = cmd,
  129. .readcnt = 0,
  130. .readarr = NULL,
  131. }, {
  132. .writecnt = 0,
  133. .writearr = NULL,
  134. .readcnt = 0,
  135. .readarr = NULL,
  136. }};
  137. msg_trace("-> %s (0x%08X-0x%08X)\n", __func__, addr, addr + len - 1);
  138. if (!len) {
  139. msg_cerr("%s called for zero-length write\n", __func__);
  140. return 1;
  141. }
  142. if (len > 256) {
  143. msg_cerr("%s called for too long a write\n", __func__);
  144. return 1;
  145. }
  146. memcpy(&cmd[(JEDEC_BYTE_PROGRAM_OUTSIZE + 1) - 1], bytes, len);
  147. result = spi_send_multicommand(flash, cmds);
  148. if (result) {
  149. msg_cerr("%s failed during command execution at address 0x%x\n",
  150. __func__, addr);
  151. }
  152. return result;
  153. }
  154. /* Read flash bytes from 4-bytes addressing mode */
  155. int spi_nbyte_read_4ba(struct flashctx *flash, unsigned int addr,
  156. uint8_t *bytes, unsigned int len)
  157. {
  158. const unsigned char cmd[JEDEC_READ_OUTSIZE + 1] = {
  159. JEDEC_READ,
  160. (addr >> 24) & 0xff,
  161. (addr >> 16) & 0xff,
  162. (addr >> 8) & 0xff,
  163. (addr >> 0) & 0xff
  164. };
  165. msg_trace("-> %s (0x%08X-0x%08X)\n", __func__, addr, addr + len - 1);
  166. /* Send Read */
  167. return spi_send_command(flash, sizeof(cmd), len, cmd, bytes);
  168. }
  169. /* Erases 4 KB of flash from 4-bytes addressing mode */
  170. int spi_block_erase_20_4ba(struct flashctx *flash, unsigned int addr,
  171. unsigned int blocklen)
  172. {
  173. int result;
  174. struct spi_command cmds[] = {
  175. {
  176. .writecnt = JEDEC_WREN_OUTSIZE,
  177. .writearr = (const unsigned char[]){ JEDEC_WREN },
  178. .readcnt = 0,
  179. .readarr = NULL,
  180. }, {
  181. .writecnt = JEDEC_SE_OUTSIZE + 1,
  182. .writearr = (const unsigned char[]){
  183. JEDEC_SE,
  184. (addr >> 24) & 0xff,
  185. (addr >> 16) & 0xff,
  186. (addr >> 8) & 0xff,
  187. (addr & 0xff)
  188. },
  189. .readcnt = 0,
  190. .readarr = NULL,
  191. }, {
  192. .writecnt = 0,
  193. .writearr = NULL,
  194. .readcnt = 0,
  195. .readarr = NULL,
  196. }};
  197. msg_trace("-> %s (0x%08X-0x%08X)\n", __func__, addr, addr + blocklen - 1);
  198. result = spi_send_multicommand(flash, cmds);
  199. if (result) {
  200. msg_cerr("%s failed during command execution at address 0x%x\n",
  201. __func__, addr);
  202. return result;
  203. }
  204. /* Wait until the Write-In-Progress bit is cleared.
  205. * This usually takes 15-800 ms, so wait in 10 ms steps.
  206. */
  207. while (spi_read_status_register(flash) & SPI_SR_WIP)
  208. programmer_delay(10 * 1000);
  209. /* FIXME: Check the status register for errors. */
  210. return 0;
  211. }
  212. /* Erases 32 KB of flash from 4-bytes addressing mode */
  213. int spi_block_erase_52_4ba(struct flashctx *flash, unsigned int addr,
  214. unsigned int blocklen)
  215. {
  216. int result;
  217. struct spi_command cmds[] = {
  218. {
  219. .writecnt = JEDEC_WREN_OUTSIZE,
  220. .writearr = (const unsigned char[]){ JEDEC_WREN },
  221. .readcnt = 0,
  222. .readarr = NULL,
  223. }, {
  224. .writecnt = JEDEC_BE_52_OUTSIZE + 1,
  225. .writearr = (const unsigned char[]){
  226. JEDEC_BE_52,
  227. (addr >> 24) & 0xff,
  228. (addr >> 16) & 0xff,
  229. (addr >> 8) & 0xff,
  230. (addr & 0xff)
  231. },
  232. .readcnt = 0,
  233. .readarr = NULL,
  234. }, {
  235. .writecnt = 0,
  236. .writearr = NULL,
  237. .readcnt = 0,
  238. .readarr = NULL,
  239. }};
  240. msg_trace("-> %s (0x%08X-0x%08X)\n", __func__, addr, addr + blocklen - 1);
  241. result = spi_send_multicommand(flash, cmds);
  242. if (result) {
  243. msg_cerr("%s failed during command execution at address 0x%x\n",
  244. __func__, addr);
  245. return result;
  246. }
  247. /* Wait until the Write-In-Progress bit is cleared.
  248. * This usually takes 100-4000 ms, so wait in 100 ms steps.
  249. */
  250. while (spi_read_status_register(flash) & SPI_SR_WIP)
  251. programmer_delay(100 * 1000);
  252. /* FIXME: Check the status register for errors. */
  253. return 0;
  254. }
  255. /* Erases 64 KB of flash from 4-bytes addressing mode */
  256. int spi_block_erase_d8_4ba(struct flashctx *flash, unsigned int addr,
  257. unsigned int blocklen)
  258. {
  259. int result;
  260. struct spi_command cmds[] = {
  261. {
  262. .writecnt = JEDEC_WREN_OUTSIZE,
  263. .writearr = (const unsigned char[]){ JEDEC_WREN },
  264. .readcnt = 0,
  265. .readarr = NULL,
  266. }, {
  267. .writecnt = JEDEC_BE_D8_OUTSIZE + 1,
  268. .writearr = (const unsigned char[]){
  269. JEDEC_BE_D8,
  270. (addr >> 24) & 0xff,
  271. (addr >> 16) & 0xff,
  272. (addr >> 8) & 0xff,
  273. (addr & 0xff)
  274. },
  275. .readcnt = 0,
  276. .readarr = NULL,
  277. }, {
  278. .writecnt = 0,
  279. .writearr = NULL,
  280. .readcnt = 0,
  281. .readarr = NULL,
  282. }};
  283. msg_trace("-> %s (0x%08X-0x%08X)\n", __func__, addr, addr + blocklen - 1);
  284. result = spi_send_multicommand(flash, cmds);
  285. if (result) {
  286. msg_cerr("%s failed during command execution at address 0x%x\n",
  287. __func__, addr);
  288. return result;
  289. }
  290. /* Wait until the Write-In-Progress bit is cleared.
  291. * This usually takes 100-4000 ms, so wait in 100 ms steps.
  292. */
  293. while (spi_read_status_register(flash) & SPI_SR_WIP)
  294. programmer_delay(100 * 1000);
  295. /* FIXME: Check the status register for errors. */
  296. return 0;
  297. }
  298. /* Write Extended Address Register value */
  299. int spi_write_extended_address_register(struct flashctx *flash, uint8_t regdata)
  300. {
  301. int result;
  302. struct spi_command cmds[] = {
  303. {
  304. .writecnt = JEDEC_WREN_OUTSIZE,
  305. .writearr = (const unsigned char[]){ JEDEC_WREN },
  306. .readcnt = 0,
  307. .readarr = NULL,
  308. }, {
  309. .writecnt = JEDEC_WRITE_EXT_ADDR_REG_OUTSIZE,
  310. .writearr = (const unsigned char[]){
  311. JEDEC_WRITE_EXT_ADDR_REG,
  312. regdata
  313. },
  314. .readcnt = 0,
  315. .readarr = NULL,
  316. }, {
  317. .writecnt = 0,
  318. .writearr = NULL,
  319. .readcnt = 0,
  320. .readarr = NULL,
  321. }};
  322. msg_trace("-> %s (%02X)\n", __func__, regdata);
  323. result = spi_send_multicommand(flash, cmds);
  324. if (result) {
  325. msg_cerr("%s failed during command execution\n", __func__);
  326. return result;
  327. }
  328. return 0;
  329. }
  330. /* Assign required value of Extended Address Register. This function
  331. keeps last value of the register and writes the register if the
  332. value has to be changed only. */
  333. int set_extended_address_register(struct flashctx *flash, uint8_t data)
  334. {
  335. static uint8_t ext_addr_reg_state; /* memory for last register state */
  336. static int ext_addr_reg_state_valid = 0;
  337. int result;
  338. if (ext_addr_reg_state_valid == 0 || data != ext_addr_reg_state) {
  339. result = spi_write_extended_address_register(flash, data);
  340. if (result) {
  341. ext_addr_reg_state_valid = 0;
  342. return result;
  343. }
  344. ext_addr_reg_state = data;
  345. ext_addr_reg_state_valid = 1;
  346. }
  347. return 0;
  348. }
  349. /* Program one flash byte using Extended Address Register
  350. from 3-bytes addressing mode */
  351. int spi_byte_program_4ba_ereg(struct flashctx *flash, unsigned int addr,
  352. uint8_t databyte)
  353. {
  354. int result;
  355. struct spi_command cmds[] = {
  356. {
  357. .writecnt = JEDEC_WREN_OUTSIZE,
  358. .writearr = (const unsigned char[]){ JEDEC_WREN },
  359. .readcnt = 0,
  360. .readarr = NULL,
  361. }, {
  362. .writecnt = JEDEC_BYTE_PROGRAM_OUTSIZE,
  363. .writearr = (const unsigned char[]){
  364. JEDEC_BYTE_PROGRAM,
  365. (addr >> 16) & 0xff,
  366. (addr >> 8) & 0xff,
  367. (addr & 0xff),
  368. databyte
  369. },
  370. .readcnt = 0,
  371. .readarr = NULL,
  372. }, {
  373. .writecnt = 0,
  374. .writearr = NULL,
  375. .readcnt = 0,
  376. .readarr = NULL,
  377. }};
  378. msg_trace("-> %s (0x%08X)\n", __func__, addr);
  379. result = set_extended_address_register(flash, (addr >> 24) & 0xff);
  380. if (result)
  381. return result;
  382. result = spi_send_multicommand(flash, cmds);
  383. if (result) {
  384. msg_cerr("%s failed during command execution at address 0x%x\n",
  385. __func__, addr);
  386. }
  387. return result;
  388. }
  389. /* Program flash bytes using Extended Address Register
  390. from 3-bytes addressing mode */
  391. int spi_nbyte_program_4ba_ereg(struct flashctx *flash, unsigned int addr,
  392. const uint8_t *bytes, unsigned int len)
  393. {
  394. int result;
  395. unsigned char cmd[JEDEC_BYTE_PROGRAM_OUTSIZE - 1 + 256] = {
  396. JEDEC_BYTE_PROGRAM,
  397. (addr >> 16) & 0xff,
  398. (addr >> 8) & 0xff,
  399. (addr >> 0) & 0xff
  400. };
  401. struct spi_command cmds[] = {
  402. {
  403. .writecnt = JEDEC_WREN_OUTSIZE,
  404. .writearr = (const unsigned char[]){ JEDEC_WREN },
  405. .readcnt = 0,
  406. .readarr = NULL,
  407. }, {
  408. .writecnt = JEDEC_BYTE_PROGRAM_OUTSIZE - 1 + len,
  409. .writearr = cmd,
  410. .readcnt = 0,
  411. .readarr = NULL,
  412. }, {
  413. .writecnt = 0,
  414. .writearr = NULL,
  415. .readcnt = 0,
  416. .readarr = NULL,
  417. }};
  418. msg_trace("-> %s (0x%08X-0x%08X)\n", __func__, addr, addr + len - 1);
  419. if (!len) {
  420. msg_cerr("%s called for zero-length write\n", __func__);
  421. return 1;
  422. }
  423. if (len > 256) {
  424. msg_cerr("%s called for too long a write\n", __func__);
  425. return 1;
  426. }
  427. memcpy(&cmd[JEDEC_BYTE_PROGRAM_OUTSIZE - 1], bytes, len);
  428. result = set_extended_address_register(flash, (addr >> 24) & 0xff);
  429. if (result)
  430. return result;
  431. result = spi_send_multicommand(flash, cmds);
  432. if (result) {
  433. msg_cerr("%s failed during command execution at address 0x%x\n",
  434. __func__, addr);
  435. }
  436. return result;
  437. }
  438. /* Read flash bytes using Extended Address Register
  439. from 3-bytes addressing mode */
  440. int spi_nbyte_read_4ba_ereg(struct flashctx *flash, unsigned int addr,
  441. uint8_t *bytes, unsigned int len)
  442. {
  443. int result;
  444. const unsigned char cmd[JEDEC_READ_OUTSIZE] = {
  445. JEDEC_READ,
  446. (addr >> 16) & 0xff,
  447. (addr >> 8) & 0xff,
  448. (addr >> 0) & 0xff
  449. };
  450. msg_trace("-> %s (0x%08X-0x%08X)\n", __func__, addr, addr + len - 1);
  451. result = set_extended_address_register(flash, (addr >> 24) & 0xff);
  452. if (result)
  453. return result;
  454. /* Send Read */
  455. return spi_send_command(flash, sizeof(cmd), len, cmd, bytes);
  456. }
  457. /* Erases 4 KB of flash using Extended Address Register
  458. from 3-bytes addressing mode */
  459. int spi_block_erase_20_4ba_ereg(struct flashctx *flash, unsigned int addr,
  460. unsigned int blocklen)
  461. {
  462. int result;
  463. struct spi_command cmds[] = {
  464. {
  465. .writecnt = JEDEC_WREN_OUTSIZE,
  466. .writearr = (const unsigned char[]){ JEDEC_WREN },
  467. .readcnt = 0,
  468. .readarr = NULL,
  469. }, {
  470. .writecnt = JEDEC_SE_OUTSIZE,
  471. .writearr = (const unsigned char[]){
  472. JEDEC_SE,
  473. (addr >> 16) & 0xff,
  474. (addr >> 8) & 0xff,
  475. (addr & 0xff)
  476. },
  477. .readcnt = 0,
  478. .readarr = NULL,
  479. }, {
  480. .writecnt = 0,
  481. .writearr = NULL,
  482. .readcnt = 0,
  483. .readarr = NULL,
  484. }};
  485. msg_trace("-> %s (0x%08X-0x%08X)\n", __func__, addr, addr + blocklen - 1);
  486. result = set_extended_address_register(flash, (addr >> 24) & 0xff);
  487. if (result)
  488. return result;
  489. result = spi_send_multicommand(flash, cmds);
  490. if (result) {
  491. msg_cerr("%s failed during command execution at address 0x%x\n",
  492. __func__, addr);
  493. return result;
  494. }
  495. /* Wait until the Write-In-Progress bit is cleared.
  496. * This usually takes 15-800 ms, so wait in 10 ms steps.
  497. */
  498. while (spi_read_status_register(flash) & SPI_SR_WIP)
  499. programmer_delay(10 * 1000);
  500. /* FIXME: Check the status register for errors. */
  501. return 0;
  502. }
  503. /* Erases 32 KB of flash using Extended Address Register
  504. from 3-bytes addressing mode */
  505. int spi_block_erase_52_4ba_ereg(struct flashctx *flash, unsigned int addr,
  506. unsigned int blocklen)
  507. {
  508. int result;
  509. struct spi_command cmds[] = {
  510. {
  511. .writecnt = JEDEC_WREN_OUTSIZE,
  512. .writearr = (const unsigned char[]){ JEDEC_WREN },
  513. .readcnt = 0,
  514. .readarr = NULL,
  515. }, {
  516. .writecnt = JEDEC_BE_52_OUTSIZE,
  517. .writearr = (const unsigned char[]){
  518. JEDEC_BE_52,
  519. (addr >> 16) & 0xff,
  520. (addr >> 8) & 0xff,
  521. (addr & 0xff)
  522. },
  523. .readcnt = 0,
  524. .readarr = NULL,
  525. }, {
  526. .writecnt = 0,
  527. .writearr = NULL,
  528. .readcnt = 0,
  529. .readarr = NULL,
  530. }};
  531. msg_trace("-> %s (0x%08X-0x%08X)\n", __func__, addr, addr + blocklen - 1);
  532. result = set_extended_address_register(flash, (addr >> 24) & 0xff);
  533. if (result)
  534. return result;
  535. result = spi_send_multicommand(flash, cmds);
  536. if (result) {
  537. msg_cerr("%s failed during command execution at address 0x%x\n",
  538. __func__, addr);
  539. return result;
  540. }
  541. /* Wait until the Write-In-Progress bit is cleared.
  542. * This usually takes 100-4000 ms, so wait in 100 ms steps.
  543. */
  544. while (spi_read_status_register(flash) & SPI_SR_WIP)
  545. programmer_delay(100 * 1000);
  546. /* FIXME: Check the status register for errors. */
  547. return 0;
  548. }
  549. /* Erases 64 KB of flash using Extended Address Register
  550. from 3-bytes addressing mode */
  551. int spi_block_erase_d8_4ba_ereg(struct flashctx *flash, unsigned int addr,
  552. unsigned int blocklen)
  553. {
  554. int result;
  555. struct spi_command cmds[] = {
  556. {
  557. .writecnt = JEDEC_WREN_OUTSIZE,
  558. .writearr = (const unsigned char[]){ JEDEC_WREN },
  559. .readcnt = 0,
  560. .readarr = NULL,
  561. }, {
  562. .writecnt = JEDEC_BE_D8_OUTSIZE,
  563. .writearr = (const unsigned char[]){
  564. JEDEC_BE_D8,
  565. (addr >> 16) & 0xff,
  566. (addr >> 8) & 0xff,
  567. (addr & 0xff)
  568. },
  569. .readcnt = 0,
  570. .readarr = NULL,
  571. }, {
  572. .writecnt = 0,
  573. .writearr = NULL,
  574. .readcnt = 0,
  575. .readarr = NULL,
  576. }};
  577. msg_trace("-> %s (0x%08X-0x%08X)\n", __func__, addr, addr + blocklen - 1);
  578. result = set_extended_address_register(flash, (addr >> 24) & 0xff);
  579. if (result)
  580. return result;
  581. result = spi_send_multicommand(flash, cmds);
  582. if (result) {
  583. msg_cerr("%s failed during command execution at address 0x%x\n",
  584. __func__, addr);
  585. return result;
  586. }
  587. /* Wait until the Write-In-Progress bit is cleared.
  588. * This usually takes 100-4000 ms, so wait in 100 ms steps.
  589. */
  590. while (spi_read_status_register(flash) & SPI_SR_WIP)
  591. programmer_delay(100 * 1000);
  592. /* FIXME: Check the status register for errors. */
  593. return 0;
  594. }
  595. /* Program one flash byte with 4-bytes address from ANY mode (3-bytes or 4-bytes)
  596. JEDEC_BYTE_PROGRAM_4BA (12h) instruction is new for 4-bytes addressing flash chips.
  597. The presence of this instruction for an exact chip should be checked
  598. by its datasheet or from SFDP 4-Bytes Address Instruction Table (JESD216B). */
  599. int spi_byte_program_4ba_direct(struct flashctx *flash, unsigned int addr,
  600. uint8_t databyte)
  601. {
  602. int result;
  603. struct spi_command cmds[] = {
  604. {
  605. .writecnt = JEDEC_WREN_OUTSIZE,
  606. .writearr = (const unsigned char[]){ JEDEC_WREN },
  607. .readcnt = 0,
  608. .readarr = NULL,
  609. }, {
  610. .writecnt = JEDEC_BYTE_PROGRAM_4BA_OUTSIZE,
  611. .writearr = (const unsigned char[]){
  612. JEDEC_BYTE_PROGRAM_4BA,
  613. (addr >> 24) & 0xff,
  614. (addr >> 16) & 0xff,
  615. (addr >> 8) & 0xff,
  616. (addr & 0xff),
  617. databyte
  618. },
  619. .readcnt = 0,
  620. .readarr = NULL,
  621. }, {
  622. .writecnt = 0,
  623. .writearr = NULL,
  624. .readcnt = 0,
  625. .readarr = NULL,
  626. }};
  627. msg_trace("-> %s (0x%08X)\n", __func__, addr);
  628. result = spi_send_multicommand(flash, cmds);
  629. if (result) {
  630. msg_cerr("%s failed during command execution at address 0x%x\n",
  631. __func__, addr);
  632. }
  633. return result;
  634. }
  635. /* Program flash bytes with 4-bytes address from ANY mode (3-bytes or 4-bytes)
  636. JEDEC_BYTE_PROGRAM_4BA (12h) instruction is new for 4-bytes addressing flash chips.
  637. The presence of this instruction for an exact chip should be checked
  638. by its datasheet or from SFDP 4-Bytes Address Instruction Table (JESD216B). */
  639. int spi_nbyte_program_4ba_direct(struct flashctx *flash, unsigned int addr,
  640. const uint8_t *bytes, unsigned int len)
  641. {
  642. int result;
  643. unsigned char cmd[JEDEC_BYTE_PROGRAM_4BA_OUTSIZE - 1 + 256] = {
  644. JEDEC_BYTE_PROGRAM_4BA,
  645. (addr >> 24) & 0xff,
  646. (addr >> 16) & 0xff,
  647. (addr >> 8) & 0xff,
  648. (addr >> 0) & 0xff
  649. };
  650. struct spi_command cmds[] = {
  651. {
  652. .writecnt = JEDEC_WREN_OUTSIZE,
  653. .writearr = (const unsigned char[]){ JEDEC_WREN },
  654. .readcnt = 0,
  655. .readarr = NULL,
  656. }, {
  657. .writecnt = JEDEC_BYTE_PROGRAM_4BA_OUTSIZE - 1 + len,
  658. .writearr = cmd,
  659. .readcnt = 0,
  660. .readarr = NULL,
  661. }, {
  662. .writecnt = 0,
  663. .writearr = NULL,
  664. .readcnt = 0,
  665. .readarr = NULL,
  666. }};
  667. msg_trace("-> %s (0x%08X-0x%08X)\n", __func__, addr, addr + len - 1);
  668. if (!len) {
  669. msg_cerr("%s called for zero-length write\n", __func__);
  670. return 1;
  671. }
  672. if (len > 256) {
  673. msg_cerr("%s called for too long a write\n", __func__);
  674. return 1;
  675. }
  676. memcpy(&cmd[JEDEC_BYTE_PROGRAM_4BA_OUTSIZE - 1], bytes, len);
  677. result = spi_send_multicommand(flash, cmds);
  678. if (result) {
  679. msg_cerr("%s failed during command execution at address 0x%x\n",
  680. __func__, addr);
  681. }
  682. return result;
  683. }
  684. /* Read flash bytes with 4-bytes address from ANY mode (3-bytes or 4-bytes)
  685. JEDEC_READ_4BA (13h) instruction is new for 4-bytes addressing flash chips.
  686. The presence of this instruction for an exact chip should be checked
  687. by its datasheet or from SFDP 4-Bytes Address Instruction Table (JESD216B). */
  688. int spi_nbyte_read_4ba_direct(struct flashctx *flash, unsigned int addr,
  689. uint8_t *bytes, unsigned int len)
  690. {
  691. const unsigned char cmd[JEDEC_READ_4BA_OUTSIZE] = {
  692. JEDEC_READ_4BA,
  693. (addr >> 24) & 0xff,
  694. (addr >> 16) & 0xff,
  695. (addr >> 8) & 0xff,
  696. (addr >> 0) & 0xff
  697. };
  698. msg_trace("-> %s (0x%08X-0x%08X)\n", __func__, addr, addr + len - 1);
  699. /* Send Read */
  700. return spi_send_command(flash, sizeof(cmd), len, cmd, bytes);
  701. }
  702. /* Erase 4 KB of flash with 4-bytes address from ANY mode (3-bytes or 4-bytes)
  703. JEDEC_SE_4BA (21h) instruction is new for 4-bytes addressing flash chips.
  704. The presence of this instruction for an exact chip should be checked
  705. by its datasheet or from SFDP 4-Bytes Address Instruction Table (JESD216B). */
  706. int spi_block_erase_21_4ba_direct(struct flashctx *flash, unsigned int addr,
  707. unsigned int blocklen)
  708. {
  709. int result;
  710. struct spi_command cmds[] = {
  711. {
  712. .writecnt = JEDEC_WREN_OUTSIZE,
  713. .writearr = (const unsigned char[]){ JEDEC_WREN },
  714. .readcnt = 0,
  715. .readarr = NULL,
  716. }, {
  717. .writecnt = JEDEC_SE_4BA_OUTSIZE,
  718. .writearr = (const unsigned char[]){
  719. JEDEC_SE_4BA,
  720. (addr >> 24) & 0xff,
  721. (addr >> 16) & 0xff,
  722. (addr >> 8) & 0xff,
  723. (addr & 0xff)
  724. },
  725. .readcnt = 0,
  726. .readarr = NULL,
  727. }, {
  728. .writecnt = 0,
  729. .writearr = NULL,
  730. .readcnt = 0,
  731. .readarr = NULL,
  732. }};
  733. msg_trace("-> %s (0x%08X-0x%08X)\n", __func__, addr, addr + blocklen - 1);
  734. result = spi_send_multicommand(flash, cmds);
  735. if (result) {
  736. msg_cerr("%s failed during command execution at address 0x%x\n",
  737. __func__, addr);
  738. return result;
  739. }
  740. /* Wait until the Write-In-Progress bit is cleared.
  741. * This usually takes 15-800 ms, so wait in 10 ms steps.
  742. */
  743. while (spi_read_status_register(flash) & SPI_SR_WIP)
  744. programmer_delay(10 * 1000);
  745. /* FIXME: Check the status register for errors. */
  746. return 0;
  747. }
  748. /* Erase 32 KB of flash with 4-bytes address from ANY mode (3-bytes or 4-bytes)
  749. JEDEC_BE_5C_4BA (5Ch) instruction is new for 4-bytes addressing flash chips.
  750. The presence of this instruction for an exact chip should be checked
  751. by its datasheet or from SFDP 4-Bytes Address Instruction Table (JESD216B). */
  752. int spi_block_erase_5c_4ba_direct(struct flashctx *flash, unsigned int addr,
  753. unsigned int blocklen)
  754. {
  755. int result;
  756. struct spi_command cmds[] = {
  757. {
  758. .writecnt = JEDEC_WREN_OUTSIZE,
  759. .writearr = (const unsigned char[]){ JEDEC_WREN },
  760. .readcnt = 0,
  761. .readarr = NULL,
  762. }, {
  763. .writecnt = JEDEC_BE_5C_4BA_OUTSIZE,
  764. .writearr = (const unsigned char[]){
  765. JEDEC_BE_5C_4BA,
  766. (addr >> 24) & 0xff,
  767. (addr >> 16) & 0xff,
  768. (addr >> 8) & 0xff,
  769. (addr & 0xff)
  770. },
  771. .readcnt = 0,
  772. .readarr = NULL,
  773. }, {
  774. .writecnt = 0,
  775. .writearr = NULL,
  776. .readcnt = 0,
  777. .readarr = NULL,
  778. }};
  779. msg_trace("-> %s (0x%08X-0x%08X)\n", __func__, addr, addr + blocklen - 1);
  780. result = spi_send_multicommand(flash, cmds);
  781. if (result) {
  782. msg_cerr("%s failed during command execution at address 0x%x\n",
  783. __func__, addr);
  784. return result;
  785. }
  786. /* Wait until the Write-In-Progress bit is cleared.
  787. * This usually takes 100-4000 ms, so wait in 100 ms steps.
  788. */
  789. while (spi_read_status_register(flash) & SPI_SR_WIP)
  790. programmer_delay(100 * 1000);
  791. /* FIXME: Check the status register for errors. */
  792. return 0;
  793. }
  794. /* Erase 64 KB of flash with 4-bytes address from ANY mode (3-bytes or 4-bytes)
  795. JEDEC_BE_DC_4BA (DCh) instruction is new for 4-bytes addressing flash chips.
  796. The presence of this instruction for an exact chip should be checked
  797. by its datasheet or from SFDP 4-Bytes Address Instruction Table (JESD216B). */
  798. int spi_block_erase_dc_4ba_direct(struct flashctx *flash, unsigned int addr,
  799. unsigned int blocklen)
  800. {
  801. int result;
  802. struct spi_command cmds[] = {
  803. {
  804. .writecnt = JEDEC_WREN_OUTSIZE,
  805. .writearr = (const unsigned char[]){ JEDEC_WREN },
  806. .readcnt = 0,
  807. .readarr = NULL,
  808. }, {
  809. .writecnt = JEDEC_BE_DC_4BA_OUTSIZE,
  810. .writearr = (const unsigned char[]){
  811. JEDEC_BE_DC_4BA,
  812. (addr >> 24) & 0xff,
  813. (addr >> 16) & 0xff,
  814. (addr >> 8) & 0xff,
  815. (addr & 0xff)
  816. },
  817. .readcnt = 0,
  818. .readarr = NULL,
  819. }, {
  820. .writecnt = 0,
  821. .writearr = NULL,
  822. .readcnt = 0,
  823. .readarr = NULL,
  824. }};
  825. msg_trace("-> %s (0x%08X-0x%08X)\n", __func__, addr, addr + blocklen - 1);
  826. result = spi_send_multicommand(flash, cmds);
  827. if (result) {
  828. msg_cerr("%s failed during command execution at address 0x%x\n",
  829. __func__, addr);
  830. return result;
  831. }
  832. /* Wait until the Write-In-Progress bit is cleared.
  833. * This usually takes 100-4000 ms, so wait in 100 ms steps.
  834. */
  835. while (spi_read_status_register(flash) & SPI_SR_WIP)
  836. programmer_delay(100 * 1000);
  837. /* FIXME: Check the status register for errors. */
  838. return 0;
  839. }