pci: sorting out type confusion in pci_register_bar().
[qemu.git] / hw / onenand.c
blobf7afecaaab51f0f9c11a2f0bba7e6274cdfe5e78
1 /*
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"
22 #include "flash.h"
23 #include "irq.h"
24 #include "blockdev.h"
26 /* 11 for 2kB-page OneNAND ("2nd generation") and 10 for 1kB-page chips */
27 #define PAGE_SHIFT 11
29 /* Fixed */
30 #define BLOCK_SHIFT (PAGE_SHIFT + 6)
32 typedef struct {
33 uint32_t id;
34 int shift;
35 target_phys_addr_t base;
36 qemu_irq intr;
37 qemu_irq rdy;
38 BlockDriverState *bdrv;
39 BlockDriverState *bdrv_cur;
40 uint8_t *image;
41 uint8_t *otp;
42 uint8_t *current;
43 ram_addr_t ram;
44 uint8_t *boot[2];
45 uint8_t *data[2][2];
46 int iomemtype;
47 int cycle;
48 int otpmode;
50 uint16_t addr[8];
51 uint16_t unladdr[8];
52 int bufaddr;
53 int count;
54 uint16_t command;
55 uint16_t config[2];
56 uint16_t status;
57 uint16_t intstatus;
58 uint16_t wpstatus;
60 ECCState ecc;
62 int density_mask;
63 int secs;
64 int secs_cur;
65 int blocks;
66 uint8_t *blockwp;
67 } OneNANDState;
69 enum {
70 ONEN_BUF_BLOCK = 0,
71 ONEN_BUF_BLOCK2 = 1,
72 ONEN_BUF_DEST_BLOCK = 2,
73 ONEN_BUF_DEST_PAGE = 3,
74 ONEN_BUF_PAGE = 7,
77 enum {
78 ONEN_ERR_CMD = 1 << 10,
79 ONEN_ERR_ERASE = 1 << 11,
80 ONEN_ERR_PROG = 1 << 12,
81 ONEN_ERR_LOAD = 1 << 13,
84 enum {
85 ONEN_INT_RESET = 1 << 4,
86 ONEN_INT_ERASE = 1 << 5,
87 ONEN_INT_PROG = 1 << 6,
88 ONEN_INT_LOAD = 1 << 7,
89 ONEN_INT = 1 << 15,
92 enum {
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;
102 s->base = new;
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),
110 0xbe00 << s->shift,
111 (s->ram +(0x0200 << s->shift)) | IO_MEM_RAM);
112 if (s->iomemtype)
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));
134 s->command = 0;
135 s->count = 1;
136 s->bufaddr = 0;
137 s->config[0] = 0x40c0;
138 s->config[1] = 0x0000;
139 onenand_intr_update(s);
140 qemu_irq_raise(s->rdy);
141 s->status = 0x0000;
142 s->intstatus = cold ? 0x8080 : 0x8010;
143 s->unladdr[0] = 0;
144 s->unladdr[1] = 0;
145 s->wpstatus = 0x0002;
146 s->cycle = 0;
147 s->otpmode = 0;
148 s->bdrv_cur = s->bdrv;
149 s->current = s->image;
150 s->secs_cur = s->secs;
152 if (cold) {
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,
162 void *dest)
164 if (s->bdrv_cur)
165 return bdrv_read(s->bdrv_cur, sec, dest, secn) < 0;
166 else if (sec + secn > s->secs_cur)
167 return 1;
169 memcpy(dest, s->current + (sec << 9), secn << 9);
171 return 0;
174 static inline int onenand_prog_main(OneNANDState *s, int sec, int secn,
175 void *src)
177 if (s->bdrv_cur)
178 return bdrv_write(s->bdrv_cur, sec, src, secn) < 0;
179 else if (sec + secn > s->secs_cur)
180 return 1;
182 memcpy(s->current + (sec << 9), src, secn << 9);
184 return 0;
187 static inline int onenand_load_spare(OneNANDState *s, int sec, int secn,
188 void *dest)
190 uint8_t buf[512];
192 if (s->bdrv_cur) {
193 if (bdrv_read(s->bdrv_cur, s->secs_cur + (sec >> 5), buf, 1) < 0)
194 return 1;
195 memcpy(dest, buf + ((sec & 31) << 4), secn << 4);
196 } else if (sec + secn > s->secs_cur)
197 return 1;
198 else
199 memcpy(dest, s->current + (s->secs_cur << 9) + (sec << 4), secn << 4);
201 return 0;
204 static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn,
205 void *src)
207 uint8_t buf[512];
209 if (s->bdrv_cur) {
210 if (bdrv_read(s->bdrv_cur, s->secs_cur + (sec >> 5), buf, 1) < 0)
211 return 1;
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)
215 return 1;
217 memcpy(s->current + (s->secs_cur << 9) + (sec << 4), src, secn << 4);
219 return 0;
222 static inline int onenand_erase(OneNANDState *s, int sec, int num)
224 /* TODO: optimise */
225 uint8_t buf[512];
227 memset(buf, 0xff, sizeof(buf));
228 for (; num > 0; num --, sec ++) {
229 if (onenand_prog_main(s, sec, 1, buf))
230 return 1;
231 if (onenand_prog_spare(s, sec, 1, buf))
232 return 1;
235 return 0;
238 static void onenand_command(OneNANDState *s, int cmd)
240 int b;
241 int sec;
242 void *buf;
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));
249 #define SETBUF_M() \
250 buf = (s->bufaddr & 8) ? \
251 s->data[(s->bufaddr >> 2) & 1][0] : s->boot[0]; \
252 buf += (s->bufaddr & 3) << 9;
253 #define SETBUF_S() \
254 buf = (s->bufaddr & 8) ? \
255 s->data[(s->bufaddr >> 2) & 1][1] : s->boot[1]; \
256 buf += (s->bufaddr & 3) << 4;
258 switch (cmd) {
259 case 0x00: /* Load single/multiple sector data unit into buffer */
260 SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
262 SETBUF_M()
263 if (onenand_load_main(s, sec, s->count, buf))
264 s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD;
266 #if 0
267 SETBUF_S()
268 if (onenand_load_spare(s, sec, s->count, buf))
269 s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD;
270 #endif
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;
277 break;
278 case 0x13: /* Load single/multiple spare sector into buffer */
279 SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
281 SETBUF_S()
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;
290 break;
291 case 0x80: /* Program single/multiple sector data unit from buffer */
292 SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
294 SETBUF_M()
295 if (onenand_prog_main(s, sec, s->count, buf))
296 s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
298 #if 0
299 SETBUF_S()
300 if (onenand_prog_spare(s, sec, s->count, buf))
301 s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
302 #endif
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;
309 break;
310 case 0x1a: /* Program single/multiple spare area sector from buffer */
311 SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
313 SETBUF_S()
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;
322 break;
323 case 0x1b: /* Copy-back program */
324 SETBUF_S()
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;
337 break;
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;
346 break;
348 if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
349 break;
351 s->wpstatus = s->blockwp[b] = ONEN_LOCK_UNLOCKED;
353 break;
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;
360 break;
362 if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
363 break;
365 s->wpstatus = s->blockwp[b] = ONEN_LOCK_UNLOCKED;
367 break;
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;
375 break;
377 if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
378 break;
380 s->wpstatus = s->blockwp[b] = ONEN_LOCK_LOCKED;
382 break;
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;
389 break;
391 if (s->blockwp[b] == ONEN_LOCK_UNLOCKED)
392 continue;
394 s->wpstatus = s->blockwp[b] = ONEN_LOCK_LOCKTIGHTEN;
396 break;
398 case 0x71: /* Erase-Verify-Read */
399 s->intstatus |= ONEN_INT;
400 break;
401 case 0x95: /* Multi-block erase */
402 qemu_irq_pulse(s->intr);
403 /* Fall through. */
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;
412 break;
413 case 0xb0: /* Erase suspend */
414 break;
415 case 0x30: /* Erase resume */
416 s->intstatus |= ONEN_INT | ONEN_INT_ERASE;
417 break;
419 case 0xf0: /* Reset NAND Flash core */
420 onenand_reset(s, 0);
421 break;
422 case 0xf3: /* Reset OneNAND */
423 onenand_reset(s, 0);
424 break;
426 case 0x65: /* OTP Access */
427 s->intstatus |= ONEN_INT;
428 s->bdrv_cur = NULL;
429 s->current = s->otp;
430 s->secs_cur = 1 << (BLOCK_SHIFT - 9);
431 s->addr[ONEN_BUF_BLOCK] = 0;
432 s->otpmode = 1;
433 break;
435 default:
436 s->status |= ONEN_ERR_CMD;
437 s->intstatus |= ONEN_INT;
438 fprintf(stderr, "%s: unknown OneNAND command %x\n",
439 __FUNCTION__, cmd);
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;
450 switch (offset) {
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 */
464 return 0x200;
465 case 0xf005: /* Amount of buffers */
466 return 1 | (2 << 8);
467 case 0xf006: /* Technology */
468 return 0;
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 */
477 return s->command;
478 case 0xf221: /* System Configuration 1 */
479 return s->config[0] & 0xffe0;
480 case 0xf222: /* System Configuration 2 */
481 return s->config[1];
483 case 0xf240: /* Controller Status */
484 return s->status;
485 case 0xf241: /* Interrupt */
486 return s->intstatus;
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 */
492 return s->wpstatus;
494 case 0xff00: /* ECC Status */
495 return 0x00;
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__);
501 return 0x0000;
504 fprintf(stderr, "%s: unknown OneNAND register %x\n",
505 __FUNCTION__, offset);
506 return 0;
509 static void onenand_write(void *opaque, target_phys_addr_t addr,
510 uint32_t value)
512 OneNANDState *s = (OneNANDState *) opaque;
513 int offset = addr >> s->shift;
514 int sec;
516 switch (offset) {
517 case 0x0000 ... 0x01ff:
518 case 0x8000 ... 0x800f:
519 if (s->cycle) {
520 s->cycle = 0;
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;
529 break;
532 switch (value) {
533 case 0x00f0: /* Reset OneNAND */
534 onenand_reset(s, 0);
535 break;
537 case 0x00e0: /* Load Data into Buffer */
538 s->cycle = 1;
539 break;
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;
546 break;
548 default:
549 fprintf(stderr, "%s: unknown OneNAND boot command %x\n",
550 __FUNCTION__, value);
552 break;
554 case 0xf100 ... 0xf107: /* Start addresses */
555 s->addr[offset - 0xf100] = value;
556 break;
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;
564 break;
566 case 0xf220: /* Command */
567 if (s->intstatus & (1 << 15))
568 break;
569 s->command = value;
570 onenand_command(s, s->command);
571 break;
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);
576 break;
577 case 0xf222: /* System Configuration 2 */
578 s->config[1] = value;
579 break;
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);
587 break;
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
592 * in there. */
593 s->unladdr[1] = value & (s->blocks - 1);
594 break;
595 case 0xf24d: /* Unlock End Block Address */
596 s->unladdr[1] = value & (s->blocks - 1);
597 break;
599 default:
600 fprintf(stderr, "%s: unknown OneNAND register %x\n",
601 __FUNCTION__, offset);
605 static CPUReadMemoryFunc * const onenand_readfn[] = {
606 onenand_read, /* TODO */
607 onenand_read,
608 onenand_read,
611 static CPUWriteMemoryFunc * const onenand_writefn[] = {
612 onenand_write, /* TODO */
613 onenand_write,
614 onenand_write,
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));
622 void *ram;
624 s->shift = regshift;
625 s->intr = irq;
626 s->rdy = NULL;
627 s->id = id;
628 s->blocks = size >> BLOCK_SHIFT;
629 s->secs = size >> 9;
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,
633 onenand_writefn, s);
634 if (!dinfo)
635 s->image = memset(qemu_malloc(size + (size >> 5)),
636 0xff, size + (size >> 5));
637 else
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);
650 onenand_reset(s, 1);
652 return s;
655 void *onenand_raw_otp(void *opaque)
657 OneNANDState *s = (OneNANDState *) opaque;
659 return s->otp;