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