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