pflash_cfi02.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787
  1. /*
  2. * CFI parallel flash with AMD command set emulation
  3. *
  4. * Copyright (c) 2005 Jocelyn Mayer
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  18. */
  19. /*
  20. * For now, this code can emulate flashes of 1, 2 or 4 bytes width.
  21. * Supported commands/modes are:
  22. * - flash read
  23. * - flash write
  24. * - flash ID read
  25. * - sector erase
  26. * - chip erase
  27. * - unlock bypass command
  28. * - CFI queries
  29. *
  30. * It does not support flash interleaving.
  31. * It does not implement boot blocs with reduced size
  32. * It does not implement software data protection as found in many real chips
  33. * It does not implement erase suspend/resume commands
  34. * It does not implement multiple sectors erase
  35. */
  36. #include "hw.h"
  37. #include "flash.h"
  38. #include "qemu/timer.h"
  39. #include "block/block.h"
  40. #include "exec/address-spaces.h"
  41. #include "qemu/host-utils.h"
  42. #include "sysbus.h"
  43. //#define PFLASH_DEBUG
  44. #ifdef PFLASH_DEBUG
  45. #define DPRINTF(fmt, ...) \
  46. do { \
  47. fprintf(stderr "PFLASH: " fmt , ## __VA_ARGS__); \
  48. } while (0)
  49. #else
  50. #define DPRINTF(fmt, ...) do { } while (0)
  51. #endif
  52. #define PFLASH_LAZY_ROMD_THRESHOLD 42
  53. struct pflash_t {
  54. SysBusDevice busdev;
  55. BlockDriverState *bs;
  56. uint32_t sector_len;
  57. uint32_t nb_blocs;
  58. uint32_t chip_len;
  59. uint8_t mappings;
  60. uint8_t width;
  61. uint8_t be;
  62. int wcycle; /* if 0, the flash is read normally */
  63. int bypass;
  64. int ro;
  65. uint8_t cmd;
  66. uint8_t status;
  67. /* FIXME: implement array device properties */
  68. uint16_t ident0;
  69. uint16_t ident1;
  70. uint16_t ident2;
  71. uint16_t ident3;
  72. uint16_t unlock_addr0;
  73. uint16_t unlock_addr1;
  74. uint8_t cfi_len;
  75. uint8_t cfi_table[0x52];
  76. QEMUTimer *timer;
  77. /* The device replicates the flash memory across its memory space. Emulate
  78. * that by having a container (.mem) filled with an array of aliases
  79. * (.mem_mappings) pointing to the flash memory (.orig_mem).
  80. */
  81. MemoryRegion mem;
  82. MemoryRegion *mem_mappings; /* array; one per mapping */
  83. MemoryRegion orig_mem;
  84. int rom_mode;
  85. int read_counter; /* used for lazy switch-back to rom mode */
  86. char *name;
  87. void *storage;
  88. };
  89. /*
  90. * Set up replicated mappings of the same region.
  91. */
  92. static void pflash_setup_mappings(pflash_t *pfl)
  93. {
  94. unsigned i;
  95. hwaddr size = memory_region_size(&pfl->orig_mem);
  96. memory_region_init(&pfl->mem, "pflash", pfl->mappings * size);
  97. pfl->mem_mappings = g_new(MemoryRegion, pfl->mappings);
  98. for (i = 0; i < pfl->mappings; ++i) {
  99. memory_region_init_alias(&pfl->mem_mappings[i], "pflash-alias",
  100. &pfl->orig_mem, 0, size);
  101. memory_region_add_subregion(&pfl->mem, i * size, &pfl->mem_mappings[i]);
  102. }
  103. }
  104. static void pflash_register_memory(pflash_t *pfl, int rom_mode)
  105. {
  106. memory_region_rom_device_set_readable(&pfl->orig_mem, rom_mode);
  107. pfl->rom_mode = rom_mode;
  108. }
  109. static void pflash_timer (void *opaque)
  110. {
  111. pflash_t *pfl = opaque;
  112. DPRINTF("%s: command %02x done\n", __func__, pfl->cmd);
  113. /* Reset flash */
  114. pfl->status ^= 0x80;
  115. if (pfl->bypass) {
  116. pfl->wcycle = 2;
  117. } else {
  118. pflash_register_memory(pfl, 1);
  119. pfl->wcycle = 0;
  120. }
  121. pfl->cmd = 0;
  122. }
  123. static uint32_t pflash_read (pflash_t *pfl, hwaddr offset,
  124. int width, int be)
  125. {
  126. hwaddr boff;
  127. uint32_t ret;
  128. uint8_t *p;
  129. DPRINTF("%s: offset " TARGET_FMT_plx "\n", __func__, offset);
  130. ret = -1;
  131. /* Lazy reset to ROMD mode after a certain amount of read accesses */
  132. if (!pfl->rom_mode && pfl->wcycle == 0 &&
  133. ++pfl->read_counter > PFLASH_LAZY_ROMD_THRESHOLD) {
  134. pflash_register_memory(pfl, 1);
  135. }
  136. offset &= pfl->chip_len - 1;
  137. boff = offset & 0xFF;
  138. if (pfl->width == 2)
  139. boff = boff >> 1;
  140. else if (pfl->width == 4)
  141. boff = boff >> 2;
  142. switch (pfl->cmd) {
  143. default:
  144. /* This should never happen : reset state & treat it as a read*/
  145. DPRINTF("%s: unknown command state: %x\n", __func__, pfl->cmd);
  146. pfl->wcycle = 0;
  147. pfl->cmd = 0;
  148. /* fall through to the read code */
  149. case 0x80:
  150. /* We accept reads during second unlock sequence... */
  151. case 0x00:
  152. flash_read:
  153. /* Flash area read */
  154. p = pfl->storage;
  155. switch (width) {
  156. case 1:
  157. ret = p[offset];
  158. // DPRINTF("%s: data offset %08x %02x\n", __func__, offset, ret);
  159. break;
  160. case 2:
  161. if (be) {
  162. ret = p[offset] << 8;
  163. ret |= p[offset + 1];
  164. } else {
  165. ret = p[offset];
  166. ret |= p[offset + 1] << 8;
  167. }
  168. // DPRINTF("%s: data offset %08x %04x\n", __func__, offset, ret);
  169. break;
  170. case 4:
  171. if (be) {
  172. ret = p[offset] << 24;
  173. ret |= p[offset + 1] << 16;
  174. ret |= p[offset + 2] << 8;
  175. ret |= p[offset + 3];
  176. } else {
  177. ret = p[offset];
  178. ret |= p[offset + 1] << 8;
  179. ret |= p[offset + 2] << 16;
  180. ret |= p[offset + 3] << 24;
  181. }
  182. // DPRINTF("%s: data offset %08x %08x\n", __func__, offset, ret);
  183. break;
  184. }
  185. break;
  186. case 0x90:
  187. /* flash ID read */
  188. switch (boff) {
  189. case 0x00:
  190. case 0x01:
  191. ret = boff & 0x01 ? pfl->ident1 : pfl->ident0;
  192. break;
  193. case 0x02:
  194. ret = 0x00; /* Pretend all sectors are unprotected */
  195. break;
  196. case 0x0E:
  197. case 0x0F:
  198. ret = boff & 0x01 ? pfl->ident3 : pfl->ident2;
  199. if (ret == (uint8_t)-1) {
  200. goto flash_read;
  201. }
  202. break;
  203. default:
  204. goto flash_read;
  205. }
  206. DPRINTF("%s: ID " TARGET_FMT_plx " %x\n", __func__, boff, ret);
  207. break;
  208. case 0xA0:
  209. case 0x10:
  210. case 0x30:
  211. /* Status register read */
  212. ret = pfl->status;
  213. DPRINTF("%s: status %x\n", __func__, ret);
  214. /* Toggle bit 6 */
  215. pfl->status ^= 0x40;
  216. break;
  217. case 0x98:
  218. /* CFI query mode */
  219. if (boff > pfl->cfi_len)
  220. ret = 0;
  221. else
  222. ret = pfl->cfi_table[boff];
  223. break;
  224. }
  225. return ret;
  226. }
  227. /* update flash content on disk */
  228. static void pflash_update(pflash_t *pfl, int offset,
  229. int size)
  230. {
  231. int offset_end;
  232. if (pfl->bs) {
  233. offset_end = offset + size;
  234. /* round to sectors */
  235. offset = offset >> 9;
  236. offset_end = (offset_end + 511) >> 9;
  237. bdrv_write(pfl->bs, offset, pfl->storage + (offset << 9),
  238. offset_end - offset);
  239. }
  240. }
  241. static void pflash_write (pflash_t *pfl, hwaddr offset,
  242. uint32_t value, int width, int be)
  243. {
  244. hwaddr boff;
  245. uint8_t *p;
  246. uint8_t cmd;
  247. cmd = value;
  248. if (pfl->cmd != 0xA0 && cmd == 0xF0) {
  249. #if 0
  250. DPRINTF("%s: flash reset asked (%02x %02x)\n",
  251. __func__, pfl->cmd, cmd);
  252. #endif
  253. goto reset_flash;
  254. }
  255. DPRINTF("%s: offset " TARGET_FMT_plx " %08x %d %d\n", __func__,
  256. offset, value, width, pfl->wcycle);
  257. offset &= pfl->chip_len - 1;
  258. DPRINTF("%s: offset " TARGET_FMT_plx " %08x %d\n", __func__,
  259. offset, value, width);
  260. boff = offset & (pfl->sector_len - 1);
  261. if (pfl->width == 2)
  262. boff = boff >> 1;
  263. else if (pfl->width == 4)
  264. boff = boff >> 2;
  265. switch (pfl->wcycle) {
  266. case 0:
  267. /* Set the device in I/O access mode if required */
  268. if (pfl->rom_mode)
  269. pflash_register_memory(pfl, 0);
  270. pfl->read_counter = 0;
  271. /* We're in read mode */
  272. check_unlock0:
  273. if (boff == 0x55 && cmd == 0x98) {
  274. enter_CFI_mode:
  275. /* Enter CFI query mode */
  276. pfl->wcycle = 7;
  277. pfl->cmd = 0x98;
  278. return;
  279. }
  280. if (boff != pfl->unlock_addr0 || cmd != 0xAA) {
  281. DPRINTF("%s: unlock0 failed " TARGET_FMT_plx " %02x %04x\n",
  282. __func__, boff, cmd, pfl->unlock_addr0);
  283. goto reset_flash;
  284. }
  285. DPRINTF("%s: unlock sequence started\n", __func__);
  286. break;
  287. case 1:
  288. /* We started an unlock sequence */
  289. check_unlock1:
  290. if (boff != pfl->unlock_addr1 || cmd != 0x55) {
  291. DPRINTF("%s: unlock1 failed " TARGET_FMT_plx " %02x\n", __func__,
  292. boff, cmd);
  293. goto reset_flash;
  294. }
  295. DPRINTF("%s: unlock sequence done\n", __func__);
  296. break;
  297. case 2:
  298. /* We finished an unlock sequence */
  299. if (!pfl->bypass && boff != pfl->unlock_addr0) {
  300. DPRINTF("%s: command failed " TARGET_FMT_plx " %02x\n", __func__,
  301. boff, cmd);
  302. goto reset_flash;
  303. }
  304. switch (cmd) {
  305. case 0x20:
  306. pfl->bypass = 1;
  307. goto do_bypass;
  308. case 0x80:
  309. case 0x90:
  310. case 0xA0:
  311. pfl->cmd = cmd;
  312. DPRINTF("%s: starting command %02x\n", __func__, cmd);
  313. break;
  314. default:
  315. DPRINTF("%s: unknown command %02x\n", __func__, cmd);
  316. goto reset_flash;
  317. }
  318. break;
  319. case 3:
  320. switch (pfl->cmd) {
  321. case 0x80:
  322. /* We need another unlock sequence */
  323. goto check_unlock0;
  324. case 0xA0:
  325. DPRINTF("%s: write data offset " TARGET_FMT_plx " %08x %d\n",
  326. __func__, offset, value, width);
  327. p = pfl->storage;
  328. if (!pfl->ro) {
  329. switch (width) {
  330. case 1:
  331. p[offset] &= value;
  332. pflash_update(pfl, offset, 1);
  333. break;
  334. case 2:
  335. if (be) {
  336. p[offset] &= value >> 8;
  337. p[offset + 1] &= value;
  338. } else {
  339. p[offset] &= value;
  340. p[offset + 1] &= value >> 8;
  341. }
  342. pflash_update(pfl, offset, 2);
  343. break;
  344. case 4:
  345. if (be) {
  346. p[offset] &= value >> 24;
  347. p[offset + 1] &= value >> 16;
  348. p[offset + 2] &= value >> 8;
  349. p[offset + 3] &= value;
  350. } else {
  351. p[offset] &= value;
  352. p[offset + 1] &= value >> 8;
  353. p[offset + 2] &= value >> 16;
  354. p[offset + 3] &= value >> 24;
  355. }
  356. pflash_update(pfl, offset, 4);
  357. break;
  358. }
  359. }
  360. pfl->status = 0x00 | ~(value & 0x80);
  361. /* Let's pretend write is immediate */
  362. if (pfl->bypass)
  363. goto do_bypass;
  364. goto reset_flash;
  365. case 0x90:
  366. if (pfl->bypass && cmd == 0x00) {
  367. /* Unlock bypass reset */
  368. goto reset_flash;
  369. }
  370. /* We can enter CFI query mode from autoselect mode */
  371. if (boff == 0x55 && cmd == 0x98)
  372. goto enter_CFI_mode;
  373. /* No break here */
  374. default:
  375. DPRINTF("%s: invalid write for command %02x\n",
  376. __func__, pfl->cmd);
  377. goto reset_flash;
  378. }
  379. case 4:
  380. switch (pfl->cmd) {
  381. case 0xA0:
  382. /* Ignore writes while flash data write is occurring */
  383. /* As we suppose write is immediate, this should never happen */
  384. return;
  385. case 0x80:
  386. goto check_unlock1;
  387. default:
  388. /* Should never happen */
  389. DPRINTF("%s: invalid command state %02x (wc 4)\n",
  390. __func__, pfl->cmd);
  391. goto reset_flash;
  392. }
  393. break;
  394. case 5:
  395. switch (cmd) {
  396. case 0x10:
  397. if (boff != pfl->unlock_addr0) {
  398. DPRINTF("%s: chip erase: invalid address " TARGET_FMT_plx "\n",
  399. __func__, offset);
  400. goto reset_flash;
  401. }
  402. /* Chip erase */
  403. DPRINTF("%s: start chip erase\n", __func__);
  404. if (!pfl->ro) {
  405. memset(pfl->storage, 0xFF, pfl->chip_len);
  406. pflash_update(pfl, 0, pfl->chip_len);
  407. }
  408. pfl->status = 0x00;
  409. /* Let's wait 5 seconds before chip erase is done */
  410. qemu_mod_timer(pfl->timer,
  411. qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() * 5));
  412. break;
  413. case 0x30:
  414. /* Sector erase */
  415. p = pfl->storage;
  416. offset &= ~(pfl->sector_len - 1);
  417. DPRINTF("%s: start sector erase at " TARGET_FMT_plx "\n", __func__,
  418. offset);
  419. if (!pfl->ro) {
  420. memset(p + offset, 0xFF, pfl->sector_len);
  421. pflash_update(pfl, offset, pfl->sector_len);
  422. }
  423. pfl->status = 0x00;
  424. /* Let's wait 1/2 second before sector erase is done */
  425. qemu_mod_timer(pfl->timer,
  426. qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() / 2));
  427. break;
  428. default:
  429. DPRINTF("%s: invalid command %02x (wc 5)\n", __func__, cmd);
  430. goto reset_flash;
  431. }
  432. pfl->cmd = cmd;
  433. break;
  434. case 6:
  435. switch (pfl->cmd) {
  436. case 0x10:
  437. /* Ignore writes during chip erase */
  438. return;
  439. case 0x30:
  440. /* Ignore writes during sector erase */
  441. return;
  442. default:
  443. /* Should never happen */
  444. DPRINTF("%s: invalid command state %02x (wc 6)\n",
  445. __func__, pfl->cmd);
  446. goto reset_flash;
  447. }
  448. break;
  449. case 7: /* Special value for CFI queries */
  450. DPRINTF("%s: invalid write in CFI query mode\n", __func__);
  451. goto reset_flash;
  452. default:
  453. /* Should never happen */
  454. DPRINTF("%s: invalid write state (wc 7)\n", __func__);
  455. goto reset_flash;
  456. }
  457. pfl->wcycle++;
  458. return;
  459. /* Reset flash */
  460. reset_flash:
  461. pfl->bypass = 0;
  462. pfl->wcycle = 0;
  463. pfl->cmd = 0;
  464. return;
  465. do_bypass:
  466. pfl->wcycle = 2;
  467. pfl->cmd = 0;
  468. }
  469. static uint32_t pflash_readb_be(void *opaque, hwaddr addr)
  470. {
  471. return pflash_read(opaque, addr, 1, 1);
  472. }
  473. static uint32_t pflash_readb_le(void *opaque, hwaddr addr)
  474. {
  475. return pflash_read(opaque, addr, 1, 0);
  476. }
  477. static uint32_t pflash_readw_be(void *opaque, hwaddr addr)
  478. {
  479. pflash_t *pfl = opaque;
  480. return pflash_read(pfl, addr, 2, 1);
  481. }
  482. static uint32_t pflash_readw_le(void *opaque, hwaddr addr)
  483. {
  484. pflash_t *pfl = opaque;
  485. return pflash_read(pfl, addr, 2, 0);
  486. }
  487. static uint32_t pflash_readl_be(void *opaque, hwaddr addr)
  488. {
  489. pflash_t *pfl = opaque;
  490. return pflash_read(pfl, addr, 4, 1);
  491. }
  492. static uint32_t pflash_readl_le(void *opaque, hwaddr addr)
  493. {
  494. pflash_t *pfl = opaque;
  495. return pflash_read(pfl, addr, 4, 0);
  496. }
  497. static void pflash_writeb_be(void *opaque, hwaddr addr,
  498. uint32_t value)
  499. {
  500. pflash_write(opaque, addr, value, 1, 1);
  501. }
  502. static void pflash_writeb_le(void *opaque, hwaddr addr,
  503. uint32_t value)
  504. {
  505. pflash_write(opaque, addr, value, 1, 0);
  506. }
  507. static void pflash_writew_be(void *opaque, hwaddr addr,
  508. uint32_t value)
  509. {
  510. pflash_t *pfl = opaque;
  511. pflash_write(pfl, addr, value, 2, 1);
  512. }
  513. static void pflash_writew_le(void *opaque, hwaddr addr,
  514. uint32_t value)
  515. {
  516. pflash_t *pfl = opaque;
  517. pflash_write(pfl, addr, value, 2, 0);
  518. }
  519. static void pflash_writel_be(void *opaque, hwaddr addr,
  520. uint32_t value)
  521. {
  522. pflash_t *pfl = opaque;
  523. pflash_write(pfl, addr, value, 4, 1);
  524. }
  525. static void pflash_writel_le(void *opaque, hwaddr addr,
  526. uint32_t value)
  527. {
  528. pflash_t *pfl = opaque;
  529. pflash_write(pfl, addr, value, 4, 0);
  530. }
  531. static const MemoryRegionOps pflash_cfi02_ops_be = {
  532. .old_mmio = {
  533. .read = { pflash_readb_be, pflash_readw_be, pflash_readl_be, },
  534. .write = { pflash_writeb_be, pflash_writew_be, pflash_writel_be, },
  535. },
  536. .endianness = DEVICE_NATIVE_ENDIAN,
  537. };
  538. static const MemoryRegionOps pflash_cfi02_ops_le = {
  539. .old_mmio = {
  540. .read = { pflash_readb_le, pflash_readw_le, pflash_readl_le, },
  541. .write = { pflash_writeb_le, pflash_writew_le, pflash_writel_le, },
  542. },
  543. .endianness = DEVICE_NATIVE_ENDIAN,
  544. };
  545. static int pflash_cfi02_init(SysBusDevice *dev)
  546. {
  547. pflash_t *pfl = FROM_SYSBUS(typeof(*pfl), dev);
  548. uint32_t chip_len;
  549. int ret;
  550. chip_len = pfl->sector_len * pfl->nb_blocs;
  551. /* XXX: to be fixed */
  552. #if 0
  553. if (total_len != (8 * 1024 * 1024) && total_len != (16 * 1024 * 1024) &&
  554. total_len != (32 * 1024 * 1024) && total_len != (64 * 1024 * 1024))
  555. return NULL;
  556. #endif
  557. memory_region_init_rom_device(&pfl->orig_mem, pfl->be ?
  558. &pflash_cfi02_ops_be : &pflash_cfi02_ops_le,
  559. pfl, pfl->name, chip_len);
  560. vmstate_register_ram(&pfl->orig_mem, DEVICE(pfl));
  561. pfl->storage = memory_region_get_ram_ptr(&pfl->orig_mem);
  562. pfl->chip_len = chip_len;
  563. if (pfl->bs) {
  564. /* read the initial flash content */
  565. ret = bdrv_read(pfl->bs, 0, pfl->storage, chip_len >> 9);
  566. if (ret < 0) {
  567. g_free(pfl);
  568. return 1;
  569. }
  570. }
  571. pflash_setup_mappings(pfl);
  572. pfl->rom_mode = 1;
  573. sysbus_init_mmio(dev, &pfl->mem);
  574. if (pfl->bs) {
  575. pfl->ro = bdrv_is_read_only(pfl->bs);
  576. } else {
  577. pfl->ro = 0;
  578. }
  579. pfl->timer = qemu_new_timer_ns(vm_clock, pflash_timer, pfl);
  580. pfl->wcycle = 0;
  581. pfl->cmd = 0;
  582. pfl->status = 0;
  583. /* Hardcoded CFI table (mostly from SG29 Spansion flash) */
  584. pfl->cfi_len = 0x52;
  585. /* Standard "QRY" string */
  586. pfl->cfi_table[0x10] = 'Q';
  587. pfl->cfi_table[0x11] = 'R';
  588. pfl->cfi_table[0x12] = 'Y';
  589. /* Command set (AMD/Fujitsu) */
  590. pfl->cfi_table[0x13] = 0x02;
  591. pfl->cfi_table[0x14] = 0x00;
  592. /* Primary extended table address */
  593. pfl->cfi_table[0x15] = 0x31;
  594. pfl->cfi_table[0x16] = 0x00;
  595. /* Alternate command set (none) */
  596. pfl->cfi_table[0x17] = 0x00;
  597. pfl->cfi_table[0x18] = 0x00;
  598. /* Alternate extended table (none) */
  599. pfl->cfi_table[0x19] = 0x00;
  600. pfl->cfi_table[0x1A] = 0x00;
  601. /* Vcc min */
  602. pfl->cfi_table[0x1B] = 0x27;
  603. /* Vcc max */
  604. pfl->cfi_table[0x1C] = 0x36;
  605. /* Vpp min (no Vpp pin) */
  606. pfl->cfi_table[0x1D] = 0x00;
  607. /* Vpp max (no Vpp pin) */
  608. pfl->cfi_table[0x1E] = 0x00;
  609. /* Reserved */
  610. pfl->cfi_table[0x1F] = 0x07;
  611. /* Timeout for min size buffer write (NA) */
  612. pfl->cfi_table[0x20] = 0x00;
  613. /* Typical timeout for block erase (512 ms) */
  614. pfl->cfi_table[0x21] = 0x09;
  615. /* Typical timeout for full chip erase (4096 ms) */
  616. pfl->cfi_table[0x22] = 0x0C;
  617. /* Reserved */
  618. pfl->cfi_table[0x23] = 0x01;
  619. /* Max timeout for buffer write (NA) */
  620. pfl->cfi_table[0x24] = 0x00;
  621. /* Max timeout for block erase */
  622. pfl->cfi_table[0x25] = 0x0A;
  623. /* Max timeout for chip erase */
  624. pfl->cfi_table[0x26] = 0x0D;
  625. /* Device size */
  626. pfl->cfi_table[0x27] = ctz32(chip_len);
  627. /* Flash device interface (8 & 16 bits) */
  628. pfl->cfi_table[0x28] = 0x02;
  629. pfl->cfi_table[0x29] = 0x00;
  630. /* Max number of bytes in multi-bytes write */
  631. /* XXX: disable buffered write as it's not supported */
  632. // pfl->cfi_table[0x2A] = 0x05;
  633. pfl->cfi_table[0x2A] = 0x00;
  634. pfl->cfi_table[0x2B] = 0x00;
  635. /* Number of erase block regions (uniform) */
  636. pfl->cfi_table[0x2C] = 0x01;
  637. /* Erase block region 1 */
  638. pfl->cfi_table[0x2D] = pfl->nb_blocs - 1;
  639. pfl->cfi_table[0x2E] = (pfl->nb_blocs - 1) >> 8;
  640. pfl->cfi_table[0x2F] = pfl->sector_len >> 8;
  641. pfl->cfi_table[0x30] = pfl->sector_len >> 16;
  642. /* Extended */
  643. pfl->cfi_table[0x31] = 'P';
  644. pfl->cfi_table[0x32] = 'R';
  645. pfl->cfi_table[0x33] = 'I';
  646. pfl->cfi_table[0x34] = '1';
  647. pfl->cfi_table[0x35] = '0';
  648. pfl->cfi_table[0x36] = 0x00;
  649. pfl->cfi_table[0x37] = 0x00;
  650. pfl->cfi_table[0x38] = 0x00;
  651. pfl->cfi_table[0x39] = 0x00;
  652. pfl->cfi_table[0x3a] = 0x00;
  653. pfl->cfi_table[0x3b] = 0x00;
  654. pfl->cfi_table[0x3c] = 0x00;
  655. return 0;
  656. }
  657. static Property pflash_cfi02_properties[] = {
  658. DEFINE_PROP_DRIVE("drive", struct pflash_t, bs),
  659. DEFINE_PROP_UINT32("num-blocks", struct pflash_t, nb_blocs, 0),
  660. DEFINE_PROP_UINT32("sector-length", struct pflash_t, sector_len, 0),
  661. DEFINE_PROP_UINT8("width", struct pflash_t, width, 0),
  662. DEFINE_PROP_UINT8("mappings", struct pflash_t, mappings, 0),
  663. DEFINE_PROP_UINT8("big-endian", struct pflash_t, be, 0),
  664. DEFINE_PROP_UINT16("id0", struct pflash_t, ident0, 0),
  665. DEFINE_PROP_UINT16("id1", struct pflash_t, ident1, 0),
  666. DEFINE_PROP_UINT16("id2", struct pflash_t, ident2, 0),
  667. DEFINE_PROP_UINT16("id3", struct pflash_t, ident3, 0),
  668. DEFINE_PROP_UINT16("unlock-addr0", struct pflash_t, unlock_addr0, 0),
  669. DEFINE_PROP_UINT16("unlock-addr1", struct pflash_t, unlock_addr1, 0),
  670. DEFINE_PROP_STRING("name", struct pflash_t, name),
  671. DEFINE_PROP_END_OF_LIST(),
  672. };
  673. static void pflash_cfi02_class_init(ObjectClass *klass, void *data)
  674. {
  675. DeviceClass *dc = DEVICE_CLASS(klass);
  676. SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
  677. k->init = pflash_cfi02_init;
  678. dc->props = pflash_cfi02_properties;
  679. }
  680. static const TypeInfo pflash_cfi02_info = {
  681. .name = "cfi.pflash02",
  682. .parent = TYPE_SYS_BUS_DEVICE,
  683. .instance_size = sizeof(struct pflash_t),
  684. .class_init = pflash_cfi02_class_init,
  685. };
  686. static void pflash_cfi02_register_types(void)
  687. {
  688. type_register_static(&pflash_cfi02_info);
  689. }
  690. type_init(pflash_cfi02_register_types)
  691. pflash_t *pflash_cfi02_register(hwaddr base,
  692. DeviceState *qdev, const char *name,
  693. hwaddr size,
  694. BlockDriverState *bs, uint32_t sector_len,
  695. int nb_blocs, int nb_mappings, int width,
  696. uint16_t id0, uint16_t id1,
  697. uint16_t id2, uint16_t id3,
  698. uint16_t unlock_addr0, uint16_t unlock_addr1,
  699. int be)
  700. {
  701. DeviceState *dev = qdev_create(NULL, "cfi.pflash02");
  702. SysBusDevice *busdev = SYS_BUS_DEVICE(dev);
  703. pflash_t *pfl = (pflash_t *)object_dynamic_cast(OBJECT(dev),
  704. "cfi.pflash02");
  705. if (bs && qdev_prop_set_drive(dev, "drive", bs)) {
  706. abort();
  707. }
  708. qdev_prop_set_uint32(dev, "num-blocks", nb_blocs);
  709. qdev_prop_set_uint32(dev, "sector-length", sector_len);
  710. qdev_prop_set_uint8(dev, "width", width);
  711. qdev_prop_set_uint8(dev, "mappings", nb_mappings);
  712. qdev_prop_set_uint8(dev, "big-endian", !!be);
  713. qdev_prop_set_uint16(dev, "id0", id0);
  714. qdev_prop_set_uint16(dev, "id1", id1);
  715. qdev_prop_set_uint16(dev, "id2", id2);
  716. qdev_prop_set_uint16(dev, "id3", id3);
  717. qdev_prop_set_uint16(dev, "unlock-addr0", unlock_addr0);
  718. qdev_prop_set_uint16(dev, "unlock-addr1", unlock_addr1);
  719. qdev_prop_set_string(dev, "name", name);
  720. qdev_init_nofail(dev);
  721. sysbus_mmio_map(busdev, 0, base);
  722. return pfl;
  723. }