xref: /illumos-kvm-cmd/hw/onenand.c (revision 68396ea9)
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 
onenand_base_update(void * opaque,target_phys_addr_t new)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 
onenand_base_unmap(void * opaque)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 
onenand_intr_update(OneNANDState * s)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) */
onenand_reset(OneNANDState * s,int cold)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 
onenand_load_main(OneNANDState * s,int sec,int secn,void * dest)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 
onenand_prog_main(OneNANDState * s,int sec,int secn,void * src)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 
onenand_load_spare(OneNANDState * s,int sec,int secn,void * dest)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 
onenand_prog_spare(OneNANDState * s,int sec,int secn,void * src)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 
onenand_erase(OneNANDState * s,int sec,int num)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 
onenand_command(OneNANDState * s,int cmd)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 
onenand_read(void * opaque,target_phys_addr_t addr)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 
onenand_write(void * opaque,target_phys_addr_t addr,uint32_t value)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 
onenand_init(uint32_t id,int regshift,qemu_irq irq)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 
onenand_raw_otp(void * opaque)656 void *onenand_raw_otp(void *opaque)
657 {
658     OneNANDState *s = (OneNANDState *) opaque;
659 
660     return s->otp;
661 }
662