2 * Big page NAND flash memory emulation. based on 256M/16 bit flash datasheet from micro(MT29F2G16ABC)
4 * Copyright (C) 2008 yajin(yajin@vm-kernel.org)
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 or
9 * (at your option) version 3 of the License.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
28 #define MAX_PAGE 0x800
30 #define PAGE_MASK (0xffff)
31 #define BUS_WIDTH_16 2
36 struct nand_flash_info_s
38 uint8_t manf_id,chip_id;
45 struct nand_flash_info_s nand_flash_info[1] =
47 {0x2c, 0xba, 256,2, 11, 6, 6}
53 BlockDriverState *bdrv;
54 uint8_t manf_id, chip_id;
56 uint32_t page_size, page_shift;
57 uint32_t oob_size, oob_shift;
58 uint32_t page_oob_size;
59 uint32_t page_sectors; /*sector = 512 bytes */
60 uint32_t block_shift, block_pages; /*how many pages in a block */
61 uint32_t bus_width; /*bytes */
63 //uint8_t *internal_buf;
64 uint8_t io[MAX_PAGE + MAX_OOB + 0x400];
69 uint32 addr_low, addr_high;
80 static void debug_init(struct nand_bflash_s *s)
82 s->fp=fopen("nandflash_debug.txt","w+");
85 fprintf(stderr,"can not open nandflash_debug.txt \n");
90 static void debug_out(struct nand_bflash_s *s,const char* format, ...)
96 vfprintf(s->fp, format, ap);
103 static void debug_init(struct nand_bflash_s *s)
107 static void debug_out(struct nand_bflash_s *s,const char* format, ...)
114 static inline uint32_t get_page_number(struct nand_bflash_s *s,
115 uint32_t addr_low, uint32 addr_high)
117 return (addr_high << 16) + ((addr_low >> 16) & PAGE_MASK);
122 /* Program a single page */
123 static void nand_blk_write(struct nand_bflash_s *s)
125 uint32_t page_number, off, sector, soff;
129 iobuf = qemu_mallocz((s->page_sectors + 2) * 0x200);
132 fprintf(stderr, "can not alloc io buffer size 0x%x \n",
133 (s->page_sectors + 2) * 0x200);
134 cpu_abort(cpu_single_env, "%s: can not alloc io buffer size 0x%x \n",
135 __FUNCTION__, (s->page_sectors + 2) * 0x200);
138 page_number = get_page_number(s, s->addr_low, s->addr_high);
140 debug_out(s,"nand_blk_write page number %x s->addr_low %x s->addr_high %x\n",page_number,s->addr_low,s->addr_high);
142 if (page_number >= s->pages)
145 off = page_number * s->page_oob_size + (s->addr_low & PAGE_MASK);
148 if (bdrv_read(s->bdrv, sector, iobuf, s->page_sectors + 2) == -1)
150 printf("%s: read error in sector %i\n", __FUNCTION__, sector);
154 memcpy(iobuf + soff, s->io, s->iolen);
156 if (bdrv_write(s->bdrv, sector, iobuf, s->page_sectors + 2) == -1)
157 printf("%s: write error in sector %i\n", __FUNCTION__, sector);
163 static void nandb_blk_load(struct nand_bflash_s *s)
165 uint32_t page_number, offset;
166 offset = s->addr_low & PAGE_MASK;
168 page_number = get_page_number(s, s->addr_low, s->addr_high);
169 debug_out(s,"nandb_blk_load page number %x s->addr_low %x s->addr_high %x\n",page_number,s->addr_low,s->addr_high);
170 if (page_number >= s->pages)
173 if (bdrv_read(s->bdrv, (page_number * s->page_oob_size + offset) >> 9,
174 s->io, (s->page_sectors + 2)) == -1)
175 printf("%s: read error in sector %i\n",
176 __FUNCTION__, page_number * s->page_oob_size);
177 s->ioaddr = s->io + ((page_number * s->page_oob_size + offset) & 0x1ff);
181 /* Erase a single block */
182 static void nandb_blk_erase(struct nand_bflash_s *s)
184 uint32_t page_number, sector, addr, i;
186 uint8_t iobuf[0x200];
188 memset(iobuf,0xff,sizeof(iobuf));
189 s->addr_low = s->addr_low & ~((1 << (16 + s->block_shift)) - 1);
190 page_number = get_page_number(s, s->addr_low, s->addr_high);
191 debug_out(s,"nandb_blk_erase page number %x s->addr_low %x s->addr_high %x\n",page_number,s->addr_low,s->addr_high);
192 if (page_number >= s->pages)
195 addr = page_number * s->page_oob_size;
198 if (bdrv_read(s->bdrv, sector, iobuf, 1) == -1)
199 printf("%s: read error in sector %i\n", __FUNCTION__, sector);
200 memset(iobuf + (addr & 0x1ff), 0xff, (~addr & 0x1ff) + 1);
201 if (bdrv_write(s->bdrv, sector, iobuf, 1) == -1)
202 printf("%s: write error in sector %i\n", __FUNCTION__, sector);
204 memset(iobuf, 0xff, 0x200);
205 i = (addr & ~0x1ff) + 0x200;
206 for (addr += (s->page_oob_size*s->block_pages - 0x200); i < addr; i += 0x200)
207 if (bdrv_write(s->bdrv, i >> 9, iobuf, 1) == -1)
208 printf("%s: write error in sector %i\n", __FUNCTION__, i >> 9);
211 if (bdrv_read(s->bdrv, sector, iobuf, 1) == -1)
212 printf("%s: read error in sector %i\n", __FUNCTION__, sector);
213 memset(iobuf, 0xff, ((addr - 1) & 0x1ff) + 1);
214 if (bdrv_write(s->bdrv, sector, iobuf, 1) == -1)
215 printf("%s: write error in sector %i\n", __FUNCTION__, sector);
218 static void nandb_next_page(struct nand_bflash_s *s)
220 if ((s->addr_low + 0x10000) < s->addr_low)
222 s->addr_low += 0x10000;
225 void nandb_write_command(struct nand_bflash_s *s, uint16_t value)
227 int id_index[4] = { 0, 1, 2, 3 };
229 debug_out(s,"nandb_write_command %x\n",value);
233 case 0x00: /* PAGE READ (cycle 1) */
234 case 0x05: /* RANDOM DATA READ (cycle 1) */
238 case 0x10: /* PROGRAM xxx / OTP PROTECT (cycle 2) */
241 case 0x30: /* PAGE READ / OTP DATA READ (cycle 2) */
242 case 0xe0: /* RANDOM DATA READ (cycle 2) */
243 s->iolen = s->page_oob_size - (s->addr_low & PAGE_MASK);
247 case 0x31: /* PAGE READ CACHE MODE START */
248 case 0x3f: /* PAGE READ CACHE MODE START LAST */
250 s->iolen = s->page_oob_size - (s->addr_low & PAGE_MASK);
253 case 0x60: /* BLOCK ERASE (cycle 1) */
254 /*erase only needs 3 address cycles. Its address is block address*/
255 s->addr_low &= ~PAGE_MASK;
259 case 0x70: /* READ STATUS */
260 if ((s->manf_id == NAND_MFR_MICRON) && (s->chip_id == 0xba))
262 s->status |= 0x60; /*flash is ready */
263 s->status |= 0x80; /*not protect */
265 s->io[0] = s->status;
269 case 0x80: /* PROGRAM PAGE / PROGRAM PAGE CACHE MODE (cycle 1) */
270 case 0x85: /* PROGRAM for INTERNAL DATA MOVE (cycle 1) / RANDOM DATA INPUT */
275 case 0x90: /* READ ID */
276 s->iolen = 4 * s->bus_width;
277 memset(s->io, 0x0, s->iolen);
278 if (s->bus_width == BUS_WIDTH_16)
285 s->io[id_index[0]] = s->manf_id;
286 s->io[id_index[1]] = s->chip_id;
287 s->io[id_index[2]] = 'Q'; /* Don't-care byte (often 0xa5) */
288 if ((s->manf_id == NAND_MFR_MICRON) && (s->chip_id == 0xba))
289 s->io[id_index[3]] = 0x55;
292 case 0xa0: /* OTP DATA PROGRAM (cycle 1) */
293 case 0xa5: /* OTP DATA PROTECT (cycle 1) */
294 case 0xaf: /* OTP DATA READ (cycle 1) */
295 fprintf(stderr, "%s: OTP command 0x%x not implemented\n", __FUNCTION__, value);
297 case 0xd0: /* BLOCK ERASE (cycle 2) */
300 case 0xff: /* RESET */
308 fprintf(stderr, "%s: unknown nand command 0x%x \n", __FUNCTION__, value);
314 void nandb_write_address(struct nand_bflash_s *s, uint16_t value)
319 /*fprintf(stderr, "%s: addr_cycle=%d, value=0x%04x, addr_low=0x%08x, addr_high=0x%08x\n",
320 __FUNCTION__, s->addr_cycle, value, s->addr_low, s->addr_high );*/
323 debug_out(s,"value %x addr_cycle %x \n",value,s->addr_cycle);
325 if (s->addr_cycle < 5) {
326 if (s->addr_cycle < 4) {
327 mask = ~(0xff << (s->addr_cycle * 8));
329 s->addr_low |= value << (s->addr_cycle * 8);
331 mask = ~(0xff << ((s->addr_cycle-4) * 8));
332 s->addr_high &= mask;
333 s->addr_high |= value << ((s->addr_cycle-4) * 8);
337 fprintf(stderr,"%s wrong addr cycle\n",__FUNCTION__);
340 if ((s->addr_cycle==1)&&(s->bus_width!=1)) {
341 colum_addr = s->addr_low & PAGE_MASK;
342 colum_addr *= s->bus_width;
343 s->addr_low &= ~PAGE_MASK;
344 s->addr_low += colum_addr;
350 uint16_t nandb_read_data16(struct nand_bflash_s *s)
353 if ((s->iolen==0)&&(s->cmd==0x31))
356 s->iolen = s->page_oob_size - (s->addr_low & PAGE_MASK);
361 fprintf(stderr,"iolen <0 \n");
366 ret = *((uint16_t *)s->ioaddr);
372 void nandb_write_data16(struct nand_bflash_s *s, uint16_t value)
374 if ((s->cmd == 0x80) )
376 if (s->iolen < s->page_oob_size)
378 s->io[s->iolen ++] = value&0xff;
379 s->io[s->iolen ++] = (value>>8)&0xff;
384 struct nand_bflash_s *nandb_init(int manf_id, int chip_id)
387 struct nand_bflash_s *s;
391 s = (struct nand_bflash_s *) qemu_mallocz(sizeof(struct nand_bflash_s));
392 for (i = 0; i < sizeof(nand_flash_info); i++)
394 if ((nand_flash_info[i].manf_id == manf_id)
395 && (nand_flash_info[i].chip_id == chip_id))
397 s->manf_id = manf_id;
398 s->chip_id = chip_id;
399 s->page_shift = nand_flash_info[i].page_shift;
400 s->oob_shift = nand_flash_info[i].oob_shift;
401 s->bus_width = nand_flash_info[i].bus_width;
402 s->page_size = 1 << s->page_shift;
403 s->oob_size = 1 << s->oob_shift;
404 s->block_shift = nand_flash_info[i].block_shift;
405 s->block_pages = 1 << s->block_shift;
406 s->page_oob_size = s->page_size + s->oob_size;
407 s->page_sectors = 1 << (s->page_shift - 9);
408 /*TODO: size overflow */
409 s->size = nand_flash_info[i].size << 20;
410 s->pages = (s->size / s->page_size);
416 if (i >= sizeof(nand_flash_info))
418 fprintf(stderr, "%s: Unsupported NAND chip ID.\n",
424 index = drive_get_index(IF_MTD, 0, 0);
426 s->bdrv = drives_table[index].bdrv;
429 fprintf(stderr, "%s: Please use -mtdblock to specify flash image.\n",
434 if (bdrv_getlength(s->bdrv) != (s->pages*s->page_oob_size))
436 fprintf(stderr, "%s: Invalid flash image size.\n",