f7afecaaab51f0f9c11a2f0bba7e6274cdfe5e78
[sdk/emulator/qemu.git] / hw / onenand.c
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 "flash.h"
23 #include "irq.h"
24 #include "blockdev.h"
25
26 /* 11 for 2kB-page OneNAND ("2nd generation") and 10 for 1kB-page chips */
27 #define PAGE_SHIFT      11
28
29 /* Fixed */
30 #define BLOCK_SHIFT     (PAGE_SHIFT + 6)
31
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;
49
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;
59
60     ECCState ecc;
61
62     int density_mask;
63     int secs;
64     int secs_cur;
65     int blocks;
66     uint8_t *blockwp;
67 } OneNANDState;
68
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,
75 };
76
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,
82 };
83
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,
90 };
91
92 enum {
93     ONEN_LOCK_LOCKTIGHTEN = 1 << 0,
94     ONEN_LOCK_LOCKED = 1 << 1,
95     ONEN_LOCK_UNLOCKED = 1 << 2,
96 };
97
98 void onenand_base_update(void *opaque, target_phys_addr_t new)
99 {
100     OneNANDState *s = (OneNANDState *) opaque;
101
102     s->base = new;
103
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));
115 }
116
117 void onenand_base_unmap(void *opaque)
118 {
119     OneNANDState *s = (OneNANDState *) opaque;
120
121     cpu_register_physical_memory(s->base,
122                     0x10000 << s->shift, IO_MEM_UNASSIGNED);
123 }
124
125 static void onenand_intr_update(OneNANDState *s)
126 {
127     qemu_set_irq(s->intr, ((s->intstatus >> 15) ^ (~s->config[0] >> 6)) & 1);
128 }
129
130 /* Hot reset (Reset OneNAND command) or warm reset (RP pin low) */
131 static void onenand_reset(OneNANDState *s, int cold)
132 {
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;
151
152     if (cold) {
153         /* Lock the whole flash */
154         memset(s->blockwp, ONEN_LOCK_LOCKED, s->blocks);
155
156         if (s->bdrv && bdrv_read(s->bdrv, 0, s->boot[0], 8) < 0)
157             hw_error("%s: Loading the BootRAM failed.\n", __FUNCTION__);
158     }
159 }
160
161 static inline int onenand_load_main(OneNANDState *s, int sec, int secn,
162                 void *dest)
163 {
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;
168
169     memcpy(dest, s->current + (sec << 9), secn << 9);
170
171     return 0;
172 }
173
174 static inline int onenand_prog_main(OneNANDState *s, int sec, int secn,
175                 void *src)
176 {
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;
181
182     memcpy(s->current + (sec << 9), src, secn << 9);
183
184     return 0;
185 }
186
187 static inline int onenand_load_spare(OneNANDState *s, int sec, int secn,
188                 void *dest)
189 {
190     uint8_t buf[512];
191
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);
200  
201     return 0;
202 }
203
204 static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn,
205                 void *src)
206 {
207     uint8_t buf[512];
208
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;
216
217     memcpy(s->current + (s->secs_cur << 9) + (sec << 4), src, secn << 4);
218  
219     return 0;
220 }
221
222 static inline int onenand_erase(OneNANDState *s, int sec, int num)
223 {
224     /* TODO: optimise */
225     uint8_t buf[512];
226
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;
233     }
234
235     return 0;
236 }
237
238 static void onenand_command(OneNANDState *s, int cmd)
239 {
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;
257
258     switch (cmd) {
259     case 0x00:  /* Load single/multiple sector data unit into buffer */
260         SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
261
262         SETBUF_M()
263         if (onenand_load_main(s, sec, s->count, buf))
264             s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD;
265
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
271
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.
275          */
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)
280
281         SETBUF_S()
282         if (onenand_load_spare(s, sec, s->count, buf))
283             s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD;
284
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.
288          */
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)
293
294         SETBUF_M()
295         if (onenand_prog_main(s, sec, s->count, buf))
296             s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
297
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
303
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.
307          */
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)
312
313         SETBUF_S()
314         if (onenand_prog_spare(s, sec, s->count, buf))
315             s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
316
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.
320          */
321         s->intstatus |= ONEN_INT | ONEN_INT_PROG;
322         break;
323     case 0x1b:  /* Copy-back program */
324         SETBUF_S()
325
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;
329
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;
333
334         /* TODO: spare areas */
335
336         s->intstatus |= ONEN_INT | ONEN_INT_PROG;
337         break;
338
339     case 0x23:  /* Unlock NAND array block(s) */
340         s->intstatus |= ONEN_INT;
341
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;
347             }
348             if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
349                 break;
350
351             s->wpstatus = s->blockwp[b] = ONEN_LOCK_UNLOCKED;
352         }
353         break;
354     case 0x27:  /* Unlock All NAND array blocks */
355         s->intstatus |= ONEN_INT;
356
357         for (b = 0; b < s->blocks; b ++) {
358             if (b >= s->blocks) {
359                 s->status |= ONEN_ERR_CMD;
360                 break;
361             }
362             if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
363                 break;
364
365             s->wpstatus = s->blockwp[b] = ONEN_LOCK_UNLOCKED;
366         }
367         break;
368
369     case 0x2a:  /* Lock NAND array block(s) */
370         s->intstatus |= ONEN_INT;
371
372         for (b = s->unladdr[0]; b <= s->unladdr[1]; b ++) {
373             if (b >= s->blocks) {
374                 s->status |= ONEN_ERR_CMD;
375                 break;
376             }
377             if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
378                 break;
379
380             s->wpstatus = s->blockwp[b] = ONEN_LOCK_LOCKED;
381         }
382         break;
383     case 0x2c:  /* Lock-tight NAND array block(s) */
384         s->intstatus |= ONEN_INT;
385
386         for (b = s->unladdr[0]; b <= s->unladdr[1]; b ++) {
387             if (b >= s->blocks) {
388                 s->status |= ONEN_ERR_CMD;
389                 break;
390             }
391             if (s->blockwp[b] == ONEN_LOCK_UNLOCKED)
392                 continue;
393
394             s->wpstatus = s->blockwp[b] = ONEN_LOCK_LOCKTIGHTEN;
395         }
396         break;
397
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;
410
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;
418
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;
425
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;
434
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);
440     }
441
442     onenand_intr_update(s);
443 }
444
445 static uint32_t onenand_read(void *opaque, target_phys_addr_t addr)
446 {
447     OneNANDState *s = (OneNANDState *) opaque;
448     int offset = addr >> s->shift;
449
450     switch (offset) {
451     case 0x0000 ... 0xc000:
452         return lduw_le_p(s->boot[0] + addr);
453
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;
469
470     case 0xf100 ... 0xf107:     /* Start addresses */
471         return s->addr[offset - 0xf100];
472
473     case 0xf200:        /* Start buffer */
474         return (s->bufaddr << 8) | ((s->count - 1) & (1 << (PAGE_SHIFT - 10)));
475
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];
482
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;
493
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;
502     }
503
504     fprintf(stderr, "%s: unknown OneNAND register %x\n",
505                     __FUNCTION__, offset);
506     return 0;
507 }
508
509 static void onenand_write(void *opaque, target_phys_addr_t addr,
510                 uint32_t value)
511 {
512     OneNANDState *s = (OneNANDState *) opaque;
513     int offset = addr >> s->shift;
514     int sec;
515
516     switch (offset) {
517     case 0x0000 ... 0x01ff:
518     case 0x8000 ... 0x800f:
519         if (s->cycle) {
520             s->cycle = 0;
521
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;
528             }
529             break;
530         }
531
532         switch (value) {
533         case 0x00f0:    /* Reset OneNAND */
534             onenand_reset(s, 0);
535             break;
536
537         case 0x00e0:    /* Load Data into Buffer */
538             s->cycle = 1;
539             break;
540
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;
547
548         default:
549             fprintf(stderr, "%s: unknown OneNAND boot command %x\n",
550                             __FUNCTION__, value);
551         }
552         break;
553
554     case 0xf100 ... 0xf107:     /* Start addresses */
555         s->addr[offset - 0xf100] = value;
556         break;
557
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;
565
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;
580
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;
598
599     default:
600         fprintf(stderr, "%s: unknown OneNAND register %x\n",
601                         __FUNCTION__, offset);
602     }
603 }
604
605 static CPUReadMemoryFunc * const onenand_readfn[] = {
606     onenand_read,       /* TODO */
607     onenand_read,
608     onenand_read,
609 };
610
611 static CPUWriteMemoryFunc * const onenand_writefn[] = {
612     onenand_write,      /* TODO */
613     onenand_write,
614     onenand_write,
615 };
616
617 void *onenand_init(uint32_t id, int regshift, qemu_irq irq)
618 {
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;
623
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);
649
650     onenand_reset(s, 1);
651
652     return s;
653 }
654
655 void *onenand_raw_otp(void *opaque)
656 {
657     OneNANDState *s = (OneNANDState *) opaque;
658
659     return s->otp;
660 }