onenand.c 19 KB

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