xref: /openbmc/qemu/hw/block/onenand.c (revision 534f6ff9)
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 
21 #include "qemu-common.h"
22 #include "hw/hw.h"
23 #include "hw/block/flash.h"
24 #include "hw/irq.h"
25 #include "sysemu/blockdev.h"
26 #include "exec/memory.h"
27 #include "exec/address-spaces.h"
28 #include "hw/sysbus.h"
29 #include "qemu/error-report.h"
30 
31 /* 11 for 2kB-page OneNAND ("2nd generation") and 10 for 1kB-page chips */
32 #define PAGE_SHIFT	11
33 
34 /* Fixed */
35 #define BLOCK_SHIFT	(PAGE_SHIFT + 6)
36 
37 #define TYPE_ONE_NAND "onenand"
38 #define ONE_NAND(obj) OBJECT_CHECK(OneNANDState, (obj), TYPE_ONE_NAND)
39 
40 typedef struct OneNANDState {
41     SysBusDevice parent_obj;
42 
43     struct {
44         uint16_t man;
45         uint16_t dev;
46         uint16_t ver;
47     } id;
48     int shift;
49     hwaddr base;
50     qemu_irq intr;
51     qemu_irq rdy;
52     BlockDriverState *bdrv;
53     BlockDriverState *bdrv_cur;
54     uint8_t *image;
55     uint8_t *otp;
56     uint8_t *current;
57     MemoryRegion ram;
58     MemoryRegion mapped_ram;
59     uint8_t current_direction;
60     uint8_t *boot[2];
61     uint8_t *data[2][2];
62     MemoryRegion iomem;
63     MemoryRegion container;
64     int cycle;
65     int otpmode;
66 
67     uint16_t addr[8];
68     uint16_t unladdr[8];
69     int bufaddr;
70     int count;
71     uint16_t command;
72     uint16_t config[2];
73     uint16_t status;
74     uint16_t intstatus;
75     uint16_t wpstatus;
76 
77     ECCState ecc;
78 
79     int density_mask;
80     int secs;
81     int secs_cur;
82     int blocks;
83     uint8_t *blockwp;
84 } OneNANDState;
85 
86 enum {
87     ONEN_BUF_BLOCK = 0,
88     ONEN_BUF_BLOCK2 = 1,
89     ONEN_BUF_DEST_BLOCK = 2,
90     ONEN_BUF_DEST_PAGE = 3,
91     ONEN_BUF_PAGE = 7,
92 };
93 
94 enum {
95     ONEN_ERR_CMD = 1 << 10,
96     ONEN_ERR_ERASE = 1 << 11,
97     ONEN_ERR_PROG = 1 << 12,
98     ONEN_ERR_LOAD = 1 << 13,
99 };
100 
101 enum {
102     ONEN_INT_RESET = 1 << 4,
103     ONEN_INT_ERASE = 1 << 5,
104     ONEN_INT_PROG = 1 << 6,
105     ONEN_INT_LOAD = 1 << 7,
106     ONEN_INT = 1 << 15,
107 };
108 
109 enum {
110     ONEN_LOCK_LOCKTIGHTEN = 1 << 0,
111     ONEN_LOCK_LOCKED = 1 << 1,
112     ONEN_LOCK_UNLOCKED = 1 << 2,
113 };
114 
115 static void onenand_mem_setup(OneNANDState *s)
116 {
117     /* XXX: We should use IO_MEM_ROMD but we broke it earlier...
118      * Both 0x0000 ... 0x01ff and 0x8000 ... 0x800f can be used to
119      * write boot commands.  Also take note of the BWPS bit.  */
120     memory_region_init(&s->container, OBJECT(s), "onenand",
121                        0x10000 << s->shift);
122     memory_region_add_subregion(&s->container, 0, &s->iomem);
123     memory_region_init_alias(&s->mapped_ram, OBJECT(s), "onenand-mapped-ram",
124                              &s->ram, 0x0200 << s->shift,
125                              0xbe00 << s->shift);
126     memory_region_add_subregion_overlap(&s->container,
127                                         0x0200 << s->shift,
128                                         &s->mapped_ram,
129                                         1);
130 }
131 
132 static void onenand_intr_update(OneNANDState *s)
133 {
134     qemu_set_irq(s->intr, ((s->intstatus >> 15) ^ (~s->config[0] >> 6)) & 1);
135 }
136 
137 static void onenand_pre_save(void *opaque)
138 {
139     OneNANDState *s = opaque;
140     if (s->current == s->otp) {
141         s->current_direction = 1;
142     } else if (s->current == s->image) {
143         s->current_direction = 2;
144     } else {
145         s->current_direction = 0;
146     }
147 }
148 
149 static int onenand_post_load(void *opaque, int version_id)
150 {
151     OneNANDState *s = opaque;
152     switch (s->current_direction) {
153     case 0:
154         break;
155     case 1:
156         s->current = s->otp;
157         break;
158     case 2:
159         s->current = s->image;
160         break;
161     default:
162         return -1;
163     }
164     onenand_intr_update(s);
165     return 0;
166 }
167 
168 static const VMStateDescription vmstate_onenand = {
169     .name = "onenand",
170     .version_id = 1,
171     .minimum_version_id = 1,
172     .minimum_version_id_old = 1,
173     .pre_save = onenand_pre_save,
174     .post_load = onenand_post_load,
175     .fields = (VMStateField[]) {
176         VMSTATE_UINT8(current_direction, OneNANDState),
177         VMSTATE_INT32(cycle, OneNANDState),
178         VMSTATE_INT32(otpmode, OneNANDState),
179         VMSTATE_UINT16_ARRAY(addr, OneNANDState, 8),
180         VMSTATE_UINT16_ARRAY(unladdr, OneNANDState, 8),
181         VMSTATE_INT32(bufaddr, OneNANDState),
182         VMSTATE_INT32(count, OneNANDState),
183         VMSTATE_UINT16(command, OneNANDState),
184         VMSTATE_UINT16_ARRAY(config, OneNANDState, 2),
185         VMSTATE_UINT16(status, OneNANDState),
186         VMSTATE_UINT16(intstatus, OneNANDState),
187         VMSTATE_UINT16(wpstatus, OneNANDState),
188         VMSTATE_INT32(secs_cur, OneNANDState),
189         VMSTATE_PARTIAL_VBUFFER(blockwp, OneNANDState, blocks),
190         VMSTATE_UINT8(ecc.cp, OneNANDState),
191         VMSTATE_UINT16_ARRAY(ecc.lp, OneNANDState, 2),
192         VMSTATE_UINT16(ecc.count, OneNANDState),
193         VMSTATE_BUFFER_POINTER_UNSAFE(otp, OneNANDState, 0,
194             ((64 + 2) << PAGE_SHIFT)),
195         VMSTATE_END_OF_LIST()
196     }
197 };
198 
199 /* Hot reset (Reset OneNAND command) or warm reset (RP pin low) */
200 static void onenand_reset(OneNANDState *s, int cold)
201 {
202     memset(&s->addr, 0, sizeof(s->addr));
203     s->command = 0;
204     s->count = 1;
205     s->bufaddr = 0;
206     s->config[0] = 0x40c0;
207     s->config[1] = 0x0000;
208     onenand_intr_update(s);
209     qemu_irq_raise(s->rdy);
210     s->status = 0x0000;
211     s->intstatus = cold ? 0x8080 : 0x8010;
212     s->unladdr[0] = 0;
213     s->unladdr[1] = 0;
214     s->wpstatus = 0x0002;
215     s->cycle = 0;
216     s->otpmode = 0;
217     s->bdrv_cur = s->bdrv;
218     s->current = s->image;
219     s->secs_cur = s->secs;
220 
221     if (cold) {
222         /* Lock the whole flash */
223         memset(s->blockwp, ONEN_LOCK_LOCKED, s->blocks);
224 
225         if (s->bdrv_cur && bdrv_read(s->bdrv_cur, 0, s->boot[0], 8) < 0) {
226             hw_error("%s: Loading the BootRAM failed.\n", __func__);
227         }
228     }
229 }
230 
231 static void onenand_system_reset(DeviceState *dev)
232 {
233     OneNANDState *s = ONE_NAND(dev);
234 
235     onenand_reset(s, 1);
236 }
237 
238 static inline int onenand_load_main(OneNANDState *s, int sec, int secn,
239                 void *dest)
240 {
241     if (s->bdrv_cur)
242         return bdrv_read(s->bdrv_cur, sec, dest, secn) < 0;
243     else if (sec + secn > s->secs_cur)
244         return 1;
245 
246     memcpy(dest, s->current + (sec << 9), secn << 9);
247 
248     return 0;
249 }
250 
251 static inline int onenand_prog_main(OneNANDState *s, int sec, int secn,
252                 void *src)
253 {
254     int result = 0;
255 
256     if (secn > 0) {
257         uint32_t size = (uint32_t)secn * 512;
258         const uint8_t *sp = (const uint8_t *)src;
259         uint8_t *dp = 0;
260         if (s->bdrv_cur) {
261             dp = g_malloc(size);
262             if (!dp || bdrv_read(s->bdrv_cur, sec, dp, secn) < 0) {
263                 result = 1;
264             }
265         } else {
266             if (sec + secn > s->secs_cur) {
267                 result = 1;
268             } else {
269                 dp = (uint8_t *)s->current + (sec << 9);
270             }
271         }
272         if (!result) {
273             uint32_t i;
274             for (i = 0; i < size; i++) {
275                 dp[i] &= sp[i];
276             }
277             if (s->bdrv_cur) {
278                 result = bdrv_write(s->bdrv_cur, sec, dp, secn) < 0;
279             }
280         }
281         if (dp && s->bdrv_cur) {
282             g_free(dp);
283         }
284     }
285 
286     return result;
287 }
288 
289 static inline int onenand_load_spare(OneNANDState *s, int sec, int secn,
290                 void *dest)
291 {
292     uint8_t buf[512];
293 
294     if (s->bdrv_cur) {
295         if (bdrv_read(s->bdrv_cur, s->secs_cur + (sec >> 5), buf, 1) < 0)
296             return 1;
297         memcpy(dest, buf + ((sec & 31) << 4), secn << 4);
298     } else if (sec + secn > s->secs_cur)
299         return 1;
300     else
301         memcpy(dest, s->current + (s->secs_cur << 9) + (sec << 4), secn << 4);
302 
303     return 0;
304 }
305 
306 static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn,
307                 void *src)
308 {
309     int result = 0;
310     if (secn > 0) {
311         const uint8_t *sp = (const uint8_t *)src;
312         uint8_t *dp = 0, *dpp = 0;
313         if (s->bdrv_cur) {
314             dp = g_malloc(512);
315             if (!dp || bdrv_read(s->bdrv_cur,
316                                  s->secs_cur + (sec >> 5),
317                                  dp, 1) < 0) {
318                 result = 1;
319             } else {
320                 dpp = dp + ((sec & 31) << 4);
321             }
322         } else {
323             if (sec + secn > s->secs_cur) {
324                 result = 1;
325             } else {
326                 dpp = s->current + (s->secs_cur << 9) + (sec << 4);
327             }
328         }
329         if (!result) {
330             uint32_t i;
331             for (i = 0; i < (secn << 4); i++) {
332                 dpp[i] &= sp[i];
333             }
334             if (s->bdrv_cur) {
335                 result = bdrv_write(s->bdrv_cur, s->secs_cur + (sec >> 5),
336                                     dp, 1) < 0;
337             }
338         }
339         if (dp) {
340             g_free(dp);
341         }
342     }
343     return result;
344 }
345 
346 static inline int onenand_erase(OneNANDState *s, int sec, int num)
347 {
348     uint8_t *blankbuf, *tmpbuf;
349     blankbuf = g_malloc(512);
350     if (!blankbuf) {
351         return 1;
352     }
353     tmpbuf = g_malloc(512);
354     if (!tmpbuf) {
355         g_free(blankbuf);
356         return 1;
357     }
358     memset(blankbuf, 0xff, 512);
359     for (; num > 0; num--, sec++) {
360         if (s->bdrv_cur) {
361             int erasesec = s->secs_cur + (sec >> 5);
362             if (bdrv_write(s->bdrv_cur, sec, blankbuf, 1) < 0) {
363                 goto fail;
364             }
365             if (bdrv_read(s->bdrv_cur, erasesec, tmpbuf, 1) < 0) {
366                 goto fail;
367             }
368             memcpy(tmpbuf + ((sec & 31) << 4), blankbuf, 1 << 4);
369             if (bdrv_write(s->bdrv_cur, erasesec, tmpbuf, 1) < 0) {
370                 goto fail;
371             }
372         } else {
373             if (sec + 1 > s->secs_cur) {
374                 goto fail;
375             }
376             memcpy(s->current + (sec << 9), blankbuf, 512);
377             memcpy(s->current + (s->secs_cur << 9) + (sec << 4),
378                    blankbuf, 1 << 4);
379         }
380     }
381 
382     g_free(tmpbuf);
383     g_free(blankbuf);
384     return 0;
385 
386 fail:
387     g_free(tmpbuf);
388     g_free(blankbuf);
389     return 1;
390 }
391 
392 static void onenand_command(OneNANDState *s)
393 {
394     int b;
395     int sec;
396     void *buf;
397 #define SETADDR(block, page)			\
398     sec = (s->addr[page] & 3) +			\
399             ((((s->addr[page] >> 2) & 0x3f) +	\
400               (((s->addr[block] & 0xfff) |	\
401                 (s->addr[block] >> 15 ?		\
402                  s->density_mask : 0)) << 6)) << (PAGE_SHIFT - 9));
403 #define SETBUF_M()				\
404     buf = (s->bufaddr & 8) ?			\
405             s->data[(s->bufaddr >> 2) & 1][0] : s->boot[0];	\
406     buf += (s->bufaddr & 3) << 9;
407 #define SETBUF_S()				\
408     buf = (s->bufaddr & 8) ?			\
409             s->data[(s->bufaddr >> 2) & 1][1] : s->boot[1];	\
410     buf += (s->bufaddr & 3) << 4;
411 
412     switch (s->command) {
413     case 0x00:	/* Load single/multiple sector data unit into buffer */
414         SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
415 
416         SETBUF_M()
417         if (onenand_load_main(s, sec, s->count, buf))
418             s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD;
419 
420 #if 0
421         SETBUF_S()
422         if (onenand_load_spare(s, sec, s->count, buf))
423             s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD;
424 #endif
425 
426         /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
427          * or    if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
428          * then we need two split the read/write into two chunks.
429          */
430         s->intstatus |= ONEN_INT | ONEN_INT_LOAD;
431         break;
432     case 0x13:	/* Load single/multiple spare sector into buffer */
433         SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
434 
435         SETBUF_S()
436         if (onenand_load_spare(s, sec, s->count, buf))
437             s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD;
438 
439         /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
440          * or    if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
441          * then we need two split the read/write into two chunks.
442          */
443         s->intstatus |= ONEN_INT | ONEN_INT_LOAD;
444         break;
445     case 0x80:	/* Program single/multiple sector data unit from buffer */
446         SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
447 
448         SETBUF_M()
449         if (onenand_prog_main(s, sec, s->count, buf))
450             s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
451 
452 #if 0
453         SETBUF_S()
454         if (onenand_prog_spare(s, sec, s->count, buf))
455             s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
456 #endif
457 
458         /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
459          * or    if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
460          * then we need two split the read/write into two chunks.
461          */
462         s->intstatus |= ONEN_INT | ONEN_INT_PROG;
463         break;
464     case 0x1a:	/* Program single/multiple spare area sector from buffer */
465         SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
466 
467         SETBUF_S()
468         if (onenand_prog_spare(s, sec, s->count, buf))
469             s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
470 
471         /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
472          * or    if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
473          * then we need two split the read/write into two chunks.
474          */
475         s->intstatus |= ONEN_INT | ONEN_INT_PROG;
476         break;
477     case 0x1b:	/* Copy-back program */
478         SETBUF_S()
479 
480         SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
481         if (onenand_load_main(s, sec, s->count, buf))
482             s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
483 
484         SETADDR(ONEN_BUF_DEST_BLOCK, ONEN_BUF_DEST_PAGE)
485         if (onenand_prog_main(s, sec, s->count, buf))
486             s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
487 
488         /* TODO: spare areas */
489 
490         s->intstatus |= ONEN_INT | ONEN_INT_PROG;
491         break;
492 
493     case 0x23:	/* Unlock NAND array block(s) */
494         s->intstatus |= ONEN_INT;
495 
496         /* XXX the previous (?) area should be locked automatically */
497         for (b = s->unladdr[0]; b <= s->unladdr[1]; b ++) {
498             if (b >= s->blocks) {
499                 s->status |= ONEN_ERR_CMD;
500                 break;
501             }
502             if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
503                 break;
504 
505             s->wpstatus = s->blockwp[b] = ONEN_LOCK_UNLOCKED;
506         }
507         break;
508     case 0x27:	/* Unlock All NAND array blocks */
509         s->intstatus |= ONEN_INT;
510 
511         for (b = 0; b < s->blocks; b ++) {
512             if (b >= s->blocks) {
513                 s->status |= ONEN_ERR_CMD;
514                 break;
515             }
516             if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
517                 break;
518 
519             s->wpstatus = s->blockwp[b] = ONEN_LOCK_UNLOCKED;
520         }
521         break;
522 
523     case 0x2a:	/* Lock NAND array block(s) */
524         s->intstatus |= ONEN_INT;
525 
526         for (b = s->unladdr[0]; b <= s->unladdr[1]; b ++) {
527             if (b >= s->blocks) {
528                 s->status |= ONEN_ERR_CMD;
529                 break;
530             }
531             if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
532                 break;
533 
534             s->wpstatus = s->blockwp[b] = ONEN_LOCK_LOCKED;
535         }
536         break;
537     case 0x2c:	/* Lock-tight NAND array block(s) */
538         s->intstatus |= ONEN_INT;
539 
540         for (b = s->unladdr[0]; b <= s->unladdr[1]; b ++) {
541             if (b >= s->blocks) {
542                 s->status |= ONEN_ERR_CMD;
543                 break;
544             }
545             if (s->blockwp[b] == ONEN_LOCK_UNLOCKED)
546                 continue;
547 
548             s->wpstatus = s->blockwp[b] = ONEN_LOCK_LOCKTIGHTEN;
549         }
550         break;
551 
552     case 0x71:	/* Erase-Verify-Read */
553         s->intstatus |= ONEN_INT;
554         break;
555     case 0x95:	/* Multi-block erase */
556         qemu_irq_pulse(s->intr);
557         /* Fall through.  */
558     case 0x94:	/* Block erase */
559         sec = ((s->addr[ONEN_BUF_BLOCK] & 0xfff) |
560                         (s->addr[ONEN_BUF_BLOCK] >> 15 ? s->density_mask : 0))
561                 << (BLOCK_SHIFT - 9);
562         if (onenand_erase(s, sec, 1 << (BLOCK_SHIFT - 9)))
563             s->status |= ONEN_ERR_CMD | ONEN_ERR_ERASE;
564 
565         s->intstatus |= ONEN_INT | ONEN_INT_ERASE;
566         break;
567     case 0xb0:	/* Erase suspend */
568         break;
569     case 0x30:	/* Erase resume */
570         s->intstatus |= ONEN_INT | ONEN_INT_ERASE;
571         break;
572 
573     case 0xf0:	/* Reset NAND Flash core */
574         onenand_reset(s, 0);
575         break;
576     case 0xf3:	/* Reset OneNAND */
577         onenand_reset(s, 0);
578         break;
579 
580     case 0x65:	/* OTP Access */
581         s->intstatus |= ONEN_INT;
582         s->bdrv_cur = NULL;
583         s->current = s->otp;
584         s->secs_cur = 1 << (BLOCK_SHIFT - 9);
585         s->addr[ONEN_BUF_BLOCK] = 0;
586         s->otpmode = 1;
587         break;
588 
589     default:
590         s->status |= ONEN_ERR_CMD;
591         s->intstatus |= ONEN_INT;
592         fprintf(stderr, "%s: unknown OneNAND command %x\n",
593                         __func__, s->command);
594     }
595 
596     onenand_intr_update(s);
597 }
598 
599 static uint64_t onenand_read(void *opaque, hwaddr addr,
600                              unsigned size)
601 {
602     OneNANDState *s = (OneNANDState *) opaque;
603     int offset = addr >> s->shift;
604 
605     switch (offset) {
606     case 0x0000 ... 0xc000:
607         return lduw_le_p(s->boot[0] + addr);
608 
609     case 0xf000:	/* Manufacturer ID */
610         return s->id.man;
611     case 0xf001:	/* Device ID */
612         return s->id.dev;
613     case 0xf002:	/* Version ID */
614         return s->id.ver;
615     /* TODO: get the following values from a real chip!  */
616     case 0xf003:	/* Data Buffer size */
617         return 1 << PAGE_SHIFT;
618     case 0xf004:	/* Boot Buffer size */
619         return 0x200;
620     case 0xf005:	/* Amount of buffers */
621         return 1 | (2 << 8);
622     case 0xf006:	/* Technology */
623         return 0;
624 
625     case 0xf100 ... 0xf107:	/* Start addresses */
626         return s->addr[offset - 0xf100];
627 
628     case 0xf200:	/* Start buffer */
629         return (s->bufaddr << 8) | ((s->count - 1) & (1 << (PAGE_SHIFT - 10)));
630 
631     case 0xf220:	/* Command */
632         return s->command;
633     case 0xf221:	/* System Configuration 1 */
634         return s->config[0] & 0xffe0;
635     case 0xf222:	/* System Configuration 2 */
636         return s->config[1];
637 
638     case 0xf240:	/* Controller Status */
639         return s->status;
640     case 0xf241:	/* Interrupt */
641         return s->intstatus;
642     case 0xf24c:	/* Unlock Start Block Address */
643         return s->unladdr[0];
644     case 0xf24d:	/* Unlock End Block Address */
645         return s->unladdr[1];
646     case 0xf24e:	/* Write Protection Status */
647         return s->wpstatus;
648 
649     case 0xff00:	/* ECC Status */
650         return 0x00;
651     case 0xff01:	/* ECC Result of main area data */
652     case 0xff02:	/* ECC Result of spare area data */
653     case 0xff03:	/* ECC Result of main area data */
654     case 0xff04:	/* ECC Result of spare area data */
655         hw_error("%s: imeplement ECC\n", __FUNCTION__);
656         return 0x0000;
657     }
658 
659     fprintf(stderr, "%s: unknown OneNAND register %x\n",
660                     __FUNCTION__, offset);
661     return 0;
662 }
663 
664 static void onenand_write(void *opaque, hwaddr addr,
665                           uint64_t value, unsigned size)
666 {
667     OneNANDState *s = (OneNANDState *) opaque;
668     int offset = addr >> s->shift;
669     int sec;
670 
671     switch (offset) {
672     case 0x0000 ... 0x01ff:
673     case 0x8000 ... 0x800f:
674         if (s->cycle) {
675             s->cycle = 0;
676 
677             if (value == 0x0000) {
678                 SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
679                 onenand_load_main(s, sec,
680                                 1 << (PAGE_SHIFT - 9), s->data[0][0]);
681                 s->addr[ONEN_BUF_PAGE] += 4;
682                 s->addr[ONEN_BUF_PAGE] &= 0xff;
683             }
684             break;
685         }
686 
687         switch (value) {
688         case 0x00f0:	/* Reset OneNAND */
689             onenand_reset(s, 0);
690             break;
691 
692         case 0x00e0:	/* Load Data into Buffer */
693             s->cycle = 1;
694             break;
695 
696         case 0x0090:	/* Read Identification Data */
697             memset(s->boot[0], 0, 3 << s->shift);
698             s->boot[0][0 << s->shift] = s->id.man & 0xff;
699             s->boot[0][1 << s->shift] = s->id.dev & 0xff;
700             s->boot[0][2 << s->shift] = s->wpstatus & 0xff;
701             break;
702 
703         default:
704             fprintf(stderr, "%s: unknown OneNAND boot command %"PRIx64"\n",
705                             __FUNCTION__, value);
706         }
707         break;
708 
709     case 0xf100 ... 0xf107:	/* Start addresses */
710         s->addr[offset - 0xf100] = value;
711         break;
712 
713     case 0xf200:	/* Start buffer */
714         s->bufaddr = (value >> 8) & 0xf;
715         if (PAGE_SHIFT == 11)
716             s->count = (value & 3) ?: 4;
717         else if (PAGE_SHIFT == 10)
718             s->count = (value & 1) ?: 2;
719         break;
720 
721     case 0xf220:	/* Command */
722         if (s->intstatus & (1 << 15))
723             break;
724         s->command = value;
725         onenand_command(s);
726         break;
727     case 0xf221:	/* System Configuration 1 */
728         s->config[0] = value;
729         onenand_intr_update(s);
730         qemu_set_irq(s->rdy, (s->config[0] >> 7) & 1);
731         break;
732     case 0xf222:	/* System Configuration 2 */
733         s->config[1] = value;
734         break;
735 
736     case 0xf241:	/* Interrupt */
737         s->intstatus &= value;
738         if ((1 << 15) & ~s->intstatus)
739             s->status &= ~(ONEN_ERR_CMD | ONEN_ERR_ERASE |
740                             ONEN_ERR_PROG | ONEN_ERR_LOAD);
741         onenand_intr_update(s);
742         break;
743     case 0xf24c:	/* Unlock Start Block Address */
744         s->unladdr[0] = value & (s->blocks - 1);
745         /* For some reason we have to set the end address to by default
746          * be same as start because the software forgets to write anything
747          * in there.  */
748         s->unladdr[1] = value & (s->blocks - 1);
749         break;
750     case 0xf24d:	/* Unlock End Block Address */
751         s->unladdr[1] = value & (s->blocks - 1);
752         break;
753 
754     default:
755         fprintf(stderr, "%s: unknown OneNAND register %x\n",
756                         __FUNCTION__, offset);
757     }
758 }
759 
760 static const MemoryRegionOps onenand_ops = {
761     .read = onenand_read,
762     .write = onenand_write,
763     .endianness = DEVICE_NATIVE_ENDIAN,
764 };
765 
766 static int onenand_initfn(SysBusDevice *sbd)
767 {
768     DeviceState *dev = DEVICE(sbd);
769     OneNANDState *s = ONE_NAND(dev);
770     uint32_t size = 1 << (24 + ((s->id.dev >> 4) & 7));
771     void *ram;
772 
773     s->base = (hwaddr)-1;
774     s->rdy = NULL;
775     s->blocks = size >> BLOCK_SHIFT;
776     s->secs = size >> 9;
777     s->blockwp = g_malloc(s->blocks);
778     s->density_mask = (s->id.dev & 0x08)
779         ? (1 << (6 + ((s->id.dev >> 4) & 7))) : 0;
780     memory_region_init_io(&s->iomem, OBJECT(s), &onenand_ops, s, "onenand",
781                           0x10000 << s->shift);
782     if (!s->bdrv) {
783         s->image = memset(g_malloc(size + (size >> 5)),
784                           0xff, size + (size >> 5));
785     } else {
786         if (bdrv_is_read_only(s->bdrv)) {
787             error_report("Can't use a read-only drive");
788             return -1;
789         }
790         s->bdrv_cur = s->bdrv;
791     }
792     s->otp = memset(g_malloc((64 + 2) << PAGE_SHIFT),
793                     0xff, (64 + 2) << PAGE_SHIFT);
794     memory_region_init_ram(&s->ram, OBJECT(s), "onenand.ram",
795                            0xc000 << s->shift);
796     vmstate_register_ram_global(&s->ram);
797     ram = memory_region_get_ram_ptr(&s->ram);
798     s->boot[0] = ram + (0x0000 << s->shift);
799     s->boot[1] = ram + (0x8000 << s->shift);
800     s->data[0][0] = ram + ((0x0200 + (0 << (PAGE_SHIFT - 1))) << s->shift);
801     s->data[0][1] = ram + ((0x8010 + (0 << (PAGE_SHIFT - 6))) << s->shift);
802     s->data[1][0] = ram + ((0x0200 + (1 << (PAGE_SHIFT - 1))) << s->shift);
803     s->data[1][1] = ram + ((0x8010 + (1 << (PAGE_SHIFT - 6))) << s->shift);
804     onenand_mem_setup(s);
805     sysbus_init_irq(sbd, &s->intr);
806     sysbus_init_mmio(sbd, &s->container);
807     vmstate_register(dev,
808                      ((s->shift & 0x7f) << 24)
809                      | ((s->id.man & 0xff) << 16)
810                      | ((s->id.dev & 0xff) << 8)
811                      | (s->id.ver & 0xff),
812                      &vmstate_onenand, s);
813     return 0;
814 }
815 
816 static Property onenand_properties[] = {
817     DEFINE_PROP_UINT16("manufacturer_id", OneNANDState, id.man, 0),
818     DEFINE_PROP_UINT16("device_id", OneNANDState, id.dev, 0),
819     DEFINE_PROP_UINT16("version_id", OneNANDState, id.ver, 0),
820     DEFINE_PROP_INT32("shift", OneNANDState, shift, 0),
821     DEFINE_PROP_DRIVE("drive", OneNANDState, bdrv),
822     DEFINE_PROP_END_OF_LIST(),
823 };
824 
825 static void onenand_class_init(ObjectClass *klass, void *data)
826 {
827     DeviceClass *dc = DEVICE_CLASS(klass);
828     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
829 
830     k->init = onenand_initfn;
831     dc->reset = onenand_system_reset;
832     dc->props = onenand_properties;
833 }
834 
835 static const TypeInfo onenand_info = {
836     .name          = TYPE_ONE_NAND,
837     .parent        = TYPE_SYS_BUS_DEVICE,
838     .instance_size = sizeof(OneNANDState),
839     .class_init    = onenand_class_init,
840 };
841 
842 static void onenand_register_types(void)
843 {
844     type_register_static(&onenand_info);
845 }
846 
847 void *onenand_raw_otp(DeviceState *onenand_device)
848 {
849     OneNANDState *s = ONE_NAND(onenand_device);
850 
851     return s->otp;
852 }
853 
854 type_init(onenand_register_types)
855