2 * OneNAND flash memories emulation.
4 * Copyright (C) 2008 Nokia Corporation
5 * Written by Andrzej Zaborowski <andrew@openedhand.com>
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.
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.
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/>.
21 #include "qemu-common.h"
26 /* 11 for 2kB-page OneNAND ("2nd generation") and 10 for 1kB-page chips */
30 #define BLOCK_SHIFT (PAGE_SHIFT + 6)
35 target_phys_addr_t base;
38 BlockDriverState *bdrv;
39 BlockDriverState *bdrv_cur;
72 ONEN_BUF_DEST_BLOCK = 2,
73 ONEN_BUF_DEST_PAGE = 3,
78 ONEN_ERR_CMD = 1 << 10,
79 ONEN_ERR_ERASE = 1 << 11,
80 ONEN_ERR_PROG = 1 << 12,
81 ONEN_ERR_LOAD = 1 << 13,
85 ONEN_INT_RESET = 1 << 4,
86 ONEN_INT_ERASE = 1 << 5,
87 ONEN_INT_PROG = 1 << 6,
88 ONEN_INT_LOAD = 1 << 7,
93 ONEN_LOCK_LOCKTIGHTEN = 1 << 0,
94 ONEN_LOCK_LOCKED = 1 << 1,
95 ONEN_LOCK_UNLOCKED = 1 << 2,
98 void onenand_base_update(void *opaque, target_phys_addr_t new)
100 OneNANDState *s = (OneNANDState *) opaque;
104 /* XXX: We should use IO_MEM_ROMD but we broke it earlier...
105 * Both 0x0000 ... 0x01ff and 0x8000 ... 0x800f can be used to
106 * write boot commands. Also take note of the BWPS bit. */
107 cpu_register_physical_memory(s->base + (0x0000 << s->shift),
108 0x0200 << s->shift, s->iomemtype);
109 cpu_register_physical_memory(s->base + (0x0200 << s->shift),
111 (s->ram +(0x0200 << s->shift)) | IO_MEM_RAM);
113 cpu_register_physical_memory_offset(s->base + (0xc000 << s->shift),
114 0x4000 << s->shift, s->iomemtype, (0xc000 << s->shift));
117 void onenand_base_unmap(void *opaque)
119 OneNANDState *s = (OneNANDState *) opaque;
121 cpu_register_physical_memory(s->base,
122 0x10000 << s->shift, IO_MEM_UNASSIGNED);
125 static void onenand_intr_update(OneNANDState *s)
127 qemu_set_irq(s->intr, ((s->intstatus >> 15) ^ (~s->config[0] >> 6)) & 1);
130 /* Hot reset (Reset OneNAND command) or warm reset (RP pin low) */
131 static void onenand_reset(OneNANDState *s, int cold)
133 memset(&s->addr, 0, sizeof(s->addr));
137 s->config[0] = 0x40c0;
138 s->config[1] = 0x0000;
139 onenand_intr_update(s);
140 qemu_irq_raise(s->rdy);
142 s->intstatus = cold ? 0x8080 : 0x8010;
145 s->wpstatus = 0x0002;
148 s->bdrv_cur = s->bdrv;
149 s->current = s->image;
150 s->secs_cur = s->secs;
153 /* Lock the whole flash */
154 memset(s->blockwp, ONEN_LOCK_LOCKED, s->blocks);
156 if (s->bdrv && bdrv_read(s->bdrv, 0, s->boot[0], 8) < 0)
157 hw_error("%s: Loading the BootRAM failed.\n", __FUNCTION__);
161 static inline int onenand_load_main(OneNANDState *s, int sec, int secn,
165 return bdrv_read(s->bdrv_cur, sec, dest, secn) < 0;
166 else if (sec + secn > s->secs_cur)
169 memcpy(dest, s->current + (sec << 9), secn << 9);
174 static inline int onenand_prog_main(OneNANDState *s, int sec, int secn,
178 return bdrv_write(s->bdrv_cur, sec, src, secn) < 0;
179 else if (sec + secn > s->secs_cur)
182 memcpy(s->current + (sec << 9), src, secn << 9);
187 static inline int onenand_load_spare(OneNANDState *s, int sec, int secn,
193 if (bdrv_read(s->bdrv_cur, s->secs_cur + (sec >> 5), buf, 1) < 0)
195 memcpy(dest, buf + ((sec & 31) << 4), secn << 4);
196 } else if (sec + secn > s->secs_cur)
199 memcpy(dest, s->current + (s->secs_cur << 9) + (sec << 4), secn << 4);
204 static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn,
210 if (bdrv_read(s->bdrv_cur, s->secs_cur + (sec >> 5), buf, 1) < 0)
212 memcpy(buf + ((sec & 31) << 4), src, secn << 4);
213 return bdrv_write(s->bdrv_cur, s->secs_cur + (sec >> 5), buf, 1) < 0;
214 } else if (sec + secn > s->secs_cur)
217 memcpy(s->current + (s->secs_cur << 9) + (sec << 4), src, secn << 4);
222 static inline int onenand_erase(OneNANDState *s, int sec, int num)
227 memset(buf, 0xff, sizeof(buf));
228 for (; num > 0; num --, sec ++) {
229 if (onenand_prog_main(s, sec, 1, buf))
231 if (onenand_prog_spare(s, sec, 1, buf))
238 static void onenand_command(OneNANDState *s, int cmd)
243 #define SETADDR(block, page) \
244 sec = (s->addr[page] & 3) + \
245 ((((s->addr[page] >> 2) & 0x3f) + \
246 (((s->addr[block] & 0xfff) | \
247 (s->addr[block] >> 15 ? \
248 s->density_mask : 0)) << 6)) << (PAGE_SHIFT - 9));
250 buf = (s->bufaddr & 8) ? \
251 s->data[(s->bufaddr >> 2) & 1][0] : s->boot[0]; \
252 buf += (s->bufaddr & 3) << 9;
254 buf = (s->bufaddr & 8) ? \
255 s->data[(s->bufaddr >> 2) & 1][1] : s->boot[1]; \
256 buf += (s->bufaddr & 3) << 4;
259 case 0x00: /* Load single/multiple sector data unit into buffer */
260 SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
263 if (onenand_load_main(s, sec, s->count, buf))
264 s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD;
268 if (onenand_load_spare(s, sec, s->count, buf))
269 s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD;
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.
276 s->intstatus |= ONEN_INT | ONEN_INT_LOAD;
278 case 0x13: /* Load single/multiple spare sector into buffer */
279 SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
282 if (onenand_load_spare(s, sec, s->count, buf))
283 s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD;
285 /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
286 * or if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
287 * then we need two split the read/write into two chunks.
289 s->intstatus |= ONEN_INT | ONEN_INT_LOAD;
291 case 0x80: /* Program single/multiple sector data unit from buffer */
292 SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
295 if (onenand_prog_main(s, sec, s->count, buf))
296 s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
300 if (onenand_prog_spare(s, sec, s->count, buf))
301 s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
304 /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
305 * or if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
306 * then we need two split the read/write into two chunks.
308 s->intstatus |= ONEN_INT | ONEN_INT_PROG;
310 case 0x1a: /* Program single/multiple spare area sector from buffer */
311 SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
314 if (onenand_prog_spare(s, sec, s->count, buf))
315 s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
317 /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
318 * or if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
319 * then we need two split the read/write into two chunks.
321 s->intstatus |= ONEN_INT | ONEN_INT_PROG;
323 case 0x1b: /* Copy-back program */
326 SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
327 if (onenand_load_main(s, sec, s->count, buf))
328 s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
330 SETADDR(ONEN_BUF_DEST_BLOCK, ONEN_BUF_DEST_PAGE)
331 if (onenand_prog_main(s, sec, s->count, buf))
332 s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
334 /* TODO: spare areas */
336 s->intstatus |= ONEN_INT | ONEN_INT_PROG;
339 case 0x23: /* Unlock NAND array block(s) */
340 s->intstatus |= ONEN_INT;
342 /* XXX the previous (?) area should be locked automatically */
343 for (b = s->unladdr[0]; b <= s->unladdr[1]; b ++) {
344 if (b >= s->blocks) {
345 s->status |= ONEN_ERR_CMD;
348 if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
351 s->wpstatus = s->blockwp[b] = ONEN_LOCK_UNLOCKED;
354 case 0x27: /* Unlock All NAND array blocks */
355 s->intstatus |= ONEN_INT;
357 for (b = 0; b < s->blocks; b ++) {
358 if (b >= s->blocks) {
359 s->status |= ONEN_ERR_CMD;
362 if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
365 s->wpstatus = s->blockwp[b] = ONEN_LOCK_UNLOCKED;
369 case 0x2a: /* Lock NAND array block(s) */
370 s->intstatus |= ONEN_INT;
372 for (b = s->unladdr[0]; b <= s->unladdr[1]; b ++) {
373 if (b >= s->blocks) {
374 s->status |= ONEN_ERR_CMD;
377 if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
380 s->wpstatus = s->blockwp[b] = ONEN_LOCK_LOCKED;
383 case 0x2c: /* Lock-tight NAND array block(s) */
384 s->intstatus |= ONEN_INT;
386 for (b = s->unladdr[0]; b <= s->unladdr[1]; b ++) {
387 if (b >= s->blocks) {
388 s->status |= ONEN_ERR_CMD;
391 if (s->blockwp[b] == ONEN_LOCK_UNLOCKED)
394 s->wpstatus = s->blockwp[b] = ONEN_LOCK_LOCKTIGHTEN;
398 case 0x71: /* Erase-Verify-Read */
399 s->intstatus |= ONEN_INT;
401 case 0x95: /* Multi-block erase */
402 qemu_irq_pulse(s->intr);
404 case 0x94: /* Block erase */
405 sec = ((s->addr[ONEN_BUF_BLOCK] & 0xfff) |
406 (s->addr[ONEN_BUF_BLOCK] >> 15 ? s->density_mask : 0))
407 << (BLOCK_SHIFT - 9);
408 if (onenand_erase(s, sec, 1 << (BLOCK_SHIFT - 9)))
409 s->status |= ONEN_ERR_CMD | ONEN_ERR_ERASE;
411 s->intstatus |= ONEN_INT | ONEN_INT_ERASE;
413 case 0xb0: /* Erase suspend */
415 case 0x30: /* Erase resume */
416 s->intstatus |= ONEN_INT | ONEN_INT_ERASE;
419 case 0xf0: /* Reset NAND Flash core */
422 case 0xf3: /* Reset OneNAND */
426 case 0x65: /* OTP Access */
427 s->intstatus |= ONEN_INT;
430 s->secs_cur = 1 << (BLOCK_SHIFT - 9);
431 s->addr[ONEN_BUF_BLOCK] = 0;
436 s->status |= ONEN_ERR_CMD;
437 s->intstatus |= ONEN_INT;
438 fprintf(stderr, "%s: unknown OneNAND command %x\n",
442 onenand_intr_update(s);
445 static uint32_t onenand_read(void *opaque, target_phys_addr_t addr)
447 OneNANDState *s = (OneNANDState *) opaque;
448 int offset = addr >> s->shift;
451 case 0x0000 ... 0xc000:
452 return lduw_le_p(s->boot[0] + addr);
454 case 0xf000: /* Manufacturer ID */
455 return (s->id >> 16) & 0xff;
456 case 0xf001: /* Device ID */
457 return (s->id >> 8) & 0xff;
458 /* TODO: get the following values from a real chip! */
459 case 0xf002: /* Version ID */
460 return (s->id >> 0) & 0xff;
461 case 0xf003: /* Data Buffer size */
462 return 1 << PAGE_SHIFT;
463 case 0xf004: /* Boot Buffer size */
465 case 0xf005: /* Amount of buffers */
467 case 0xf006: /* Technology */
470 case 0xf100 ... 0xf107: /* Start addresses */
471 return s->addr[offset - 0xf100];
473 case 0xf200: /* Start buffer */
474 return (s->bufaddr << 8) | ((s->count - 1) & (1 << (PAGE_SHIFT - 10)));
476 case 0xf220: /* Command */
478 case 0xf221: /* System Configuration 1 */
479 return s->config[0] & 0xffe0;
480 case 0xf222: /* System Configuration 2 */
483 case 0xf240: /* Controller Status */
485 case 0xf241: /* Interrupt */
487 case 0xf24c: /* Unlock Start Block Address */
488 return s->unladdr[0];
489 case 0xf24d: /* Unlock End Block Address */
490 return s->unladdr[1];
491 case 0xf24e: /* Write Protection Status */
494 case 0xff00: /* ECC Status */
496 case 0xff01: /* ECC Result of main area data */
497 case 0xff02: /* ECC Result of spare area data */
498 case 0xff03: /* ECC Result of main area data */
499 case 0xff04: /* ECC Result of spare area data */
500 hw_error("%s: imeplement ECC\n", __FUNCTION__);
504 fprintf(stderr, "%s: unknown OneNAND register %x\n",
505 __FUNCTION__, offset);
509 static void onenand_write(void *opaque, target_phys_addr_t addr,
512 OneNANDState *s = (OneNANDState *) opaque;
513 int offset = addr >> s->shift;
517 case 0x0000 ... 0x01ff:
518 case 0x8000 ... 0x800f:
522 if (value == 0x0000) {
523 SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
524 onenand_load_main(s, sec,
525 1 << (PAGE_SHIFT - 9), s->data[0][0]);
526 s->addr[ONEN_BUF_PAGE] += 4;
527 s->addr[ONEN_BUF_PAGE] &= 0xff;
533 case 0x00f0: /* Reset OneNAND */
537 case 0x00e0: /* Load Data into Buffer */
541 case 0x0090: /* Read Identification Data */
542 memset(s->boot[0], 0, 3 << s->shift);
543 s->boot[0][0 << s->shift] = (s->id >> 16) & 0xff;
544 s->boot[0][1 << s->shift] = (s->id >> 8) & 0xff;
545 s->boot[0][2 << s->shift] = s->wpstatus & 0xff;
549 fprintf(stderr, "%s: unknown OneNAND boot command %x\n",
550 __FUNCTION__, value);
554 case 0xf100 ... 0xf107: /* Start addresses */
555 s->addr[offset - 0xf100] = value;
558 case 0xf200: /* Start buffer */
559 s->bufaddr = (value >> 8) & 0xf;
560 if (PAGE_SHIFT == 11)
561 s->count = (value & 3) ?: 4;
562 else if (PAGE_SHIFT == 10)
563 s->count = (value & 1) ?: 2;
566 case 0xf220: /* Command */
567 if (s->intstatus & (1 << 15))
570 onenand_command(s, s->command);
572 case 0xf221: /* System Configuration 1 */
573 s->config[0] = value;
574 onenand_intr_update(s);
575 qemu_set_irq(s->rdy, (s->config[0] >> 7) & 1);
577 case 0xf222: /* System Configuration 2 */
578 s->config[1] = value;
581 case 0xf241: /* Interrupt */
582 s->intstatus &= value;
583 if ((1 << 15) & ~s->intstatus)
584 s->status &= ~(ONEN_ERR_CMD | ONEN_ERR_ERASE |
585 ONEN_ERR_PROG | ONEN_ERR_LOAD);
586 onenand_intr_update(s);
588 case 0xf24c: /* Unlock Start Block Address */
589 s->unladdr[0] = value & (s->blocks - 1);
590 /* For some reason we have to set the end address to by default
591 * be same as start because the software forgets to write anything
593 s->unladdr[1] = value & (s->blocks - 1);
595 case 0xf24d: /* Unlock End Block Address */
596 s->unladdr[1] = value & (s->blocks - 1);
600 fprintf(stderr, "%s: unknown OneNAND register %x\n",
601 __FUNCTION__, offset);
605 static CPUReadMemoryFunc * const onenand_readfn[] = {
606 onenand_read, /* TODO */
611 static CPUWriteMemoryFunc * const onenand_writefn[] = {
612 onenand_write, /* TODO */
617 void *onenand_init(uint32_t id, int regshift, qemu_irq irq)
619 OneNANDState *s = (OneNANDState *) qemu_mallocz(sizeof(*s));
620 DriveInfo *dinfo = drive_get(IF_MTD, 0, 0);
621 uint32_t size = 1 << (24 + ((id >> 12) & 7));
628 s->blocks = size >> BLOCK_SHIFT;
630 s->blockwp = qemu_malloc(s->blocks);
631 s->density_mask = (id & (1 << 11)) ? (1 << (6 + ((id >> 12) & 7))) : 0;
632 s->iomemtype = cpu_register_io_memory(onenand_readfn,
635 s->image = memset(qemu_malloc(size + (size >> 5)),
636 0xff, size + (size >> 5));
638 s->bdrv = dinfo->bdrv;
639 s->otp = memset(qemu_malloc((64 + 2) << PAGE_SHIFT),
640 0xff, (64 + 2) << PAGE_SHIFT);
641 s->ram = qemu_ram_alloc(NULL, "onenand.ram", 0xc000 << s->shift);
642 ram = qemu_get_ram_ptr(s->ram);
643 s->boot[0] = ram + (0x0000 << s->shift);
644 s->boot[1] = ram + (0x8000 << s->shift);
645 s->data[0][0] = ram + ((0x0200 + (0 << (PAGE_SHIFT - 1))) << s->shift);
646 s->data[0][1] = ram + ((0x8010 + (0 << (PAGE_SHIFT - 6))) << s->shift);
647 s->data[1][0] = ram + ((0x0200 + (1 << (PAGE_SHIFT - 1))) << s->shift);
648 s->data[1][1] = ram + ((0x8010 + (1 << (PAGE_SHIFT - 6))) << s->shift);
655 void *onenand_raw_otp(void *opaque)
657 OneNANDState *s = (OneNANDState *) opaque;