dummyflasher.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874
  1. /*
  2. * This file is part of the flashrom project.
  3. *
  4. * Copyright (C) 2009,2010 Carl-Daniel Hailfinger
  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. #include <errno.h>
  20. #include <string.h>
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <ctype.h>
  24. #include "flash.h"
  25. #include "chipdrivers.h"
  26. #include "programmer.h"
  27. #include "flashchips.h"
  28. /* Remove the #define below if you don't want SPI flash chip emulation. */
  29. #define EMULATE_SPI_CHIP 1
  30. #if EMULATE_SPI_CHIP
  31. #define EMULATE_CHIP 1
  32. #include "spi.h"
  33. #endif
  34. #if EMULATE_CHIP
  35. #include <sys/types.h>
  36. #include <sys/stat.h>
  37. #if EMULATE_SPI_CHIP
  38. /* The name of variable-size virtual chip. A 4MB flash example:
  39. * flashrom -p dummy:emulate=VARIABLE_SIZE,size=4194304
  40. */
  41. #define VARIABLE_SIZE_CHIP_NAME "VARIABLE_SIZE"
  42. unsigned char spi_blacklist[256];
  43. unsigned char spi_ignorelist[256];
  44. int spi_blacklist_size = 0;
  45. int spi_ignorelist_size = 0;
  46. #endif
  47. #endif
  48. #if EMULATE_CHIP
  49. static uint8_t *flashchip_contents = NULL;
  50. enum emu_chip {
  51. EMULATE_NONE,
  52. EMULATE_ST_M25P10_RES,
  53. EMULATE_SST_SST25VF040_REMS,
  54. EMULATE_SST_SST25VF032B,
  55. EMULATE_VARIABLE_SIZE,
  56. };
  57. static enum emu_chip emu_chip = EMULATE_NONE;
  58. static char *emu_persistent_image = NULL;
  59. static unsigned int emu_chip_size = 0;
  60. static int emu_modified; /* is the image modified since reading it? */
  61. static int erase_to_zero;
  62. #if EMULATE_SPI_CHIP
  63. static unsigned int emu_max_byteprogram_size = 0;
  64. static unsigned int emu_max_aai_size = 0;
  65. static unsigned int emu_jedec_se_size = 0;
  66. static unsigned int emu_jedec_be_52_size = 0;
  67. static unsigned int emu_jedec_be_d8_size = 0;
  68. static unsigned int emu_jedec_ce_60_size = 0;
  69. static unsigned int emu_jedec_ce_c7_size = 0;
  70. #endif
  71. #endif
  72. static unsigned int spi_write_256_chunksize = 256;
  73. /* If "freq" parameter is passed in from command line, commands will delay
  74. * for this period before returning. */
  75. static unsigned long int delay_us = 0;
  76. static int dummy_spi_send_command(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
  77. const unsigned char *writearr, unsigned char *readarr);
  78. static int dummy_spi_write_256(struct flashctx *flash, uint8_t *buf,
  79. unsigned int start, unsigned int len);
  80. static void dummy_chip_writeb(const struct flashctx *flash, uint8_t val,
  81. chipaddr addr);
  82. static void dummy_chip_writew(const struct flashctx *flash, uint16_t val,
  83. chipaddr addr);
  84. static void dummy_chip_writel(const struct flashctx *flash, uint32_t val,
  85. chipaddr addr);
  86. static void dummy_chip_writen(const struct flashctx *flash, uint8_t *buf,
  87. chipaddr addr, size_t len);
  88. static uint8_t dummy_chip_readb(const struct flashctx *flash,
  89. const chipaddr addr);
  90. static uint16_t dummy_chip_readw(const struct flashctx *flash,
  91. const chipaddr addr);
  92. static uint32_t dummy_chip_readl(const struct flashctx *flash,
  93. const chipaddr addr);
  94. static void dummy_chip_readn(const struct flashctx *flash, uint8_t *buf,
  95. const chipaddr addr, size_t len);
  96. static const struct spi_programmer spi_programmer_dummyflasher = {
  97. .type = SPI_CONTROLLER_DUMMY,
  98. .max_data_read = MAX_DATA_READ_UNLIMITED,
  99. .max_data_write = MAX_DATA_UNSPECIFIED,
  100. .command = dummy_spi_send_command,
  101. .multicommand = default_spi_send_multicommand,
  102. .read = default_spi_read,
  103. .write_256 = dummy_spi_write_256,
  104. };
  105. static const struct par_programmer par_programmer_dummy = {
  106. .chip_readb = dummy_chip_readb,
  107. .chip_readw = dummy_chip_readw,
  108. .chip_readl = dummy_chip_readl,
  109. .chip_readn = dummy_chip_readn,
  110. .chip_writeb = dummy_chip_writeb,
  111. .chip_writew = dummy_chip_writew,
  112. .chip_writel = dummy_chip_writel,
  113. .chip_writen = dummy_chip_writen,
  114. };
  115. enum chipbustype dummy_buses_supported = BUS_NONE;
  116. static int dummy_shutdown(void *data)
  117. {
  118. msg_pspew("%s\n", __func__);
  119. #if EMULATE_CHIP
  120. if (emu_chip != EMULATE_NONE) {
  121. if (emu_persistent_image && emu_modified) {
  122. msg_pdbg("Writing %s\n", emu_persistent_image);
  123. write_buf_to_file(flashchip_contents, emu_chip_size,
  124. emu_persistent_image);
  125. }
  126. free(flashchip_contents);
  127. }
  128. #endif
  129. return 0;
  130. }
  131. /* Values for the 'size' parameter */
  132. enum {
  133. SIZE_UNKNOWN = -1,
  134. SIZE_AUTO = -2,
  135. };
  136. int dummy_init(void)
  137. {
  138. char *bustext = NULL;
  139. char *tmp = NULL;
  140. int i;
  141. #if EMULATE_CHIP
  142. struct stat image_stat;
  143. #if EMULATE_SPI_CHIP
  144. int size = SIZE_UNKNOWN; /* size for generic chip */
  145. #endif
  146. #endif
  147. int image_size = SIZE_UNKNOWN;
  148. msg_pspew("%s\n", __func__);
  149. bustext = extract_programmer_param("bus");
  150. msg_pdbg("Requested buses are: %s\n", bustext ? bustext : "default");
  151. if (!bustext)
  152. bustext = strdup("parallel+lpc+fwh+spi");
  153. /* Convert the parameters to lowercase. */
  154. tolower_string(bustext);
  155. dummy_buses_supported = BUS_NONE;
  156. if (strstr(bustext, "parallel")) {
  157. dummy_buses_supported |= BUS_PARALLEL;
  158. msg_pdbg("Enabling support for %s flash.\n", "parallel");
  159. }
  160. if (strstr(bustext, "lpc")) {
  161. dummy_buses_supported |= BUS_LPC;
  162. msg_pdbg("Enabling support for %s flash.\n", "LPC");
  163. }
  164. if (strstr(bustext, "fwh")) {
  165. dummy_buses_supported |= BUS_FWH;
  166. msg_pdbg("Enabling support for %s flash.\n", "FWH");
  167. }
  168. if (strstr(bustext, "spi")) {
  169. dummy_buses_supported |= BUS_SPI;
  170. msg_pdbg("Enabling support for %s flash.\n", "SPI");
  171. }
  172. if (dummy_buses_supported == BUS_NONE)
  173. msg_pdbg("Support for all flash bus types disabled.\n");
  174. free(bustext);
  175. tmp = extract_programmer_param("spi_write_256_chunksize");
  176. if (tmp) {
  177. spi_write_256_chunksize = atoi(tmp);
  178. free(tmp);
  179. if (spi_write_256_chunksize < 1) {
  180. msg_perr("invalid spi_write_256_chunksize\n");
  181. return 1;
  182. }
  183. }
  184. tmp = extract_programmer_param("spi_blacklist");
  185. if (tmp) {
  186. i = strlen(tmp);
  187. if (!strncmp(tmp, "0x", 2)) {
  188. i -= 2;
  189. memmove(tmp, tmp + 2, i + 1);
  190. }
  191. if ((i > 512) || (i % 2)) {
  192. msg_perr("Invalid SPI command blacklist length\n");
  193. free(tmp);
  194. return 1;
  195. }
  196. spi_blacklist_size = i / 2;
  197. for (i = 0; i < spi_blacklist_size * 2; i++) {
  198. if (!isxdigit((unsigned char)tmp[i])) {
  199. msg_perr("Invalid char \"%c\" in SPI command "
  200. "blacklist\n", tmp[i]);
  201. free(tmp);
  202. return 1;
  203. }
  204. }
  205. for (i = 0; i < spi_blacklist_size; i++) {
  206. unsigned int tmp2;
  207. /* SCNx8 is apparently not supported by MSVC (and thus
  208. * MinGW), so work around it with an extra variable
  209. */
  210. sscanf(tmp + i * 2, "%2x", &tmp2);
  211. spi_blacklist[i] = (uint8_t)tmp2;
  212. }
  213. msg_pdbg("SPI blacklist is ");
  214. for (i = 0; i < spi_blacklist_size; i++)
  215. msg_pdbg("%02x ", spi_blacklist[i]);
  216. msg_pdbg(", size %i\n", spi_blacklist_size);
  217. }
  218. free(tmp);
  219. tmp = extract_programmer_param("spi_ignorelist");
  220. if (tmp) {
  221. i = strlen(tmp);
  222. if (!strncmp(tmp, "0x", 2)) {
  223. i -= 2;
  224. memmove(tmp, tmp + 2, i + 1);
  225. }
  226. if ((i > 512) || (i % 2)) {
  227. msg_perr("Invalid SPI command ignorelist length\n");
  228. free(tmp);
  229. return 1;
  230. }
  231. spi_ignorelist_size = i / 2;
  232. for (i = 0; i < spi_ignorelist_size * 2; i++) {
  233. if (!isxdigit((unsigned char)tmp[i])) {
  234. msg_perr("Invalid char \"%c\" in SPI command "
  235. "ignorelist\n", tmp[i]);
  236. free(tmp);
  237. return 1;
  238. }
  239. }
  240. for (i = 0; i < spi_ignorelist_size; i++) {
  241. unsigned int tmp2;
  242. /* SCNx8 is apparently not supported by MSVC (and thus
  243. * MinGW), so work around it with an extra variable
  244. */
  245. sscanf(tmp + i * 2, "%2x", &tmp2);
  246. spi_ignorelist[i] = (uint8_t)tmp2;
  247. }
  248. msg_pdbg("SPI ignorelist is ");
  249. for (i = 0; i < spi_ignorelist_size; i++)
  250. msg_pdbg("%02x ", spi_ignorelist[i]);
  251. msg_pdbg(", size %i\n", spi_ignorelist_size);
  252. }
  253. free(tmp);
  254. /* frequency to emulate in Hz (default), KHz, or MHz */
  255. tmp = extract_programmer_param("freq");
  256. if (tmp) {
  257. unsigned long int freq;
  258. char *units = tmp;
  259. char *end = tmp + strlen(tmp);
  260. errno = 0;
  261. freq = strtoul(tmp, &units, 0);
  262. if (errno) {
  263. msg_perr("Invalid frequency \"%s\", %s\n",
  264. tmp, strerror(errno));
  265. goto dummy_init_out;
  266. }
  267. if ((units > tmp) && (units < end)) {
  268. int units_valid = 0;
  269. if (units < end - 3) {
  270. ;
  271. } else if (units == end - 2) {
  272. if (!strcasecmp(units, "hz"))
  273. units_valid = 1;
  274. } else if (units == end - 3) {
  275. if (!strcasecmp(units, "khz")) {
  276. freq *= 1000;
  277. units_valid = 1;
  278. } else if (!strcasecmp(units, "mhz")) {
  279. freq *= 1000000;
  280. units_valid = 1;
  281. }
  282. }
  283. if (!units_valid) {
  284. msg_perr("Invalid units: %s\n", units);
  285. return 1;
  286. }
  287. }
  288. /* Assume we only work with bytes and transfer at 1 bit/Hz */
  289. delay_us = (1000000 * 8) / freq;
  290. }
  291. #if EMULATE_CHIP
  292. #if EMULATE_SPI_CHIP
  293. tmp = extract_programmer_param("size");
  294. if (tmp) {
  295. int multiplier = 1;
  296. if (!strcmp(tmp, "auto"))
  297. size = SIZE_AUTO;
  298. else if (strlen(tmp)) {
  299. int remove_last_char = 1;
  300. switch (tmp[strlen(tmp) - 1]) {
  301. case 'k': case 'K':
  302. multiplier = 1024;
  303. break;
  304. case 'm': case 'M':
  305. multiplier = 1024 * 1024;
  306. break;
  307. default:
  308. remove_last_char = 0;
  309. break;
  310. }
  311. if (remove_last_char) tmp[strlen(tmp) - 1] = '\0';
  312. size = atoi(tmp) * multiplier;
  313. }
  314. }
  315. #endif
  316. tmp = extract_programmer_param("emulate");
  317. if (!tmp) {
  318. msg_pdbg("Not emulating any flash chip.\n");
  319. /* Nothing else to do. */
  320. goto dummy_init_out;
  321. }
  322. #if EMULATE_SPI_CHIP
  323. if (!strcmp(tmp, "M25P10.RES")) {
  324. emu_chip = EMULATE_ST_M25P10_RES;
  325. emu_chip_size = 128 * 1024;
  326. emu_max_byteprogram_size = 128;
  327. emu_max_aai_size = 0;
  328. emu_jedec_se_size = 0;
  329. emu_jedec_be_52_size = 0;
  330. emu_jedec_be_d8_size = 32 * 1024;
  331. emu_jedec_ce_60_size = 0;
  332. emu_jedec_ce_c7_size = emu_chip_size;
  333. msg_pdbg("Emulating ST M25P10.RES SPI flash chip (RES, page "
  334. "write)\n");
  335. }
  336. if (!strcmp(tmp, "SST25VF040.REMS")) {
  337. emu_chip = EMULATE_SST_SST25VF040_REMS;
  338. emu_chip_size = 512 * 1024;
  339. emu_max_byteprogram_size = 1;
  340. emu_max_aai_size = 0;
  341. emu_jedec_se_size = 4 * 1024;
  342. emu_jedec_be_52_size = 32 * 1024;
  343. emu_jedec_be_d8_size = 0;
  344. emu_jedec_ce_60_size = emu_chip_size;
  345. emu_jedec_ce_c7_size = 0;
  346. msg_pdbg("Emulating SST SST25VF040.REMS SPI flash chip (REMS, "
  347. "byte write)\n");
  348. }
  349. if (!strcmp(tmp, "SST25VF032B")) {
  350. emu_chip = EMULATE_SST_SST25VF032B;
  351. emu_chip_size = 4 * 1024 * 1024;
  352. emu_max_byteprogram_size = 1;
  353. emu_max_aai_size = 2;
  354. emu_jedec_se_size = 4 * 1024;
  355. emu_jedec_be_52_size = 32 * 1024;
  356. emu_jedec_be_d8_size = 64 * 1024;
  357. emu_jedec_ce_60_size = emu_chip_size;
  358. emu_jedec_ce_c7_size = emu_chip_size;
  359. msg_pdbg("Emulating SST SST25VF032B SPI flash chip (RDID, AAI "
  360. "write)\n");
  361. }
  362. emu_persistent_image = extract_programmer_param("image");
  363. if (!stat(emu_persistent_image, &image_stat))
  364. image_size = image_stat.st_size;
  365. if (!strncmp(tmp, VARIABLE_SIZE_CHIP_NAME,
  366. strlen(VARIABLE_SIZE_CHIP_NAME))) {
  367. if (size == SIZE_UNKNOWN) {
  368. msg_perr("%s: the size parameter is not given.\n",
  369. __func__);
  370. free(tmp);
  371. return 1;
  372. } else if (size == SIZE_AUTO) {
  373. if (image_size == SIZE_UNKNOWN) {
  374. msg_perr("%s: no image so cannot use automatic size.\n",
  375. __func__);
  376. free(tmp);
  377. return 1;
  378. }
  379. size = image_size;
  380. }
  381. emu_chip = EMULATE_VARIABLE_SIZE;
  382. emu_chip_size = size;
  383. emu_max_byteprogram_size = 256;
  384. emu_max_aai_size = 0;
  385. emu_jedec_se_size = 4 * 1024;
  386. emu_jedec_be_52_size = 32 * 1024;
  387. emu_jedec_be_d8_size = 64 * 1024;
  388. emu_jedec_ce_60_size = emu_chip_size;
  389. emu_jedec_ce_c7_size = emu_chip_size;
  390. msg_pdbg("Emulating generic SPI flash chip (size=%d bytes)\n",
  391. emu_chip_size);
  392. }
  393. #endif
  394. if (emu_chip == EMULATE_NONE) {
  395. msg_perr("Invalid chip specified for emulation: %s\n", tmp);
  396. free(tmp);
  397. return 1;
  398. }
  399. /* Should emulated flash erase to zero (yes/no)? */
  400. tmp = extract_programmer_param("erase_to_zero");
  401. if (tmp) {
  402. if (!strcmp(tmp, "yes")) {
  403. msg_pdbg("Emulated chip will erase to 0x00\n");
  404. erase_to_zero = 1;
  405. } else if (!strcmp(tmp, "no")) {
  406. msg_pdbg("Emulated chip will erase to 0xff\n");
  407. } else {
  408. msg_perr("erase_to_zero can be \"yes\" or \"no\"\n");
  409. return 1;
  410. }
  411. }
  412. free(tmp);
  413. flashchip_contents = malloc(emu_chip_size);
  414. if (!flashchip_contents) {
  415. msg_perr("Out of memory!\n");
  416. return 1;
  417. }
  418. msg_pdbg("Filling fake flash chip with 0x%02x, size %i\n",
  419. erase_to_zero ? 0x00 : 0xff, emu_chip_size);
  420. memset(flashchip_contents, erase_to_zero ? 0x00 : 0xff, emu_chip_size);
  421. if (!emu_persistent_image) {
  422. /* Nothing else to do. */
  423. goto dummy_init_out;
  424. }
  425. if (!stat(emu_persistent_image, &image_stat)) {
  426. msg_pdbg("Found persistent image %s, size %li ",
  427. emu_persistent_image, (long)image_stat.st_size);
  428. if (image_stat.st_size == emu_chip_size) {
  429. msg_pdbg("matches.\n");
  430. msg_pdbg("Reading %s\n", emu_persistent_image);
  431. read_buf_from_file(flashchip_contents, emu_chip_size,
  432. emu_persistent_image);
  433. } else {
  434. msg_pdbg("doesn't match.\n");
  435. }
  436. }
  437. #endif
  438. dummy_init_out:
  439. if (register_shutdown(dummy_shutdown, NULL)) {
  440. free(flashchip_contents);
  441. return 1;
  442. }
  443. if (dummy_buses_supported & (BUS_PARALLEL | BUS_LPC | BUS_FWH))
  444. register_par_programmer(&par_programmer_dummy,
  445. dummy_buses_supported &
  446. (BUS_PARALLEL | BUS_LPC |
  447. BUS_FWH));
  448. if (dummy_buses_supported & BUS_SPI)
  449. register_spi_programmer(&spi_programmer_dummyflasher);
  450. return 0;
  451. }
  452. void *dummy_map(const char *descr, unsigned long phys_addr, size_t len)
  453. {
  454. msg_pspew("%s: Mapping %s, 0x%lx bytes at 0x%08lx\n",
  455. __func__, descr, (unsigned long)len, phys_addr);
  456. return (void *)phys_addr;
  457. }
  458. void dummy_unmap(void *virt_addr, size_t len)
  459. {
  460. msg_pspew("%s: Unmapping 0x%lx bytes at %p\n",
  461. __func__, (unsigned long)len, virt_addr);
  462. }
  463. void dummy_chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
  464. {
  465. msg_pspew("%s: addr=0x%lx, val=0x%02x\n", __func__, addr, val);
  466. }
  467. void dummy_chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr)
  468. {
  469. msg_pspew("%s: addr=0x%lx, val=0x%04x\n", __func__, addr, val);
  470. }
  471. void dummy_chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr)
  472. {
  473. msg_pspew("%s: addr=0x%lx, val=0x%08x\n", __func__, addr, val);
  474. }
  475. void dummy_chip_writen(const struct flashctx *flash, uint8_t *buf, chipaddr addr, size_t len)
  476. {
  477. size_t i;
  478. msg_pspew("%s: addr=0x%lx, len=0x%08lx, writing data (hex):",
  479. __func__, addr, (unsigned long)len);
  480. for (i = 0; i < len; i++) {
  481. if ((i % 16) == 0)
  482. msg_pspew("\n");
  483. msg_pspew("%02x ", buf[i]);
  484. }
  485. }
  486. uint8_t dummy_chip_readb(const struct flashctx *flash, const chipaddr addr)
  487. {
  488. msg_pspew("%s: addr=0x%lx, returning 0xff\n", __func__, addr);
  489. return 0xff;
  490. }
  491. uint16_t dummy_chip_readw(const struct flashctx *flash, const chipaddr addr)
  492. {
  493. msg_pspew("%s: addr=0x%lx, returning 0xffff\n", __func__, addr);
  494. return 0xffff;
  495. }
  496. uint32_t dummy_chip_readl(const struct flashctx *flash, const chipaddr addr)
  497. {
  498. msg_pspew("%s: addr=0x%lx, returning 0xffffffff\n", __func__, addr);
  499. return 0xffffffff;
  500. }
  501. void dummy_chip_readn(const struct flashctx *flash, uint8_t *buf, const chipaddr addr, size_t len)
  502. {
  503. msg_pspew("%s: addr=0x%lx, len=0x%lx, returning array of 0xff\n",
  504. __func__, addr, (unsigned long)len);
  505. memset(buf, 0xff, len);
  506. return;
  507. }
  508. #if EMULATE_SPI_CHIP
  509. static int emulate_spi_chip_response(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
  510. const unsigned char *writearr, unsigned char *readarr)
  511. {
  512. unsigned int offs, i;
  513. static int unsigned aai_offs;
  514. static int aai_active = 0;
  515. if (writecnt == 0) {
  516. msg_perr("No command sent to the chip!\n");
  517. return 1;
  518. }
  519. /* spi_blacklist has precedence over spi_ignorelist. */
  520. for (i = 0; i < spi_blacklist_size; i++) {
  521. if (writearr[0] == spi_blacklist[i]) {
  522. msg_pdbg("Refusing blacklisted SPI command 0x%02x\n",
  523. spi_blacklist[i]);
  524. return SPI_INVALID_OPCODE;
  525. }
  526. }
  527. for (i = 0; i < spi_ignorelist_size; i++) {
  528. if (writearr[0] == spi_ignorelist[i]) {
  529. msg_cdbg("Ignoring ignorelisted SPI command 0x%02x\n",
  530. spi_ignorelist[i]);
  531. /* Return success because the command does not fail,
  532. * it is simply ignored.
  533. */
  534. return 0;
  535. }
  536. }
  537. switch (writearr[0]) {
  538. case JEDEC_RES:
  539. if (emu_chip != EMULATE_ST_M25P10_RES)
  540. break;
  541. /* Respond with ST_M25P10_RES. */
  542. if (readcnt > 0)
  543. readarr[0] = 0x10;
  544. break;
  545. case JEDEC_REMS:
  546. if (emu_chip != EMULATE_SST_SST25VF040_REMS)
  547. break;
  548. /* Respond with SST_SST25VF040_REMS. */
  549. if (readcnt > 0)
  550. readarr[0] = 0xbf;
  551. if (readcnt > 1)
  552. readarr[1] = 0x44;
  553. break;
  554. case JEDEC_RDID:
  555. if (emu_chip == EMULATE_SST_SST25VF032B) {
  556. /* Respond with SST_SST25VF032B. */
  557. if (readcnt > 0)
  558. readarr[0] = 0xbf;
  559. if (readcnt > 1)
  560. readarr[1] = 0x25;
  561. if (readcnt > 2)
  562. readarr[2] = 0x4a;
  563. } else if (emu_chip == EMULATE_VARIABLE_SIZE) {
  564. const uint16_t man_id = VARIABLE_SIZE_MANUF_ID;
  565. const uint16_t dev_id = VARIABLE_SIZE_DEVICE_ID;
  566. if (readcnt > 0) readarr[0] = man_id >> 8;
  567. if (readcnt > 1) readarr[1] = man_id & 0xff;
  568. if (readcnt > 2) readarr[2] = dev_id >> 8;
  569. if (readcnt > 3) readarr[3] = dev_id & 0xff;
  570. }
  571. break;
  572. case JEDEC_RDSR:
  573. memset(readarr, 0, readcnt);
  574. if (aai_active)
  575. memset(readarr, 1 << 6, readcnt);
  576. break;
  577. case JEDEC_READ:
  578. offs = writearr[1] << 16 | writearr[2] << 8 | writearr[3];
  579. /* Truncate to emu_chip_size. */
  580. offs %= emu_chip_size;
  581. if (readcnt > 0)
  582. memcpy(readarr, flashchip_contents + offs, readcnt);
  583. break;
  584. case JEDEC_BYTE_PROGRAM:
  585. offs = writearr[1] << 16 | writearr[2] << 8 | writearr[3];
  586. /* Truncate to emu_chip_size. */
  587. offs %= emu_chip_size;
  588. if (writecnt < 5) {
  589. msg_perr("BYTE PROGRAM size too short!\n");
  590. return 1;
  591. }
  592. if (writecnt - 4 > emu_max_byteprogram_size) {
  593. msg_perr("Max BYTE PROGRAM size exceeded!\n");
  594. return 1;
  595. }
  596. memcpy(flashchip_contents + offs, writearr + 4, writecnt - 4);
  597. emu_modified = 1;
  598. break;
  599. case JEDEC_AAI_WORD_PROGRAM:
  600. if (!emu_max_aai_size)
  601. break;
  602. if (!aai_active) {
  603. if (writecnt < JEDEC_AAI_WORD_PROGRAM_OUTSIZE) {
  604. msg_perr("Initial AAI WORD PROGRAM size too "
  605. "short!\n");
  606. return 1;
  607. }
  608. if (writecnt > JEDEC_AAI_WORD_PROGRAM_OUTSIZE) {
  609. msg_perr("Initial AAI WORD PROGRAM size too "
  610. "long!\n");
  611. return 1;
  612. }
  613. aai_active = 1;
  614. aai_offs = writearr[1] << 16 | writearr[2] << 8 |
  615. writearr[3];
  616. /* Truncate to emu_chip_size. */
  617. aai_offs %= emu_chip_size;
  618. memcpy(flashchip_contents + aai_offs, writearr + 4, 2);
  619. aai_offs += 2;
  620. } else {
  621. if (writecnt < JEDEC_AAI_WORD_PROGRAM_CONT_OUTSIZE) {
  622. msg_perr("Continuation AAI WORD PROGRAM size "
  623. "too short!\n");
  624. return 1;
  625. }
  626. if (writecnt > JEDEC_AAI_WORD_PROGRAM_CONT_OUTSIZE) {
  627. msg_perr("Continuation AAI WORD PROGRAM size "
  628. "too long!\n");
  629. return 1;
  630. }
  631. memcpy(flashchip_contents + aai_offs, writearr + 1, 2);
  632. aai_offs += 2;
  633. }
  634. emu_modified = 1;
  635. break;
  636. case JEDEC_WRDI:
  637. if (!emu_max_aai_size)
  638. break;
  639. aai_active = 0;
  640. break;
  641. case JEDEC_SE:
  642. if (!emu_jedec_se_size)
  643. break;
  644. if (writecnt != JEDEC_SE_OUTSIZE) {
  645. msg_perr("SECTOR ERASE 0x20 outsize invalid!\n");
  646. return 1;
  647. }
  648. if (readcnt != JEDEC_SE_INSIZE) {
  649. msg_perr("SECTOR ERASE 0x20 insize invalid!\n");
  650. return 1;
  651. }
  652. offs = writearr[1] << 16 | writearr[2] << 8 | writearr[3];
  653. if (offs & (emu_jedec_se_size - 1))
  654. msg_pdbg("Unaligned SECTOR ERASE 0x20: 0x%x\n", offs);
  655. offs &= ~(emu_jedec_se_size - 1);
  656. memset(flashchip_contents + offs, 0xff, emu_jedec_se_size);
  657. emu_modified = 1;
  658. break;
  659. case JEDEC_BE_52:
  660. if (!emu_jedec_be_52_size)
  661. break;
  662. if (writecnt != JEDEC_BE_52_OUTSIZE) {
  663. msg_perr("BLOCK ERASE 0x52 outsize invalid!\n");
  664. return 1;
  665. }
  666. if (readcnt != JEDEC_BE_52_INSIZE) {
  667. msg_perr("BLOCK ERASE 0x52 insize invalid!\n");
  668. return 1;
  669. }
  670. offs = writearr[1] << 16 | writearr[2] << 8 | writearr[3];
  671. if (offs & (emu_jedec_be_52_size - 1))
  672. msg_pdbg("Unaligned BLOCK ERASE 0x52: 0x%x\n", offs);
  673. offs &= ~(emu_jedec_be_52_size - 1);
  674. memset(flashchip_contents + offs, 0xff, emu_jedec_be_52_size);
  675. emu_modified = 1;
  676. break;
  677. case JEDEC_BE_D8:
  678. if (!emu_jedec_be_d8_size)
  679. break;
  680. if (writecnt != JEDEC_BE_D8_OUTSIZE) {
  681. msg_perr("BLOCK ERASE 0xd8 outsize invalid!\n");
  682. return 1;
  683. }
  684. if (readcnt != JEDEC_BE_D8_INSIZE) {
  685. msg_perr("BLOCK ERASE 0xd8 insize invalid!\n");
  686. return 1;
  687. }
  688. offs = writearr[1] << 16 | writearr[2] << 8 | writearr[3];
  689. if (offs & (emu_jedec_be_d8_size - 1))
  690. msg_pdbg("Unaligned BLOCK ERASE 0xd8: 0x%x\n", offs);
  691. offs &= ~(emu_jedec_be_d8_size - 1);
  692. memset(flashchip_contents + offs, 0xff, emu_jedec_be_d8_size);
  693. break;
  694. case JEDEC_CE_60:
  695. if (!emu_jedec_ce_60_size)
  696. break;
  697. if (writecnt != JEDEC_CE_60_OUTSIZE) {
  698. msg_perr("CHIP ERASE 0x60 outsize invalid!\n");
  699. return 1;
  700. }
  701. if (readcnt != JEDEC_CE_60_INSIZE) {
  702. msg_perr("CHIP ERASE 0x60 insize invalid!\n");
  703. return 1;
  704. }
  705. /* JEDEC_CE_60_OUTSIZE is 1 (no address) -> no offset. */
  706. /* emu_jedec_ce_60_size is emu_chip_size. */
  707. memset(flashchip_contents, 0xff, emu_jedec_ce_60_size);
  708. emu_modified = 1;
  709. break;
  710. case JEDEC_CE_C7:
  711. if (!emu_jedec_ce_c7_size)
  712. break;
  713. if (writecnt != JEDEC_CE_C7_OUTSIZE) {
  714. msg_perr("CHIP ERASE 0xc7 outsize invalid!\n");
  715. return 1;
  716. }
  717. if (readcnt != JEDEC_CE_C7_INSIZE) {
  718. msg_perr("CHIP ERASE 0xc7 insize invalid!\n");
  719. return 1;
  720. }
  721. /* JEDEC_CE_C7_OUTSIZE is 1 (no address) -> no offset. */
  722. /* emu_jedec_ce_c7_size is emu_chip_size. */
  723. memset(flashchip_contents, 0xff, emu_jedec_ce_c7_size);
  724. emu_modified = 1;
  725. break;
  726. default:
  727. /* No special response. */
  728. break;
  729. }
  730. return 0;
  731. }
  732. #endif
  733. static int dummy_spi_send_command(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
  734. const unsigned char *writearr, unsigned char *readarr)
  735. {
  736. int i;
  737. msg_pspew("%s:", __func__);
  738. msg_pspew(" writing %u bytes:", writecnt);
  739. for (i = 0; i < writecnt; i++)
  740. msg_pspew(" 0x%02x", writearr[i]);
  741. /* Response for unknown commands and missing chip is 0xff. */
  742. memset(readarr, 0xff, readcnt);
  743. #if EMULATE_SPI_CHIP
  744. switch (emu_chip) {
  745. case EMULATE_ST_M25P10_RES:
  746. case EMULATE_SST_SST25VF040_REMS:
  747. case EMULATE_SST_SST25VF032B:
  748. case EMULATE_VARIABLE_SIZE:
  749. if (emulate_spi_chip_response(flash, writecnt, readcnt, writearr,
  750. readarr)) {
  751. msg_pdbg("Invalid command sent to flash chip!\n");
  752. return 1;
  753. }
  754. break;
  755. default:
  756. break;
  757. }
  758. #endif
  759. msg_pspew(" reading %u bytes:", readcnt);
  760. for (i = 0; i < readcnt; i++)
  761. msg_pspew(" 0x%02x", readarr[i]);
  762. msg_pspew("\n");
  763. programmer_delay((writecnt + readcnt) * delay_us);
  764. return 0;
  765. }
  766. static int dummy_spi_write_256(struct flashctx *flash, uint8_t *buf,
  767. unsigned int start, unsigned int len)
  768. {
  769. return spi_write_chunked(flash, buf, start, len,
  770. spi_write_256_chunksize);
  771. }
  772. #if EMULATE_CHIP && EMULATE_SPI_CHIP
  773. int probe_variable_size(struct flashctx *flash)
  774. {
  775. int i;
  776. /* Skip the probing if we don't emulate this chip. */
  777. if (emu_chip != EMULATE_VARIABLE_SIZE)
  778. return 0;
  779. /*
  780. * This will break if one day flashctx becomes read-only.
  781. * Once that happens, we need to have special hacks in functions:
  782. *
  783. * erase_and_write_flash() in flashrom.c
  784. * read_flash_to_file()
  785. * handle_romentries()
  786. * ...
  787. *
  788. * Search "total_size * 1024" in code.
  789. */
  790. if (emu_chip_size % 1024)
  791. msg_perr("%s: emu_chip_size is not multipler of 1024.\n",
  792. __func__);
  793. flash->total_size = emu_chip_size / 1024;
  794. msg_cdbg("%s: set flash->total_size to %dK bytes.\n", __func__,
  795. flash->total_size);
  796. if (erase_to_zero)
  797. flash->feature_bits |= FEATURE_ERASE_TO_ZERO;
  798. /* Update eraser count */
  799. for (i = 0; i < NUM_ERASEFUNCTIONS; i++) {
  800. struct block_eraser *eraser = &flash->block_erasers[i];
  801. if (eraser->block_erase == NULL)
  802. break;
  803. eraser->eraseblocks[0].count = emu_chip_size /
  804. eraser->eraseblocks[0].size;
  805. msg_cdbg("%s: eraser.size=%d, .count=%d\n",
  806. __func__, eraser->eraseblocks[0].size,
  807. eraser->eraseblocks[0].count);
  808. }
  809. return 1;
  810. }
  811. #endif