Merge branch 'master' of /home/nchip/public_html/qemu into garage-push
[qemu] / hw / nand.c
1 /*
2  * Flash NAND memory emulation.  Based on "16M x 8 Bit NAND Flash
3  * Memory" datasheet for the KM29U128AT / K9F2808U0A chips from
4  * Samsung Electronic.
5  *
6  * Copyright (c) 2006 Openedhand Ltd.
7  * Written by Andrzej Zaborowski <balrog@zabor.org>
8  *
9  * Support for additional features based on "MT29F2G16ABCWP 2Gx16"
10  * datasheet from Micron Technology and "NAND02G-B2C" datasheet
11  * from ST Microelectronics.
12  *
13  * This code is licensed under the GNU GPL v2.
14  */
15
16 #ifndef NAND_IO
17
18 # include "hw.h"
19 # include "flash.h"
20 # include "block.h"
21
22 # define NAND_CMD_READ0         0x00
23 # define NAND_CMD_READ1         0x01
24 # define NAND_CMD_READ2         0x50
25 # define NAND_CMD_LPREAD2       0x30
26 # define NAND_CMD_READCACHESTART 0x31
27 # define NAND_CMD_READCACHEEXIT  0x34
28 # define NAND_CMD_READCACHELAST  0x3f
29 # define NAND_CMD_NOSERIALREAD2 0x35
30 # define NAND_CMD_RANDOMREAD1   0x05
31 # define NAND_CMD_RANDOMREAD2   0xe0
32 # define NAND_CMD_READID        0x90
33 # define NAND_CMD_RESET         0xff
34 # define NAND_CMD_PAGEPROGRAM1  0x80
35 # define NAND_CMD_PAGEPROGRAM2  0x10
36 # define NAND_CMD_CACHEPROGRAM2 0x15
37 # define NAND_CMD_BLOCKERASE1   0x60
38 # define NAND_CMD_BLOCKERASE2   0xd0
39 # define NAND_CMD_READSTATUS    0x70
40 # define NAND_CMD_COPYBACKPRG1  0x85
41
42 # define NAND_IOSTATUS_ERROR    (1 << 0)
43 # define NAND_IOSTATUS_PLANE0   (1 << 1)
44 # define NAND_IOSTATUS_PLANE1   (1 << 2)
45 # define NAND_IOSTATUS_PLANE2   (1 << 3)
46 # define NAND_IOSTATUS_PLANE3   (1 << 4)
47 # define NAND_IOSTATUS_READY    (3 << 5)
48 # define NAND_IOSTATUS_UNPROTCT (1 << 7)
49
50 # define MAX_PAGE               0x800
51 # define MAX_OOB                0x40
52
53 struct NANDFlashState {
54     uint8_t manf_id, chip_id;
55     uint8_t buswidth; /* in BYTES */
56     int size, pages;
57     int page_shift, oob_shift, erase_shift, addr_shift;
58     uint8_t *storage;
59     BlockDriverState *bdrv;
60     int mem_oob;
61
62     int cle, ale, ce, wp, gnd;
63
64     uint8_t io[MAX_PAGE + MAX_OOB + 0x400];
65     uint8_t *ioaddr;
66     int iolen;
67
68     uint32_t cmd;
69     uint64_t addr;
70     int addrlen;
71     int status;
72     int offset;
73
74     void (*blk_write)(NANDFlashState *s);
75     void (*blk_erase)(NANDFlashState *s);
76     void (*blk_load)(NANDFlashState *s, uint64_t addr, int offset);
77 };
78
79 # define NAND_NO_AUTOINCR       0x00000001
80 # define NAND_BUSWIDTH_16       0x00000002
81 # define NAND_NO_PADDING        0x00000004
82 # define NAND_CACHEPRG          0x00000008
83 # define NAND_COPYBACK          0x00000010
84 # define NAND_IS_AND            0x00000020
85 # define NAND_4PAGE_ARRAY       0x00000040
86 # define NAND_NO_READRDY        0x00000100
87 # define NAND_SAMSUNG_LP        (NAND_NO_PADDING | NAND_COPYBACK)
88
89 # define NAND_IO
90
91 # define PAGE(addr)             ((addr) >> ADDR_SHIFT)
92 # define PAGE_START(page)       (PAGE(page) * (PAGE_SIZE + OOB_SIZE))
93 # define PAGE_MASK              ((1 << ADDR_SHIFT) - 1)
94 # define OOB_SHIFT              (PAGE_SHIFT - 5)
95 # define OOB_SIZE               (1 << OOB_SHIFT)
96 # define SECTOR(addr)           ((addr) >> (9 + ADDR_SHIFT - PAGE_SHIFT))
97 # define SECTOR_OFFSET(addr)    ((addr) & ((511 >> PAGE_SHIFT) << 8))
98
99 # define PAGE_SIZE              256
100 # define PAGE_SHIFT             8
101 # define PAGE_SECTORS           1
102 # define ADDR_SHIFT             8
103 # include "nand.c"
104 # define PAGE_SIZE              512
105 # define PAGE_SHIFT             9
106 # define PAGE_SECTORS           1
107 # define ADDR_SHIFT             8
108 # include "nand.c"
109 # define PAGE_SIZE              2048
110 # define PAGE_SHIFT             11
111 # define PAGE_SECTORS           4
112 # define ADDR_SHIFT             16
113 # include "nand.c"
114
115 /* Information based on Linux drivers/mtd/nand/nand_ids.c */
116 static const struct {
117     int size;
118     int width;
119     int page_shift;
120     int erase_shift;
121     uint32_t options;
122 } nand_flash_ids[0x100] = {
123     [0 ... 0xff] = { 0 },
124
125     [0x6e] = { 1,       8,      8, 4, 0 },
126     [0x64] = { 2,       8,      8, 4, 0 },
127     [0x6b] = { 4,       8,      9, 4, 0 },
128     [0xe8] = { 1,       8,      8, 4, 0 },
129     [0xec] = { 1,       8,      8, 4, 0 },
130     [0xea] = { 2,       8,      8, 4, 0 },
131     [0xd5] = { 4,       8,      9, 4, 0 },
132     [0xe3] = { 4,       8,      9, 4, 0 },
133     [0xe5] = { 4,       8,      9, 4, 0 },
134     [0xd6] = { 8,       8,      9, 4, 0 },
135
136     [0x39] = { 8,       8,      9, 4, 0 },
137     [0xe6] = { 8,       8,      9, 4, 0 },
138     [0x49] = { 8,       16,     9, 4, NAND_BUSWIDTH_16 },
139     [0x59] = { 8,       16,     9, 4, NAND_BUSWIDTH_16 },
140
141     [0x33] = { 16,      8,      9, 5, 0 },
142     [0x73] = { 16,      8,      9, 5, 0 },
143     [0x43] = { 16,      16,     9, 5, NAND_BUSWIDTH_16 },
144     [0x53] = { 16,      16,     9, 5, NAND_BUSWIDTH_16 },
145
146     [0x35] = { 32,      8,      9, 5, 0 },
147     [0x75] = { 32,      8,      9, 5, 0 },
148     [0x45] = { 32,      16,     9, 5, NAND_BUSWIDTH_16 },
149     [0x55] = { 32,      16,     9, 5, NAND_BUSWIDTH_16 },
150
151     [0x36] = { 64,      8,      9, 5, 0 },
152     [0x76] = { 64,      8,      9, 5, 0 },
153     [0x46] = { 64,      16,     9, 5, NAND_BUSWIDTH_16 },
154     [0x56] = { 64,      16,     9, 5, NAND_BUSWIDTH_16 },
155
156     [0x78] = { 128,     8,      9, 5, 0 },
157     [0x39] = { 128,     8,      9, 5, 0 },
158     [0x79] = { 128,     8,      9, 5, 0 },
159     [0x72] = { 128,     16,     9, 5, NAND_BUSWIDTH_16 },
160     [0x49] = { 128,     16,     9, 5, NAND_BUSWIDTH_16 },
161     [0x74] = { 128,     16,     9, 5, NAND_BUSWIDTH_16 },
162     [0x59] = { 128,     16,     9, 5, NAND_BUSWIDTH_16 },
163
164     [0x71] = { 256,     8,      9, 5, 0 },
165
166     /*
167      * These are the new chips with large page size. The pagesize and the
168      * erasesize is determined from the extended id bytes
169      */
170 # define LP_OPTIONS     (NAND_SAMSUNG_LP | NAND_NO_READRDY | NAND_NO_AUTOINCR)
171 # define LP_OPTIONS16   (LP_OPTIONS | NAND_BUSWIDTH_16)
172
173     /* 512 Megabit */
174     [0xa2] = { 64,      8,      0, 0, LP_OPTIONS },
175     [0xf2] = { 64,      8,      0, 0, LP_OPTIONS },
176     [0xb2] = { 64,      16,     0, 0, LP_OPTIONS16 },
177     [0xc2] = { 64,      16,     0, 0, LP_OPTIONS16 },
178
179     /* 1 Gigabit */
180     [0xa1] = { 128,     8,      0, 0, LP_OPTIONS },
181     [0xf1] = { 128,     8,      0, 0, LP_OPTIONS },
182     [0xb1] = { 128,     16,     0, 0, LP_OPTIONS16 },
183     [0xc1] = { 128,     16,     0, 0, LP_OPTIONS16 },
184
185     /* 2 Gigabit */
186     [0xaa] = { 256,     8,      0, 0, LP_OPTIONS },
187     [0xda] = { 256,     8,      0, 0, LP_OPTIONS },
188     [0xba] = { 256,     16,     0, 0, LP_OPTIONS16 },
189     [0xca] = { 256,     16,     0, 0, LP_OPTIONS16 },
190
191     /* 4 Gigabit */
192     [0xac] = { 512,     8,      0, 0, LP_OPTIONS },
193     [0xdc] = { 512,     8,      0, 0, LP_OPTIONS },
194     [0xbc] = { 512,     16,     0, 0, LP_OPTIONS16 },
195     [0xcc] = { 512,     16,     0, 0, LP_OPTIONS16 },
196
197     /* 8 Gigabit */
198     [0xa3] = { 1024,    8,      0, 0, LP_OPTIONS },
199     [0xd3] = { 1024,    8,      0, 0, LP_OPTIONS },
200     [0xb3] = { 1024,    16,     0, 0, LP_OPTIONS16 },
201     [0xc3] = { 1024,    16,     0, 0, LP_OPTIONS16 },
202
203     /* 16 Gigabit */
204     [0xa5] = { 2048,    8,      0, 0, LP_OPTIONS },
205     [0xd5] = { 2048,    8,      0, 0, LP_OPTIONS },
206     [0xb5] = { 2048,    16,     0, 0, LP_OPTIONS16 },
207     [0xc5] = { 2048,    16,     0, 0, LP_OPTIONS16 },
208 };
209
210 static void nand_reset(NANDFlashState *s)
211 {
212     s->cmd = NAND_CMD_READ0;
213     s->addr = 0;
214     s->addrlen = 0;
215     s->iolen = 0;
216     s->offset = 0;
217     s->status &= NAND_IOSTATUS_UNPROTCT;
218     s->status |= NAND_IOSTATUS_READY;
219 }
220
221 static inline void nand_pushio_byte(NANDFlashState *s, uint8_t value)
222 {
223     s->ioaddr[s->iolen++] = value;
224     for (value = s->buswidth; --value;)
225         s->ioaddr[s->iolen++] = 0;
226 }
227
228 static void nand_command(NANDFlashState *s)
229 {
230     switch (s->cmd) {
231     case NAND_CMD_READ0:
232     case NAND_CMD_READCACHEEXIT:
233         s->iolen = 0;
234         break;
235
236     case NAND_CMD_READID:
237         s->ioaddr = s->io;
238         s->iolen = 0;
239         nand_pushio_byte(s, s->manf_id);
240         nand_pushio_byte(s, s->chip_id);
241         nand_pushio_byte(s, 'Q'); /* Don't-case byte (often 0xa5) */
242         if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP)
243             nand_pushio_byte(s, (s->buswidth == 2) ? 0x55 : 0x15);
244         else
245             nand_pushio_byte(s, 0xc0); /* Multi-plane */
246         break;
247
248     case NAND_CMD_RANDOMREAD2:
249     case NAND_CMD_NOSERIALREAD2:
250         if (!(nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP))
251             break;
252
253         s->blk_load(s, s->addr, (int)(s->addr & ((1 << s->addr_shift) - 1)));
254         break;
255
256     case NAND_CMD_RESET:
257         nand_reset(s);
258         break;
259
260     case NAND_CMD_PAGEPROGRAM1:
261         s->ioaddr = s->io;
262         s->iolen = 0;
263         break;
264
265     case NAND_CMD_PAGEPROGRAM2:
266         if (s->wp) {
267             s->blk_write(s);
268         }
269         break;
270
271     case NAND_CMD_BLOCKERASE1:
272         break;
273
274     case NAND_CMD_BLOCKERASE2:
275         if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP)
276             s->addr <<= 16;
277         else
278             s->addr <<= 8;
279
280         if (s->wp) {
281             s->blk_erase(s);
282         }
283         break;
284
285     case NAND_CMD_READSTATUS:
286         s->ioaddr = s->io;
287         s->iolen = 0;
288         nand_pushio_byte(s, s->status);
289         break;
290
291     default:
292         printf("%s: Unknown NAND command 0x%02x\n", __FUNCTION__, s->cmd);
293     }
294 }
295
296 static void nand_save(QEMUFile *f, void *opaque)
297 {
298     NANDFlashState *s = (NANDFlashState *) opaque;
299     qemu_put_byte(f, s->cle);
300     qemu_put_byte(f, s->ale);
301     qemu_put_byte(f, s->ce);
302     qemu_put_byte(f, s->wp);
303     qemu_put_byte(f, s->gnd);
304     qemu_put_buffer(f, s->io, sizeof(s->io));
305     qemu_put_be32(f, s->ioaddr - s->io);
306     qemu_put_be32(f, s->iolen);
307
308     qemu_put_be32s(f, &s->cmd);
309     qemu_put_be64s(f, &s->addr);
310     qemu_put_be32(f, s->addrlen);
311     qemu_put_be32(f, s->status);
312     qemu_put_be32(f, s->offset);
313     /* XXX: do we want to save s->storage too? */
314 }
315
316 static int nand_load(QEMUFile *f, void *opaque, int version_id)
317 {
318     NANDFlashState *s = (NANDFlashState *) opaque;
319     s->cle = qemu_get_byte(f);
320     s->ale = qemu_get_byte(f);
321     s->ce = qemu_get_byte(f);
322     s->wp = qemu_get_byte(f);
323     s->gnd = qemu_get_byte(f);
324     qemu_get_buffer(f, s->io, sizeof(s->io));
325     s->ioaddr = s->io + qemu_get_be32(f);
326     s->iolen = qemu_get_be32(f);
327     if (s->ioaddr >= s->io + sizeof(s->io) || s->ioaddr < s->io)
328         return -EINVAL;
329
330     qemu_get_be32s(f, &s->cmd);
331     qemu_get_be64s(f, &s->addr);
332     s->addrlen = qemu_get_be32(f);
333     s->status = qemu_get_be32(f);
334     s->offset = qemu_get_be32(f);
335     return 0;
336 }
337
338 /*
339  * Chip inputs are CLE, ALE, CE, WP, GND and eight I/O pins.  Chip
340  * outputs are R/B and eight I/O pins.
341  *
342  * CE, WP and R/B are active low.
343  */
344 void nand_setpins(NANDFlashState *s,
345                 int cle, int ale, int ce, int wp, int gnd)
346 {
347     s->cle = cle;
348     s->ale = ale;
349     s->ce = ce;
350     s->wp = wp;
351     s->gnd = gnd;
352     if (wp)
353         s->status |= NAND_IOSTATUS_UNPROTCT;
354     else
355         s->status &= ~NAND_IOSTATUS_UNPROTCT;
356 }
357
358 void nand_getpins(NANDFlashState *s, int *rb)
359 {
360     *rb = 1;
361 }
362
363 void nand_setio(NANDFlashState *s, uint32_t value)
364 {
365     int i;
366     
367     if (!s->ce && s->cle) {
368         if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) {
369             if (s->cmd == NAND_CMD_READ0 
370                 && (value == NAND_CMD_LPREAD2
371                     || value == NAND_CMD_READCACHESTART
372                     || value == NAND_CMD_READCACHELAST))
373                 return;
374             if (value == NAND_CMD_RANDOMREAD1) {
375                 s->addr &= ~((1 << s->addr_shift) - 1);
376                 s->addrlen = 0;
377                 return;
378             }
379         }
380         if (value == NAND_CMD_READ0)
381             s->offset = 0;
382         else if (value == NAND_CMD_READ1) {
383             s->offset = 0x100;
384             value = NAND_CMD_READ0;
385         }
386         else if (value == NAND_CMD_READ2) {
387             s->offset = 1 << s->page_shift;
388             value = NAND_CMD_READ0;
389         }
390
391         s->cmd = value;
392
393         if (s->cmd == NAND_CMD_READSTATUS ||
394                 s->cmd == NAND_CMD_PAGEPROGRAM2 ||
395                 s->cmd == NAND_CMD_BLOCKERASE1 ||
396                 s->cmd == NAND_CMD_BLOCKERASE2 ||
397                 s->cmd == NAND_CMD_NOSERIALREAD2 ||
398                 s->cmd == NAND_CMD_RANDOMREAD2 ||
399                 s->cmd == NAND_CMD_RESET ||
400             s->cmd == NAND_CMD_READCACHEEXIT)
401             nand_command(s);
402
403         if (s->cmd != NAND_CMD_RANDOMREAD2) {
404             s->addrlen = 0;
405             s->addr = 0;
406         }
407     }
408
409     if (s->ale) {
410         s->addr |= value << (s->addrlen * 8);
411         s->addrlen ++;
412
413         switch (s->addrlen) {
414             case 1:
415                 if (s->cmd == NAND_CMD_READID)
416                     nand_command(s);
417                 break;
418             case 2: /* fix cache address as a byte address */
419                 s->addr <<= (s->buswidth - 1);
420                 break;
421             case 3:
422                 if (!(nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP)
423                     && (s->cmd == NAND_CMD_READ0
424                         || s->cmd == NAND_CMD_PAGEPROGRAM1))
425                     nand_command(s);
426                 break;
427             case 4:
428                 if ((nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP)
429                     && nand_flash_ids[s->chip_id].size < 256 /* 1Gb or less */
430                     && (s->cmd == NAND_CMD_READ0 ||
431                         s->cmd == NAND_CMD_PAGEPROGRAM1))
432                     nand_command(s);
433                 break;
434             case 5:
435                 if ((nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP)
436                     && nand_flash_ids[s->chip_id].size >= 256 /* 2Gb or more */
437                     && (s->cmd == NAND_CMD_READ0 ||
438                         s->cmd == NAND_CMD_PAGEPROGRAM1))
439                     nand_command(s);
440                 break;
441             default:
442                 break;
443         }
444     }
445
446     if (!s->cle && !s->ale && s->cmd == NAND_CMD_PAGEPROGRAM1) {
447         if (s->iolen < (1 << s->page_shift) + (1 << s->oob_shift))
448             for (i = s->buswidth; i--; value >>= 8)
449                 s->io[s->iolen++] = (uint8_t)(value & 0xff);
450     } else if (!s->cle && !s->ale && s->cmd == NAND_CMD_COPYBACKPRG1) {
451         if ((s->addr & ((1 << s->addr_shift) - 1)) <
452                 (1 << s->page_shift) + (1 << s->oob_shift))
453             for (i = s->buswidth; i--; s->addr++, value >>= 8)
454                 s->io[s->iolen + (s->addr & ((1 << s->addr_shift) - 1))] =
455                     (uint8_t)(value & 0xff);
456     }
457 }
458
459 uint32_t nand_getio(NANDFlashState *s)
460 {
461     int offset;
462     uint32_t x = 0;
463
464     /* Allow sequential reading */
465     if (!s->iolen && s->cmd == NAND_CMD_READ0) {
466         offset = (int)((s->addr & ((1 << s->addr_shift) - 1))) + s->offset;
467         s->offset = 0;
468
469         s->blk_load(s, s->addr, offset);
470         if (s->gnd)
471             s->iolen = (1 << s->page_shift) - offset;
472         else
473             s->iolen = (1 << s->page_shift) + (1 << s->oob_shift) - offset;
474     }
475
476     if (s->ce || s->iolen <= 0)
477         return 0;
478
479     for (offset = s->buswidth; offset--;)
480         x |= s->ioaddr[offset] << (offset << 3);
481     /* after receiving READ STATUS command all subsequent reads will
482        return the status register value until another command is issued */
483     if (s->cmd != NAND_CMD_READSTATUS) {
484         s->ioaddr += s->buswidth;
485         s->iolen  -= s->buswidth;
486     }
487     return x;
488 }
489
490 uint32_t nand_getbuswidth(NANDFlashState *s)
491 {
492     if (!s)
493         return 0;
494     return (s->buswidth << 3);
495 }
496
497 NANDFlashState *nand_init(int manf_id, int chip_id, BlockDriverState *bdrv)
498 {
499     int pagesize;
500     NANDFlashState *s;
501
502     if (nand_flash_ids[chip_id].size == 0) {
503         hw_error("%s: Unsupported NAND chip ID.\n", __FUNCTION__);
504     }
505
506     s = (NANDFlashState *) qemu_mallocz(sizeof(NANDFlashState));
507     s->bdrv = bdrv;
508     s->manf_id = manf_id;
509     s->chip_id = chip_id;
510     s->buswidth = (uint8_t)(nand_flash_ids[s->chip_id].width >> 3);
511     s->size = nand_flash_ids[s->chip_id].size << 20;
512     if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) {
513         s->page_shift = 11;
514         s->erase_shift = 6;
515     } else {
516         s->page_shift = nand_flash_ids[s->chip_id].page_shift;
517         s->erase_shift = nand_flash_ids[s->chip_id].erase_shift;
518     }
519
520     switch (1 << s->page_shift) {
521     case 256:
522         nand_init_256(s);
523         break;
524     case 512:
525         nand_init_512(s);
526         break;
527     case 2048:
528         nand_init_2048(s);
529         break;
530     default:
531         hw_error("%s: Unsupported NAND block size.\n", __FUNCTION__);
532     }
533
534     pagesize = 1 << s->oob_shift;
535     s->mem_oob = 1;
536     if (s->bdrv && bdrv_getlength(s->bdrv) >=
537                     (s->pages << s->page_shift) + (s->pages << s->oob_shift)) {
538         pagesize = 0;
539         s->mem_oob = 0;
540     }
541
542     if (!s->bdrv)
543         pagesize += 1 << s->page_shift;
544     if (pagesize)
545         s->storage = (uint8_t *) memset(qemu_malloc(s->pages * pagesize),
546                         0xff, s->pages * pagesize);
547     /* Give s->ioaddr a sane value in case we save state before it
548        is used.  */
549     s->ioaddr = s->io;
550
551     register_savevm("nand", -1, 0, nand_save, nand_load, s);
552
553     return s;
554 }
555
556 void nand_done(NANDFlashState *s)
557 {
558     if (s->bdrv) {
559         bdrv_close(s->bdrv);
560         bdrv_delete(s->bdrv);
561     }
562
563     if (!s->bdrv || s->mem_oob)
564         free(s->storage);
565
566     free(s);
567 }
568
569 #else
570
571 /* Program a single page */
572 static void glue(nand_blk_write_, PAGE_SIZE)(NANDFlashState *s)
573 {
574     uint64_t off, page, sector, soff;
575     uint8_t iobuf[(PAGE_SECTORS + 2) * 0x200];
576     if (PAGE(s->addr) >= s->pages)
577         return;
578
579     if (!s->bdrv) {
580         uint8_t *p = s->storage + PAGE_START(s->addr) + (s->addr & PAGE_MASK) +
581                      s->offset;
582         int i;
583         for (i = 0; i < s->iolen; i++) {
584             p[i] &= s->io[i];
585         }
586     } else if (s->mem_oob) {
587         sector = SECTOR(s->addr);
588         off = (s->addr & PAGE_MASK) + s->offset;
589         soff = SECTOR_OFFSET(s->addr);
590         if (bdrv_read(s->bdrv, sector, iobuf, PAGE_SECTORS) == -1) {
591             printf("%s: read error in sector %lli\n", __FUNCTION__, sector);
592             return;
593         }
594
595         uint8_t *p = iobuf + (soff | off);
596         int i, count = MIN(s->iolen, PAGE_SIZE - off);
597         for (i = 0; i < count; i++) {
598             p[i] &= s->io[i];
599         }
600         if (off + s->iolen > PAGE_SIZE) {
601             page = PAGE(s->addr);
602             p = s->storage + (page << OOB_SHIFT);
603             uint8_t *q = s->io + PAGE_SIZE - off;
604             count = MIN(OOB_SIZE, off + s->iolen - PAGE_SIZE);
605             for (i = 0; i < count; i++) {
606                 p[i] &= q[i];
607             }
608         }
609
610         if (bdrv_write(s->bdrv, sector, iobuf, PAGE_SECTORS) == -1)
611             printf("%s: write error in sector %lli\n", __FUNCTION__, sector);
612     } else {
613         off = PAGE_START(s->addr) + (s->addr & PAGE_MASK) + s->offset;
614         sector = off >> 9;
615         soff = off & 0x1ff;
616         if (bdrv_read(s->bdrv, sector, iobuf, PAGE_SECTORS + 2) == -1) {
617             printf("%s: read error in sector %lli\n", __FUNCTION__, sector);
618             return;
619         }
620
621         uint8_t *p = iobuf + soff;
622         int i;
623         for (i = 0; i < s->iolen; i++) {
624             p[i] &= s->io[i];
625         }
626
627         if (bdrv_write(s->bdrv, sector, iobuf, PAGE_SECTORS + 2) == -1)
628             printf("%s: write error in sector %lli\n", __FUNCTION__, sector);
629     }
630     s->offset = 0;
631 }
632
633 /* Erase a single block */
634 static void glue(nand_blk_erase_, PAGE_SIZE)(NANDFlashState *s)
635 {
636     uint64_t i, page, addr;
637     uint8_t iobuf[0x200] = { [0 ... 0x1ff] = 0xff, };
638     addr = s->addr & ~((1 << (ADDR_SHIFT + s->erase_shift)) - 1);
639
640     if (PAGE(addr) >= s->pages)
641         return;
642
643     if (!s->bdrv) {
644         memset(s->storage + PAGE_START(addr),
645                         0xff, (PAGE_SIZE + OOB_SIZE) << s->erase_shift);
646     } else if (s->mem_oob) {
647         memset(s->storage + (PAGE(addr) << OOB_SHIFT),
648                         0xff, OOB_SIZE << s->erase_shift);
649         i = SECTOR(addr);
650         page = SECTOR(addr + (ADDR_SHIFT + s->erase_shift));
651         for (; i < page; i ++)
652             if (bdrv_write(s->bdrv, i, iobuf, 1) == -1)
653                 printf("%s: write error in sector %lli\n", __FUNCTION__, i);
654     } else {
655         addr = PAGE_START(addr);
656         page = addr >> 9;
657         if (bdrv_read(s->bdrv, page, iobuf, 1) == -1)
658             printf("%s: read error in sector %lli\n", __FUNCTION__, page);
659         memset(iobuf + (addr & 0x1ff), 0xff, (~addr & 0x1ff) + 1);
660         if (bdrv_write(s->bdrv, page, iobuf, 1) == -1)
661             printf("%s: write error in sector %lli\n", __FUNCTION__, page);
662
663         memset(iobuf, 0xff, 0x200);
664         i = (addr & ~0x1ff) + 0x200;
665         for (addr += ((PAGE_SIZE + OOB_SIZE) << s->erase_shift) - 0x200;
666                         i < addr; i += 0x200)
667             if (bdrv_write(s->bdrv, i >> 9, iobuf, 1) == -1)
668                 printf("%s: write error in sector %lli\n", __FUNCTION__, i >> 9);
669
670         page = i >> 9;
671         if (bdrv_read(s->bdrv, page, iobuf, 1) == -1)
672             printf("%s: read error in sector %lli\n", __FUNCTION__, page);
673         memset(iobuf, 0xff, ((addr - 1) & 0x1ff) + 1);
674         if (bdrv_write(s->bdrv, page, iobuf, 1) == -1)
675             printf("%s: write error in sector %lli\n", __FUNCTION__, page);
676     }
677 }
678
679 static void glue(nand_blk_load_, PAGE_SIZE)(NANDFlashState *s,
680                 uint64_t addr, int offset)
681 {
682     if (PAGE(addr) >= s->pages)
683         return;
684
685     if (s->bdrv) {
686         if (s->mem_oob) {
687             if (bdrv_read(s->bdrv, SECTOR(addr), s->io, PAGE_SECTORS) == -1)
688                 printf("%s: read error in sector %lli\n",
689                                 __FUNCTION__, SECTOR(addr));
690             memcpy(s->io + SECTOR_OFFSET(s->addr) + PAGE_SIZE,
691                             s->storage + (PAGE(s->addr) << OOB_SHIFT),
692                             OOB_SIZE);
693             s->ioaddr = s->io + SECTOR_OFFSET(s->addr) + offset;
694         } else {
695             if (bdrv_read(s->bdrv, PAGE_START(addr) >> 9,
696                                     s->io, (PAGE_SECTORS + 2)) == -1)
697                 printf("%s: read error in sector %lli\n",
698                                 __FUNCTION__, PAGE_START(addr) >> 9);
699             s->ioaddr = s->io + (PAGE_START(addr) & 0x1ff) + offset;
700         }
701     } else {
702         memcpy(s->io, s->storage + PAGE_START(s->addr) +
703                         offset, PAGE_SIZE + OOB_SIZE - offset);
704         s->ioaddr = s->io;
705     }
706
707     s->addr &= PAGE_SIZE - 1;
708     s->addr += PAGE_SIZE;
709 }
710
711 static void glue(nand_init_, PAGE_SIZE)(NANDFlashState *s)
712 {
713     s->oob_shift = PAGE_SHIFT - 5;
714     s->pages = s->size >> PAGE_SHIFT;
715     s->addr_shift = ADDR_SHIFT;
716
717     s->blk_erase = glue(nand_blk_erase_, PAGE_SIZE);
718     s->blk_write = glue(nand_blk_write_, PAGE_SIZE);
719     s->blk_load = glue(nand_blk_load_, PAGE_SIZE);
720 }
721
722 # undef PAGE_SIZE
723 # undef PAGE_SHIFT
724 # undef PAGE_SECTORS
725 # undef ADDR_SHIFT
726 #endif  /* NAND_IO */