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