support xattr syscall in qemu-arm
[external/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 "hw.h"
23 #include "flash.h"
24 #include "irq.h"
25 #include "blockdev.h"
26
27 /* 11 for 2kB-page OneNAND ("2nd generation") and 10 for 1kB-page chips */
28 #define PAGE_SHIFT      11
29
30 /* Fixed */
31 #define BLOCK_SHIFT     (PAGE_SHIFT + 6)
32
33 typedef struct {
34     uint32_t id;
35     int shift;
36     target_phys_addr_t base;
37     qemu_irq intr;
38     qemu_irq rdy;
39     BlockDriverState *bdrv;
40     BlockDriverState *bdrv_cur;
41     uint8_t *image;
42     uint8_t *otp;
43     uint8_t *current;
44     ram_addr_t ram;
45     uint8_t *boot[2];
46     uint8_t *data[2][2];
47     int iomemtype;
48     int cycle;
49     int otpmode;
50
51     uint16_t addr[8];
52     uint16_t unladdr[8];
53     int bufaddr;
54     int count;
55     uint16_t command;
56     uint16_t config[2];
57     uint16_t status;
58     uint16_t intstatus;
59     uint16_t wpstatus;
60
61     ECCState ecc;
62
63     int density_mask;
64     int secs;
65     int secs_cur;
66     int blocks;
67     uint8_t *blockwp;
68 } OneNANDState;
69
70 enum {
71     ONEN_BUF_BLOCK = 0,
72     ONEN_BUF_BLOCK2 = 1,
73     ONEN_BUF_DEST_BLOCK = 2,
74     ONEN_BUF_DEST_PAGE = 3,
75     ONEN_BUF_PAGE = 7,
76 };
77
78 enum {
79     ONEN_ERR_CMD = 1 << 10,
80     ONEN_ERR_ERASE = 1 << 11,
81     ONEN_ERR_PROG = 1 << 12,
82     ONEN_ERR_LOAD = 1 << 13,
83 };
84
85 enum {
86     ONEN_INT_RESET = 1 << 4,
87     ONEN_INT_ERASE = 1 << 5,
88     ONEN_INT_PROG = 1 << 6,
89     ONEN_INT_LOAD = 1 << 7,
90     ONEN_INT = 1 << 15,
91 };
92
93 enum {
94     ONEN_LOCK_LOCKTIGHTEN = 1 << 0,
95     ONEN_LOCK_LOCKED = 1 << 1,
96     ONEN_LOCK_UNLOCKED = 1 << 2,
97 };
98
99 void onenand_base_update(void *opaque, target_phys_addr_t new)
100 {
101     OneNANDState *s = (OneNANDState *) opaque;
102
103     s->base = new;
104
105     /* XXX: We should use IO_MEM_ROMD but we broke it earlier...
106      * Both 0x0000 ... 0x01ff and 0x8000 ... 0x800f can be used to
107      * write boot commands.  Also take note of the BWPS bit.  */
108     cpu_register_physical_memory(s->base + (0x0000 << s->shift),
109                     0x0200 << s->shift, s->iomemtype);
110     cpu_register_physical_memory(s->base + (0x0200 << s->shift),
111                     0xbe00 << s->shift,
112                     (s->ram +(0x0200 << s->shift)) | IO_MEM_RAM);
113     if (s->iomemtype)
114         cpu_register_physical_memory_offset(s->base + (0xc000 << s->shift),
115                     0x4000 << s->shift, s->iomemtype, (0xc000 << s->shift));
116 }
117
118 void onenand_base_unmap(void *opaque)
119 {
120     OneNANDState *s = (OneNANDState *) opaque;
121
122     cpu_register_physical_memory(s->base,
123                     0x10000 << s->shift, IO_MEM_UNASSIGNED);
124 }
125
126 static void onenand_intr_update(OneNANDState *s)
127 {
128     qemu_set_irq(s->intr, ((s->intstatus >> 15) ^ (~s->config[0] >> 6)) & 1);
129 }
130
131 /* Hot reset (Reset OneNAND command) or warm reset (RP pin low) */
132 static void onenand_reset(OneNANDState *s, int cold)
133 {
134     memset(&s->addr, 0, sizeof(s->addr));
135     s->command = 0;
136     s->count = 1;
137     s->bufaddr = 0;
138     s->config[0] = 0x40c0;
139     s->config[1] = 0x0000;
140     onenand_intr_update(s);
141     qemu_irq_raise(s->rdy);
142     s->status = 0x0000;
143     s->intstatus = cold ? 0x8080 : 0x8010;
144     s->unladdr[0] = 0;
145     s->unladdr[1] = 0;
146     s->wpstatus = 0x0002;
147     s->cycle = 0;
148     s->otpmode = 0;
149     s->bdrv_cur = s->bdrv;
150     s->current = s->image;
151     s->secs_cur = s->secs;
152
153     if (cold) {
154         /* Lock the whole flash */
155         memset(s->blockwp, ONEN_LOCK_LOCKED, s->blocks);
156
157         if (s->bdrv && bdrv_read(s->bdrv, 0, s->boot[0], 8) < 0)
158             hw_error("%s: Loading the BootRAM failed.\n", __FUNCTION__);
159     }
160 }
161
162 static inline int onenand_load_main(OneNANDState *s, int sec, int secn,
163                 void *dest)
164 {
165     if (s->bdrv_cur)
166         return bdrv_read(s->bdrv_cur, sec, dest, secn) < 0;
167     else if (sec + secn > s->secs_cur)
168         return 1;
169
170     memcpy(dest, s->current + (sec << 9), secn << 9);
171
172     return 0;
173 }
174
175 static inline int onenand_prog_main(OneNANDState *s, int sec, int secn,
176                 void *src)
177 {
178     if (s->bdrv_cur)
179         return bdrv_write(s->bdrv_cur, sec, src, secn) < 0;
180     else if (sec + secn > s->secs_cur)
181         return 1;
182
183     memcpy(s->current + (sec << 9), src, secn << 9);
184
185     return 0;
186 }
187
188 static inline int onenand_load_spare(OneNANDState *s, int sec, int secn,
189                 void *dest)
190 {
191     uint8_t buf[512];
192
193     if (s->bdrv_cur) {
194         if (bdrv_read(s->bdrv_cur, s->secs_cur + (sec >> 5), buf, 1) < 0)
195             return 1;
196         memcpy(dest, buf + ((sec & 31) << 4), secn << 4);
197     } else if (sec + secn > s->secs_cur)
198         return 1;
199     else
200         memcpy(dest, s->current + (s->secs_cur << 9) + (sec << 4), secn << 4);
201  
202     return 0;
203 }
204
205 static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn,
206                 void *src)
207 {
208     uint8_t buf[512];
209
210     if (s->bdrv_cur) {
211         if (bdrv_read(s->bdrv_cur, s->secs_cur + (sec >> 5), buf, 1) < 0)
212             return 1;
213         memcpy(buf + ((sec & 31) << 4), src, secn << 4);
214         return bdrv_write(s->bdrv_cur, s->secs_cur + (sec >> 5), buf, 1) < 0;
215     } else if (sec + secn > s->secs_cur)
216         return 1;
217
218     memcpy(s->current + (s->secs_cur << 9) + (sec << 4), src, secn << 4);
219  
220     return 0;
221 }
222
223 static inline int onenand_erase(OneNANDState *s, int sec, int num)
224 {
225     /* TODO: optimise */
226     uint8_t buf[512];
227
228     memset(buf, 0xff, sizeof(buf));
229     for (; num > 0; num --, sec ++) {
230         if (onenand_prog_main(s, sec, 1, buf))
231             return 1;
232         if (onenand_prog_spare(s, sec, 1, buf))
233             return 1;
234     }
235
236     return 0;
237 }
238
239 static void onenand_command(OneNANDState *s, int cmd)
240 {
241     int b;
242     int sec;
243     void *buf;
244 #define SETADDR(block, page)                    \
245     sec = (s->addr[page] & 3) +                 \
246             ((((s->addr[page] >> 2) & 0x3f) +   \
247               (((s->addr[block] & 0xfff) |      \
248                 (s->addr[block] >> 15 ?         \
249                  s->density_mask : 0)) << 6)) << (PAGE_SHIFT - 9));
250 #define SETBUF_M()                              \
251     buf = (s->bufaddr & 8) ?                    \
252             s->data[(s->bufaddr >> 2) & 1][0] : s->boot[0];     \
253     buf += (s->bufaddr & 3) << 9;
254 #define SETBUF_S()                              \
255     buf = (s->bufaddr & 8) ?                    \
256             s->data[(s->bufaddr >> 2) & 1][1] : s->boot[1];     \
257     buf += (s->bufaddr & 3) << 4;
258
259     switch (cmd) {
260     case 0x00:  /* Load single/multiple sector data unit into buffer */
261         SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
262
263         SETBUF_M()
264         if (onenand_load_main(s, sec, s->count, buf))
265             s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD;
266
267 #if 0
268         SETBUF_S()
269         if (onenand_load_spare(s, sec, s->count, buf))
270             s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD;
271 #endif
272
273         /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
274          * or    if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
275          * then we need two split the read/write into two chunks.
276          */
277         s->intstatus |= ONEN_INT | ONEN_INT_LOAD;
278         break;
279     case 0x13:  /* Load single/multiple spare sector into buffer */
280         SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
281
282         SETBUF_S()
283         if (onenand_load_spare(s, sec, s->count, buf))
284             s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD;
285
286         /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
287          * or    if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
288          * then we need two split the read/write into two chunks.
289          */
290         s->intstatus |= ONEN_INT | ONEN_INT_LOAD;
291         break;
292     case 0x80:  /* Program single/multiple sector data unit from buffer */
293         SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
294
295         SETBUF_M()
296         if (onenand_prog_main(s, sec, s->count, buf))
297             s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
298
299 #if 0
300         SETBUF_S()
301         if (onenand_prog_spare(s, sec, s->count, buf))
302             s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
303 #endif
304
305         /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
306          * or    if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
307          * then we need two split the read/write into two chunks.
308          */
309         s->intstatus |= ONEN_INT | ONEN_INT_PROG;
310         break;
311     case 0x1a:  /* Program single/multiple spare area sector from buffer */
312         SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
313
314         SETBUF_S()
315         if (onenand_prog_spare(s, sec, s->count, buf))
316             s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
317
318         /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
319          * or    if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
320          * then we need two split the read/write into two chunks.
321          */
322         s->intstatus |= ONEN_INT | ONEN_INT_PROG;
323         break;
324     case 0x1b:  /* Copy-back program */
325         SETBUF_S()
326
327         SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
328         if (onenand_load_main(s, sec, s->count, buf))
329             s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
330
331         SETADDR(ONEN_BUF_DEST_BLOCK, ONEN_BUF_DEST_PAGE)
332         if (onenand_prog_main(s, sec, s->count, buf))
333             s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
334
335         /* TODO: spare areas */
336
337         s->intstatus |= ONEN_INT | ONEN_INT_PROG;
338         break;
339
340     case 0x23:  /* Unlock NAND array block(s) */
341         s->intstatus |= ONEN_INT;
342
343         /* XXX the previous (?) area should be locked automatically */
344         for (b = s->unladdr[0]; b <= s->unladdr[1]; b ++) {
345             if (b >= s->blocks) {
346                 s->status |= ONEN_ERR_CMD;
347                 break;
348             }
349             if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
350                 break;
351
352             s->wpstatus = s->blockwp[b] = ONEN_LOCK_UNLOCKED;
353         }
354         break;
355     case 0x27:  /* Unlock All NAND array blocks */
356         s->intstatus |= ONEN_INT;
357
358         for (b = 0; b < s->blocks; b ++) {
359             if (b >= s->blocks) {
360                 s->status |= ONEN_ERR_CMD;
361                 break;
362             }
363             if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
364                 break;
365
366             s->wpstatus = s->blockwp[b] = ONEN_LOCK_UNLOCKED;
367         }
368         break;
369
370     case 0x2a:  /* Lock NAND array block(s) */
371         s->intstatus |= ONEN_INT;
372
373         for (b = s->unladdr[0]; b <= s->unladdr[1]; b ++) {
374             if (b >= s->blocks) {
375                 s->status |= ONEN_ERR_CMD;
376                 break;
377             }
378             if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
379                 break;
380
381             s->wpstatus = s->blockwp[b] = ONEN_LOCK_LOCKED;
382         }
383         break;
384     case 0x2c:  /* Lock-tight NAND array block(s) */
385         s->intstatus |= ONEN_INT;
386
387         for (b = s->unladdr[0]; b <= s->unladdr[1]; b ++) {
388             if (b >= s->blocks) {
389                 s->status |= ONEN_ERR_CMD;
390                 break;
391             }
392             if (s->blockwp[b] == ONEN_LOCK_UNLOCKED)
393                 continue;
394
395             s->wpstatus = s->blockwp[b] = ONEN_LOCK_LOCKTIGHTEN;
396         }
397         break;
398
399     case 0x71:  /* Erase-Verify-Read */
400         s->intstatus |= ONEN_INT;
401         break;
402     case 0x95:  /* Multi-block erase */
403         qemu_irq_pulse(s->intr);
404         /* Fall through.  */
405     case 0x94:  /* Block erase */
406         sec = ((s->addr[ONEN_BUF_BLOCK] & 0xfff) |
407                         (s->addr[ONEN_BUF_BLOCK] >> 15 ? s->density_mask : 0))
408                 << (BLOCK_SHIFT - 9);
409         if (onenand_erase(s, sec, 1 << (BLOCK_SHIFT - 9)))
410             s->status |= ONEN_ERR_CMD | ONEN_ERR_ERASE;
411
412         s->intstatus |= ONEN_INT | ONEN_INT_ERASE;
413         break;
414     case 0xb0:  /* Erase suspend */
415         break;
416     case 0x30:  /* Erase resume */
417         s->intstatus |= ONEN_INT | ONEN_INT_ERASE;
418         break;
419
420     case 0xf0:  /* Reset NAND Flash core */
421         onenand_reset(s, 0);
422         break;
423     case 0xf3:  /* Reset OneNAND */
424         onenand_reset(s, 0);
425         break;
426
427     case 0x65:  /* OTP Access */
428         s->intstatus |= ONEN_INT;
429         s->bdrv_cur = NULL;
430         s->current = s->otp;
431         s->secs_cur = 1 << (BLOCK_SHIFT - 9);
432         s->addr[ONEN_BUF_BLOCK] = 0;
433         s->otpmode = 1;
434         break;
435
436     default:
437         s->status |= ONEN_ERR_CMD;
438         s->intstatus |= ONEN_INT;
439         fprintf(stderr, "%s: unknown OneNAND command %x\n",
440                         __FUNCTION__, cmd);
441     }
442
443     onenand_intr_update(s);
444 }
445
446 static uint32_t onenand_read(void *opaque, target_phys_addr_t addr)
447 {
448     OneNANDState *s = (OneNANDState *) opaque;
449     int offset = addr >> s->shift;
450
451     switch (offset) {
452     case 0x0000 ... 0xc000:
453         return lduw_le_p(s->boot[0] + addr);
454
455     case 0xf000:        /* Manufacturer ID */
456         return (s->id >> 16) & 0xff;
457     case 0xf001:        /* Device ID */
458         return (s->id >>  8) & 0xff;
459     /* TODO: get the following values from a real chip!  */
460     case 0xf002:        /* Version ID */
461         return (s->id >>  0) & 0xff;
462     case 0xf003:        /* Data Buffer size */
463         return 1 << PAGE_SHIFT;
464     case 0xf004:        /* Boot Buffer size */
465         return 0x200;
466     case 0xf005:        /* Amount of buffers */
467         return 1 | (2 << 8);
468     case 0xf006:        /* Technology */
469         return 0;
470
471     case 0xf100 ... 0xf107:     /* Start addresses */
472         return s->addr[offset - 0xf100];
473
474     case 0xf200:        /* Start buffer */
475         return (s->bufaddr << 8) | ((s->count - 1) & (1 << (PAGE_SHIFT - 10)));
476
477     case 0xf220:        /* Command */
478         return s->command;
479     case 0xf221:        /* System Configuration 1 */
480         return s->config[0] & 0xffe0;
481     case 0xf222:        /* System Configuration 2 */
482         return s->config[1];
483
484     case 0xf240:        /* Controller Status */
485         return s->status;
486     case 0xf241:        /* Interrupt */
487         return s->intstatus;
488     case 0xf24c:        /* Unlock Start Block Address */
489         return s->unladdr[0];
490     case 0xf24d:        /* Unlock End Block Address */
491         return s->unladdr[1];
492     case 0xf24e:        /* Write Protection Status */
493         return s->wpstatus;
494
495     case 0xff00:        /* ECC Status */
496         return 0x00;
497     case 0xff01:        /* ECC Result of main area data */
498     case 0xff02:        /* ECC Result of spare area data */
499     case 0xff03:        /* ECC Result of main area data */
500     case 0xff04:        /* ECC Result of spare area data */
501         hw_error("%s: imeplement ECC\n", __FUNCTION__);
502         return 0x0000;
503     }
504
505     fprintf(stderr, "%s: unknown OneNAND register %x\n",
506                     __FUNCTION__, offset);
507     return 0;
508 }
509
510 static void onenand_write(void *opaque, target_phys_addr_t addr,
511                 uint32_t value)
512 {
513     OneNANDState *s = (OneNANDState *) opaque;
514     int offset = addr >> s->shift;
515     int sec;
516
517     switch (offset) {
518     case 0x0000 ... 0x01ff:
519     case 0x8000 ... 0x800f:
520         if (s->cycle) {
521             s->cycle = 0;
522
523             if (value == 0x0000) {
524                 SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
525                 onenand_load_main(s, sec,
526                                 1 << (PAGE_SHIFT - 9), s->data[0][0]);
527                 s->addr[ONEN_BUF_PAGE] += 4;
528                 s->addr[ONEN_BUF_PAGE] &= 0xff;
529             }
530             break;
531         }
532
533         switch (value) {
534         case 0x00f0:    /* Reset OneNAND */
535             onenand_reset(s, 0);
536             break;
537
538         case 0x00e0:    /* Load Data into Buffer */
539             s->cycle = 1;
540             break;
541
542         case 0x0090:    /* Read Identification Data */
543             memset(s->boot[0], 0, 3 << s->shift);
544             s->boot[0][0 << s->shift] = (s->id >> 16) & 0xff;
545             s->boot[0][1 << s->shift] = (s->id >>  8) & 0xff;
546             s->boot[0][2 << s->shift] = s->wpstatus & 0xff;
547             break;
548
549         default:
550             fprintf(stderr, "%s: unknown OneNAND boot command %x\n",
551                             __FUNCTION__, value);
552         }
553         break;
554
555     case 0xf100 ... 0xf107:     /* Start addresses */
556         s->addr[offset - 0xf100] = value;
557         break;
558
559     case 0xf200:        /* Start buffer */
560         s->bufaddr = (value >> 8) & 0xf;
561         if (PAGE_SHIFT == 11)
562             s->count = (value & 3) ?: 4;
563         else if (PAGE_SHIFT == 10)
564             s->count = (value & 1) ?: 2;
565         break;
566
567     case 0xf220:        /* Command */
568         if (s->intstatus & (1 << 15))
569             break;
570         s->command = value;
571         onenand_command(s, s->command);
572         break;
573     case 0xf221:        /* System Configuration 1 */
574         s->config[0] = value;
575         onenand_intr_update(s);
576         qemu_set_irq(s->rdy, (s->config[0] >> 7) & 1);
577         break;
578     case 0xf222:        /* System Configuration 2 */
579         s->config[1] = value;
580         break;
581
582     case 0xf241:        /* Interrupt */
583         s->intstatus &= value;
584         if ((1 << 15) & ~s->intstatus)
585             s->status &= ~(ONEN_ERR_CMD | ONEN_ERR_ERASE |
586                             ONEN_ERR_PROG | ONEN_ERR_LOAD);
587         onenand_intr_update(s);
588         break;
589     case 0xf24c:        /* Unlock Start Block Address */
590         s->unladdr[0] = value & (s->blocks - 1);
591         /* For some reason we have to set the end address to by default
592          * be same as start because the software forgets to write anything
593          * in there.  */
594         s->unladdr[1] = value & (s->blocks - 1);
595         break;
596     case 0xf24d:        /* Unlock End Block Address */
597         s->unladdr[1] = value & (s->blocks - 1);
598         break;
599
600     default:
601         fprintf(stderr, "%s: unknown OneNAND register %x\n",
602                         __FUNCTION__, offset);
603     }
604 }
605
606 static CPUReadMemoryFunc * const onenand_readfn[] = {
607     onenand_read,       /* TODO */
608     onenand_read,
609     onenand_read,
610 };
611
612 static CPUWriteMemoryFunc * const onenand_writefn[] = {
613     onenand_write,      /* TODO */
614     onenand_write,
615     onenand_write,
616 };
617
618 void *onenand_init(uint32_t id, int regshift, qemu_irq irq)
619 {
620     OneNANDState *s = (OneNANDState *) qemu_mallocz(sizeof(*s));
621     DriveInfo *dinfo = drive_get(IF_MTD, 0, 0);
622     uint32_t size = 1 << (24 + ((id >> 12) & 7));
623     void *ram;
624
625     s->shift = regshift;
626     s->intr = irq;
627     s->rdy = NULL;
628     s->id = id;
629     s->blocks = size >> BLOCK_SHIFT;
630     s->secs = size >> 9;
631     s->blockwp = qemu_malloc(s->blocks);
632     s->density_mask = (id & (1 << 11)) ? (1 << (6 + ((id >> 12) & 7))) : 0;
633     s->iomemtype = cpu_register_io_memory(onenand_readfn,
634                     onenand_writefn, s, DEVICE_NATIVE_ENDIAN);
635     if (!dinfo)
636         s->image = memset(qemu_malloc(size + (size >> 5)),
637                         0xff, size + (size >> 5));
638     else
639         s->bdrv = dinfo->bdrv;
640     s->otp = memset(qemu_malloc((64 + 2) << PAGE_SHIFT),
641                     0xff, (64 + 2) << PAGE_SHIFT);
642     s->ram = qemu_ram_alloc(NULL, "onenand.ram", 0xc000 << s->shift);
643     ram = qemu_get_ram_ptr(s->ram);
644     s->boot[0] = ram + (0x0000 << s->shift);
645     s->boot[1] = ram + (0x8000 << s->shift);
646     s->data[0][0] = ram + ((0x0200 + (0 << (PAGE_SHIFT - 1))) << s->shift);
647     s->data[0][1] = ram + ((0x8010 + (0 << (PAGE_SHIFT - 6))) << s->shift);
648     s->data[1][0] = ram + ((0x0200 + (1 << (PAGE_SHIFT - 1))) << s->shift);
649     s->data[1][1] = ram + ((0x8010 + (1 << (PAGE_SHIFT - 6))) << s->shift);
650
651     onenand_reset(s, 1);
652
653     return s;
654 }
655
656 void *onenand_raw_otp(void *opaque)
657 {
658     OneNANDState *s = (OneNANDState *) opaque;
659
660     return s->otp;
661 }