onenand.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663
  1. /*
  2. * OneNAND flash memories emulation.
  3. *
  4. * Copyright (C) 2008 Nokia Corporation
  5. * Written by Andrzej Zaborowski <andrew@openedhand.com>
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2 or
  10. * (at your option) version 3 of the License.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License along
  18. * with this program; if not, write to the Free Software Foundation, Inc.,
  19. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20. */
  21. #include "qemu-common.h"
  22. #include "flash.h"
  23. #include "irq.h"
  24. #include "sysemu.h"
  25. #include "block.h"
  26. /* 11 for 2kB-page OneNAND ("2nd generation") and 10 for 1kB-page chips */
  27. #define PAGE_SHIFT 11
  28. /* Fixed */
  29. #define BLOCK_SHIFT (PAGE_SHIFT + 6)
  30. struct onenand_s {
  31. uint32_t id;
  32. int shift;
  33. target_phys_addr_t base;
  34. qemu_irq intr;
  35. qemu_irq rdy;
  36. BlockDriverState *bdrv;
  37. BlockDriverState *bdrv_cur;
  38. uint8_t *image;
  39. uint8_t *otp;
  40. uint8_t *current;
  41. ram_addr_t ram;
  42. uint8_t *boot[2];
  43. uint8_t *data[2][2];
  44. int iomemtype;
  45. int cycle;
  46. int otpmode;
  47. uint16_t addr[8];
  48. uint16_t unladdr[8];
  49. int bufaddr;
  50. int count;
  51. uint16_t command;
  52. uint16_t config[2];
  53. uint16_t status;
  54. uint16_t intstatus;
  55. uint16_t wpstatus;
  56. struct ecc_state_s ecc;
  57. int density_mask;
  58. int secs;
  59. int secs_cur;
  60. int blocks;
  61. uint8_t *blockwp;
  62. };
  63. enum {
  64. ONEN_BUF_BLOCK = 0,
  65. ONEN_BUF_BLOCK2 = 1,
  66. ONEN_BUF_DEST_BLOCK = 2,
  67. ONEN_BUF_DEST_PAGE = 3,
  68. ONEN_BUF_PAGE = 7,
  69. };
  70. enum {
  71. ONEN_ERR_CMD = 1 << 10,
  72. ONEN_ERR_ERASE = 1 << 11,
  73. ONEN_ERR_PROG = 1 << 12,
  74. ONEN_ERR_LOAD = 1 << 13,
  75. };
  76. enum {
  77. ONEN_INT_RESET = 1 << 4,
  78. ONEN_INT_ERASE = 1 << 5,
  79. ONEN_INT_PROG = 1 << 6,
  80. ONEN_INT_LOAD = 1 << 7,
  81. ONEN_INT = 1 << 15,
  82. };
  83. enum {
  84. ONEN_LOCK_LOCKTIGHTEN = 1 << 0,
  85. ONEN_LOCK_LOCKED = 1 << 1,
  86. ONEN_LOCK_UNLOCKED = 1 << 2,
  87. };
  88. void onenand_base_update(void *opaque, target_phys_addr_t new)
  89. {
  90. struct onenand_s *s = (struct onenand_s *) opaque;
  91. s->base = new;
  92. /* XXX: We should use IO_MEM_ROMD but we broke it earlier...
  93. * Both 0x0000 ... 0x01ff and 0x8000 ... 0x800f can be used to
  94. * write boot commands. Also take note of the BWPS bit. */
  95. cpu_register_physical_memory(s->base + (0x0000 << s->shift),
  96. 0x0200 << s->shift, s->iomemtype);
  97. cpu_register_physical_memory(s->base + (0x0200 << s->shift),
  98. 0xbe00 << s->shift,
  99. (s->ram +(0x0200 << s->shift)) | IO_MEM_RAM);
  100. if (s->iomemtype)
  101. cpu_register_physical_memory_offset(s->base + (0xc000 << s->shift),
  102. 0x4000 << s->shift, s->iomemtype, (0xc000 << s->shift));
  103. }
  104. void onenand_base_unmap(void *opaque)
  105. {
  106. struct onenand_s *s = (struct onenand_s *) opaque;
  107. cpu_register_physical_memory(s->base,
  108. 0x10000 << s->shift, IO_MEM_UNASSIGNED);
  109. }
  110. static void onenand_intr_update(struct onenand_s *s)
  111. {
  112. qemu_set_irq(s->intr, ((s->intstatus >> 15) ^ (~s->config[0] >> 6)) & 1);
  113. }
  114. /* Hot reset (Reset OneNAND command) or warm reset (RP pin low) */
  115. static void onenand_reset(struct onenand_s *s, int cold)
  116. {
  117. memset(&s->addr, 0, sizeof(s->addr));
  118. s->command = 0;
  119. s->count = 1;
  120. s->bufaddr = 0;
  121. s->config[0] = 0x40c0;
  122. s->config[1] = 0x0000;
  123. onenand_intr_update(s);
  124. qemu_irq_raise(s->rdy);
  125. s->status = 0x0000;
  126. s->intstatus = cold ? 0x8080 : 0x8010;
  127. s->unladdr[0] = 0;
  128. s->unladdr[1] = 0;
  129. s->wpstatus = 0x0002;
  130. s->cycle = 0;
  131. s->otpmode = 0;
  132. s->bdrv_cur = s->bdrv;
  133. s->current = s->image;
  134. s->secs_cur = s->secs;
  135. if (cold) {
  136. /* Lock the whole flash */
  137. memset(s->blockwp, ONEN_LOCK_LOCKED, s->blocks);
  138. if (s->bdrv && bdrv_read(s->bdrv, 0, s->boot[0], 8) < 0)
  139. cpu_abort(cpu_single_env, "%s: Loading the BootRAM failed.\n",
  140. __FUNCTION__);
  141. }
  142. }
  143. static inline int onenand_load_main(struct onenand_s *s, int sec, int secn,
  144. void *dest)
  145. {
  146. if (s->bdrv_cur)
  147. return bdrv_read(s->bdrv_cur, sec, dest, secn) < 0;
  148. else if (sec + secn > s->secs_cur)
  149. return 1;
  150. memcpy(dest, s->current + (sec << 9), secn << 9);
  151. return 0;
  152. }
  153. static inline int onenand_prog_main(struct onenand_s *s, int sec, int secn,
  154. void *src)
  155. {
  156. if (s->bdrv_cur)
  157. return bdrv_write(s->bdrv_cur, sec, src, secn) < 0;
  158. else if (sec + secn > s->secs_cur)
  159. return 1;
  160. memcpy(s->current + (sec << 9), src, secn << 9);
  161. return 0;
  162. }
  163. static inline int onenand_load_spare(struct onenand_s *s, int sec, int secn,
  164. void *dest)
  165. {
  166. uint8_t buf[512];
  167. if (s->bdrv_cur) {
  168. if (bdrv_read(s->bdrv_cur, s->secs_cur + (sec >> 5), buf, 1) < 0)
  169. return 1;
  170. memcpy(dest, buf + ((sec & 31) << 4), secn << 4);
  171. } else if (sec + secn > s->secs_cur)
  172. return 1;
  173. else
  174. memcpy(dest, s->current + (s->secs_cur << 9) + (sec << 4), secn << 4);
  175. return 0;
  176. }
  177. static inline int onenand_prog_spare(struct onenand_s *s, int sec, int secn,
  178. void *src)
  179. {
  180. uint8_t buf[512];
  181. if (s->bdrv_cur) {
  182. if (bdrv_read(s->bdrv_cur, s->secs_cur + (sec >> 5), buf, 1) < 0)
  183. return 1;
  184. memcpy(buf + ((sec & 31) << 4), src, secn << 4);
  185. return bdrv_write(s->bdrv_cur, s->secs_cur + (sec >> 5), buf, 1) < 0;
  186. } else if (sec + secn > s->secs_cur)
  187. return 1;
  188. memcpy(s->current + (s->secs_cur << 9) + (sec << 4), src, secn << 4);
  189. return 0;
  190. }
  191. static inline int onenand_erase(struct onenand_s *s, int sec, int num)
  192. {
  193. /* TODO: optimise */
  194. uint8_t buf[512];
  195. memset(buf, 0xff, sizeof(buf));
  196. for (; num > 0; num --, sec ++) {
  197. if (onenand_prog_main(s, sec, 1, buf))
  198. return 1;
  199. if (onenand_prog_spare(s, sec, 1, buf))
  200. return 1;
  201. }
  202. return 0;
  203. }
  204. static void onenand_command(struct onenand_s *s, int cmd)
  205. {
  206. int b;
  207. int sec;
  208. void *buf;
  209. #define SETADDR(block, page) \
  210. sec = (s->addr[page] & 3) + \
  211. ((((s->addr[page] >> 2) & 0x3f) + \
  212. (((s->addr[block] & 0xfff) | \
  213. (s->addr[block] >> 15 ? \
  214. s->density_mask : 0)) << 6)) << (PAGE_SHIFT - 9));
  215. #define SETBUF_M() \
  216. buf = (s->bufaddr & 8) ? \
  217. s->data[(s->bufaddr >> 2) & 1][0] : s->boot[0]; \
  218. buf += (s->bufaddr & 3) << 9;
  219. #define SETBUF_S() \
  220. buf = (s->bufaddr & 8) ? \
  221. s->data[(s->bufaddr >> 2) & 1][1] : s->boot[1]; \
  222. buf += (s->bufaddr & 3) << 4;
  223. switch (cmd) {
  224. case 0x00: /* Load single/multiple sector data unit into buffer */
  225. SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
  226. SETBUF_M()
  227. if (onenand_load_main(s, sec, s->count, buf))
  228. s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD;
  229. #if 0
  230. SETBUF_S()
  231. if (onenand_load_spare(s, sec, s->count, buf))
  232. s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD;
  233. #endif
  234. /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
  235. * or if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
  236. * then we need two split the read/write into two chunks.
  237. */
  238. s->intstatus |= ONEN_INT | ONEN_INT_LOAD;
  239. break;
  240. case 0x13: /* Load single/multiple spare sector into buffer */
  241. SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
  242. SETBUF_S()
  243. if (onenand_load_spare(s, sec, s->count, buf))
  244. s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD;
  245. /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
  246. * or if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
  247. * then we need two split the read/write into two chunks.
  248. */
  249. s->intstatus |= ONEN_INT | ONEN_INT_LOAD;
  250. break;
  251. case 0x80: /* Program single/multiple sector data unit from buffer */
  252. SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
  253. SETBUF_M()
  254. if (onenand_prog_main(s, sec, s->count, buf))
  255. s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
  256. #if 0
  257. SETBUF_S()
  258. if (onenand_prog_spare(s, sec, s->count, buf))
  259. s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
  260. #endif
  261. /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
  262. * or if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
  263. * then we need two split the read/write into two chunks.
  264. */
  265. s->intstatus |= ONEN_INT | ONEN_INT_PROG;
  266. break;
  267. case 0x1a: /* Program single/multiple spare area sector from buffer */
  268. SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
  269. SETBUF_S()
  270. if (onenand_prog_spare(s, sec, s->count, buf))
  271. s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
  272. /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
  273. * or if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
  274. * then we need two split the read/write into two chunks.
  275. */
  276. s->intstatus |= ONEN_INT | ONEN_INT_PROG;
  277. break;
  278. case 0x1b: /* Copy-back program */
  279. SETBUF_S()
  280. SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
  281. if (onenand_load_main(s, sec, s->count, buf))
  282. s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
  283. SETADDR(ONEN_BUF_DEST_BLOCK, ONEN_BUF_DEST_PAGE)
  284. if (onenand_prog_main(s, sec, s->count, buf))
  285. s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
  286. /* TODO: spare areas */
  287. s->intstatus |= ONEN_INT | ONEN_INT_PROG;
  288. break;
  289. case 0x23: /* Unlock NAND array block(s) */
  290. s->intstatus |= ONEN_INT;
  291. /* XXX the previous (?) area should be locked automatically */
  292. for (b = s->unladdr[0]; b <= s->unladdr[1]; b ++) {
  293. if (b >= s->blocks) {
  294. s->status |= ONEN_ERR_CMD;
  295. break;
  296. }
  297. if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
  298. break;
  299. s->wpstatus = s->blockwp[b] = ONEN_LOCK_UNLOCKED;
  300. }
  301. break;
  302. case 0x27: /* Unlock All NAND array blocks */
  303. s->intstatus |= ONEN_INT;
  304. for (b = 0; b < s->blocks; b ++) {
  305. if (b >= s->blocks) {
  306. s->status |= ONEN_ERR_CMD;
  307. break;
  308. }
  309. if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
  310. break;
  311. s->wpstatus = s->blockwp[b] = ONEN_LOCK_UNLOCKED;
  312. }
  313. break;
  314. case 0x2a: /* Lock NAND array block(s) */
  315. s->intstatus |= ONEN_INT;
  316. for (b = s->unladdr[0]; b <= s->unladdr[1]; b ++) {
  317. if (b >= s->blocks) {
  318. s->status |= ONEN_ERR_CMD;
  319. break;
  320. }
  321. if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
  322. break;
  323. s->wpstatus = s->blockwp[b] = ONEN_LOCK_LOCKED;
  324. }
  325. break;
  326. case 0x2c: /* Lock-tight NAND array block(s) */
  327. s->intstatus |= ONEN_INT;
  328. for (b = s->unladdr[0]; b <= s->unladdr[1]; b ++) {
  329. if (b >= s->blocks) {
  330. s->status |= ONEN_ERR_CMD;
  331. break;
  332. }
  333. if (s->blockwp[b] == ONEN_LOCK_UNLOCKED)
  334. continue;
  335. s->wpstatus = s->blockwp[b] = ONEN_LOCK_LOCKTIGHTEN;
  336. }
  337. break;
  338. case 0x71: /* Erase-Verify-Read */
  339. s->intstatus |= ONEN_INT;
  340. break;
  341. case 0x95: /* Multi-block erase */
  342. qemu_irq_pulse(s->intr);
  343. /* Fall through. */
  344. case 0x94: /* Block erase */
  345. sec = ((s->addr[ONEN_BUF_BLOCK] & 0xfff) |
  346. (s->addr[ONEN_BUF_BLOCK] >> 15 ? s->density_mask : 0))
  347. << (BLOCK_SHIFT - 9);
  348. if (onenand_erase(s, sec, 1 << (BLOCK_SHIFT - 9)))
  349. s->status |= ONEN_ERR_CMD | ONEN_ERR_ERASE;
  350. s->intstatus |= ONEN_INT | ONEN_INT_ERASE;
  351. break;
  352. case 0xb0: /* Erase suspend */
  353. break;
  354. case 0x30: /* Erase resume */
  355. s->intstatus |= ONEN_INT | ONEN_INT_ERASE;
  356. break;
  357. case 0xf0: /* Reset NAND Flash core */
  358. onenand_reset(s, 0);
  359. break;
  360. case 0xf3: /* Reset OneNAND */
  361. onenand_reset(s, 0);
  362. break;
  363. case 0x65: /* OTP Access */
  364. s->intstatus |= ONEN_INT;
  365. s->bdrv_cur = 0;
  366. s->current = s->otp;
  367. s->secs_cur = 1 << (BLOCK_SHIFT - 9);
  368. s->addr[ONEN_BUF_BLOCK] = 0;
  369. s->otpmode = 1;
  370. break;
  371. default:
  372. s->status |= ONEN_ERR_CMD;
  373. s->intstatus |= ONEN_INT;
  374. fprintf(stderr, "%s: unknown OneNAND command %x\n",
  375. __FUNCTION__, cmd);
  376. }
  377. onenand_intr_update(s);
  378. }
  379. static uint32_t onenand_read(void *opaque, target_phys_addr_t addr)
  380. {
  381. struct onenand_s *s = (struct onenand_s *) opaque;
  382. int offset = addr >> s->shift;
  383. switch (offset) {
  384. case 0x0000 ... 0xc000:
  385. return lduw_le_p(s->boot[0] + addr);
  386. case 0xf000: /* Manufacturer ID */
  387. return (s->id >> 16) & 0xff;
  388. case 0xf001: /* Device ID */
  389. return (s->id >> 8) & 0xff;
  390. /* TODO: get the following values from a real chip! */
  391. case 0xf002: /* Version ID */
  392. return (s->id >> 0) & 0xff;
  393. case 0xf003: /* Data Buffer size */
  394. return 1 << PAGE_SHIFT;
  395. case 0xf004: /* Boot Buffer size */
  396. return 0x200;
  397. case 0xf005: /* Amount of buffers */
  398. return 1 | (2 << 8);
  399. case 0xf006: /* Technology */
  400. return 0;
  401. case 0xf100 ... 0xf107: /* Start addresses */
  402. return s->addr[offset - 0xf100];
  403. case 0xf200: /* Start buffer */
  404. return (s->bufaddr << 8) | ((s->count - 1) & (1 << (PAGE_SHIFT - 10)));
  405. case 0xf220: /* Command */
  406. return s->command;
  407. case 0xf221: /* System Configuration 1 */
  408. return s->config[0] & 0xffe0;
  409. case 0xf222: /* System Configuration 2 */
  410. return s->config[1];
  411. case 0xf240: /* Controller Status */
  412. return s->status;
  413. case 0xf241: /* Interrupt */
  414. return s->intstatus;
  415. case 0xf24c: /* Unlock Start Block Address */
  416. return s->unladdr[0];
  417. case 0xf24d: /* Unlock End Block Address */
  418. return s->unladdr[1];
  419. case 0xf24e: /* Write Protection Status */
  420. return s->wpstatus;
  421. case 0xff00: /* ECC Status */
  422. return 0x00;
  423. case 0xff01: /* ECC Result of main area data */
  424. case 0xff02: /* ECC Result of spare area data */
  425. case 0xff03: /* ECC Result of main area data */
  426. case 0xff04: /* ECC Result of spare area data */
  427. cpu_abort(cpu_single_env, "%s: imeplement ECC\n", __FUNCTION__);
  428. return 0x0000;
  429. }
  430. fprintf(stderr, "%s: unknown OneNAND register %x\n",
  431. __FUNCTION__, offset);
  432. return 0;
  433. }
  434. static void onenand_write(void *opaque, target_phys_addr_t addr,
  435. uint32_t value)
  436. {
  437. struct onenand_s *s = (struct onenand_s *) opaque;
  438. int offset = addr >> s->shift;
  439. int sec;
  440. switch (offset) {
  441. case 0x0000 ... 0x01ff:
  442. case 0x8000 ... 0x800f:
  443. if (s->cycle) {
  444. s->cycle = 0;
  445. if (value == 0x0000) {
  446. SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
  447. onenand_load_main(s, sec,
  448. 1 << (PAGE_SHIFT - 9), s->data[0][0]);
  449. s->addr[ONEN_BUF_PAGE] += 4;
  450. s->addr[ONEN_BUF_PAGE] &= 0xff;
  451. }
  452. break;
  453. }
  454. switch (value) {
  455. case 0x00f0: /* Reset OneNAND */
  456. onenand_reset(s, 0);
  457. break;
  458. case 0x00e0: /* Load Data into Buffer */
  459. s->cycle = 1;
  460. break;
  461. case 0x0090: /* Read Identification Data */
  462. memset(s->boot[0], 0, 3 << s->shift);
  463. s->boot[0][0 << s->shift] = (s->id >> 16) & 0xff;
  464. s->boot[0][1 << s->shift] = (s->id >> 8) & 0xff;
  465. s->boot[0][2 << s->shift] = s->wpstatus & 0xff;
  466. break;
  467. default:
  468. fprintf(stderr, "%s: unknown OneNAND boot command %x\n",
  469. __FUNCTION__, value);
  470. }
  471. break;
  472. case 0xf100 ... 0xf107: /* Start addresses */
  473. s->addr[offset - 0xf100] = value;
  474. break;
  475. case 0xf200: /* Start buffer */
  476. s->bufaddr = (value >> 8) & 0xf;
  477. if (PAGE_SHIFT == 11)
  478. s->count = (value & 3) ?: 4;
  479. else if (PAGE_SHIFT == 10)
  480. s->count = (value & 1) ?: 2;
  481. break;
  482. case 0xf220: /* Command */
  483. if (s->intstatus & (1 << 15))
  484. break;
  485. s->command = value;
  486. onenand_command(s, s->command);
  487. break;
  488. case 0xf221: /* System Configuration 1 */
  489. s->config[0] = value;
  490. onenand_intr_update(s);
  491. qemu_set_irq(s->rdy, (s->config[0] >> 7) & 1);
  492. break;
  493. case 0xf222: /* System Configuration 2 */
  494. s->config[1] = value;
  495. break;
  496. case 0xf241: /* Interrupt */
  497. s->intstatus &= value;
  498. if ((1 << 15) & ~s->intstatus)
  499. s->status &= ~(ONEN_ERR_CMD | ONEN_ERR_ERASE |
  500. ONEN_ERR_PROG | ONEN_ERR_LOAD);
  501. onenand_intr_update(s);
  502. break;
  503. case 0xf24c: /* Unlock Start Block Address */
  504. s->unladdr[0] = value & (s->blocks - 1);
  505. /* For some reason we have to set the end address to by default
  506. * be same as start because the software forgets to write anything
  507. * in there. */
  508. s->unladdr[1] = value & (s->blocks - 1);
  509. break;
  510. case 0xf24d: /* Unlock End Block Address */
  511. s->unladdr[1] = value & (s->blocks - 1);
  512. break;
  513. default:
  514. fprintf(stderr, "%s: unknown OneNAND register %x\n",
  515. __FUNCTION__, offset);
  516. }
  517. }
  518. static CPUReadMemoryFunc *onenand_readfn[] = {
  519. onenand_read, /* TODO */
  520. onenand_read,
  521. onenand_read,
  522. };
  523. static CPUWriteMemoryFunc *onenand_writefn[] = {
  524. onenand_write, /* TODO */
  525. onenand_write,
  526. onenand_write,
  527. };
  528. void *onenand_init(uint32_t id, int regshift, qemu_irq irq)
  529. {
  530. struct onenand_s *s = (struct onenand_s *) qemu_mallocz(sizeof(*s));
  531. int bdrv_index = drive_get_index(IF_MTD, 0, 0);
  532. uint32_t size = 1 << (24 + ((id >> 12) & 7));
  533. void *ram;
  534. s->shift = regshift;
  535. s->intr = irq;
  536. s->rdy = 0;
  537. s->id = id;
  538. s->blocks = size >> BLOCK_SHIFT;
  539. s->secs = size >> 9;
  540. s->blockwp = qemu_malloc(s->blocks);
  541. s->density_mask = (id & (1 << 11)) ? (1 << (6 + ((id >> 12) & 7))) : 0;
  542. s->iomemtype = cpu_register_io_memory(0, onenand_readfn,
  543. onenand_writefn, s);
  544. if (bdrv_index == -1)
  545. s->image = memset(qemu_malloc(size + (size >> 5)),
  546. 0xff, size + (size >> 5));
  547. else
  548. s->bdrv = drives_table[bdrv_index].bdrv;
  549. s->otp = memset(qemu_malloc((64 + 2) << PAGE_SHIFT),
  550. 0xff, (64 + 2) << PAGE_SHIFT);
  551. s->ram = qemu_ram_alloc(0xc000 << s->shift);
  552. ram = phys_ram_base + s->ram;
  553. s->boot[0] = ram + (0x0000 << s->shift);
  554. s->boot[1] = ram + (0x8000 << s->shift);
  555. s->data[0][0] = ram + ((0x0200 + (0 << (PAGE_SHIFT - 1))) << s->shift);
  556. s->data[0][1] = ram + ((0x8010 + (0 << (PAGE_SHIFT - 6))) << s->shift);
  557. s->data[1][0] = ram + ((0x0200 + (1 << (PAGE_SHIFT - 1))) << s->shift);
  558. s->data[1][1] = ram + ((0x8010 + (1 << (PAGE_SHIFT - 6))) << s->shift);
  559. onenand_reset(s, 1);
  560. return s;
  561. }
  562. void *onenand_raw_otp(void *opaque)
  563. {
  564. struct onenand_s *s = (struct onenand_s *) opaque;
  565. return s->otp;
  566. }