(linenum→info "unix/slp.c:2238")

qemu/0.9.1/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:  * This code is licensed under the GNU GPL v2.
   10:  */
   11: 
   12: #ifndef NAND_IO
   13: 
   14: # include "hw.h"
   15: # include "flash.h"
   16: # include "block.h"
   17: /* FIXME: Pass block device as an argument.  */
   18: # include "sysemu.h"
   19: 
   20: # define NAND_CMD_READ0         0x00
   21: # define NAND_CMD_READ1         0x01
   22: # define NAND_CMD_READ2         0x50
   23: # define NAND_CMD_LPREAD2       0x30
   24: # define NAND_CMD_NOSERIALREAD2 0x35
   25: # define NAND_CMD_RANDOMREAD1   0x05
   26: # define NAND_CMD_RANDOMREAD2   0xe0
   27: # define NAND_CMD_READID        0x90
   28: # define NAND_CMD_RESET         0xff
   29: # define NAND_CMD_PAGEPROGRAM1  0x80
   30: # define NAND_CMD_PAGEPROGRAM2  0x10
   31: # define NAND_CMD_CACHEPROGRAM2 0x15
   32: # define NAND_CMD_BLOCKERASE1   0x60
   33: # define NAND_CMD_BLOCKERASE2   0xd0
   34: # define NAND_CMD_READSTATUS    0x70
   35: # define NAND_CMD_COPYBACKPRG1  0x85
   36: 
   37: # define NAND_IOSTATUS_ERROR    (1 << 0)
   38: # define NAND_IOSTATUS_PLANE0   (1 << 1)
   39: # define NAND_IOSTATUS_PLANE1   (1 << 2)
   40: # define NAND_IOSTATUS_PLANE2   (1 << 3)
   41: # define NAND_IOSTATUS_PLANE3   (1 << 4)
   42: # define NAND_IOSTATUS_BUSY     (1 << 6)
   43: # define NAND_IOSTATUS_UNPROTCT (1 << 7)
   44: 
   45: # define MAX_PAGE               0x800
   46: # define MAX_OOB                0x40
   47: 
   48: struct nand_flash_s {
   49:     uint8_t manf_id, chip_id;
   50:     int size, pages;
   51:     int page_shift, oob_shift, erase_shift, addr_shift;
   52:     uint8_t *storage;
   53:     BlockDriverState *bdrv;
   54:     int mem_oob;
   55: 
   56:     int cle, ale, ce, wp, gnd;
   57: 
   58:     uint8_t io[MAX_PAGE + MAX_OOB + 0x400];
   59:     uint8_t *ioaddr;
   60:     int iolen;
   61: 
   62:     uint32_t cmd, addr;
   63:     int addrlen;
   64:     int status;
   65:     int offset;
   66: 
   67:     void (*blk_write)(struct nand_flash_s *s);
   68:     void (*blk_erase)(struct nand_flash_s *s);
   69:     void (*blk_load)(struct nand_flash_s *s, uint32_t addr, int offset);
   70: };
   71: 
   72: # define NAND_NO_AUTOINCR       0x00000001
   73: # define NAND_BUSWIDTH_16       0x00000002
   74: # define NAND_NO_PADDING        0x00000004
   75: # define NAND_CACHEPRG          0x00000008
   76: # define NAND_COPYBACK          0x00000010
   77: # define NAND_IS_AND            0x00000020
   78: # define NAND_4PAGE_ARRAY       0x00000040
   79: # define NAND_NO_READRDY        0x00000100
   80: # define NAND_SAMSUNG_LP        (NAND_NO_PADDING | NAND_COPYBACK)
   81: 
   82: # define NAND_IO
   83: 
   84: # define PAGE(addr)             ((addr) >> ADDR_SHIFT)
   85: # define PAGE_START(page)       (PAGE(page) * (PAGE_SIZE + OOB_SIZE))
   86: # define PAGE_MASK              ((1 << ADDR_SHIFT) - 1)
   87: # define OOB_SHIFT              (PAGE_SHIFT - 5)
   88: # define OOB_SIZE               (1 << OOB_SHIFT)
   89: # define SECTOR(addr)           ((addr) >> (9 + ADDR_SHIFT - PAGE_SHIFT))
   90: # define SECTOR_OFFSET(addr)    ((addr) & ((511 >> PAGE_SHIFT) << 8))
   91: 
   92: # define PAGE_SIZE              256
   93: # define PAGE_SHIFT             8
   94: # define PAGE_SECTORS           1
   95: # define ADDR_SHIFT             8
   96: # include "nand.c"
   97: # define PAGE_SIZE              512
   98: # define PAGE_SHIFT             9
   99: # define PAGE_SECTORS           1
  100: # define ADDR_SHIFT             8
  101: # include "nand.c"
  102: # define PAGE_SIZE              2048
  103: # define PAGE_SHIFT             11
  104: # define PAGE_SECTORS           4
  105: # define ADDR_SHIFT             16
  106: # include "nand.c"
  107: 
  108: /* Information based on Linux drivers/mtd/nand/nand_ids.c */
  109: struct nand_info_s {
  110:     int size;
  111:     int width;
  112:     int page_shift;
  113:     int erase_shift;
  114:     uint32_t options;
  115: } nand_flash_ids[0x100] = {
  116:     [0 ... 0xff] = { 0 },
  117: 
  118:     [0x6e] = { 1,       8,    8, 4, 0 },
  119:     [0x64] = { 2,       8,    8, 4, 0 },
  120:     [0x6b] = { 4,       8,    9, 4, 0 },
  121:     [0xe8] = { 1,       8,    8, 4, 0 },
  122:     [0xec] = { 1,       8,    8, 4, 0 },
  123:     [0xea] = { 2,       8,    8, 4, 0 },
  124:     [0xd5] = { 4,       8,    9, 4, 0 },
  125:     [0xe3] = { 4,       8,    9, 4, 0 },
  126:     [0xe5] = { 4,       8,    9, 4, 0 },
  127:     [0xd6] = { 8,       8,    9, 4, 0 },
  128: 
  129:     [0x39] = { 8,       8,    9, 4, 0 },
  130:     [0xe6] = { 8,       8,    9, 4, 0 },
  131:     [0x49] = { 8,       16,   9, 4, NAND_BUSWIDTH_16 },
  132:     [0x59] = { 8,       16,   9, 4, NAND_BUSWIDTH_16 },
  133: 
  134:     [0x33] = { 16,      8,   9, 5, 0 },
  135:     [0x73] = { 16,      8,   9, 5, 0 },
  136:     [0x43] = { 16,      16,  9, 5, NAND_BUSWIDTH_16 },
  137:     [0x53] = { 16,      16,  9, 5, NAND_BUSWIDTH_16 },
  138: 
  139:     [0x35] = { 32,      8,   9, 5, 0 },
  140:     [0x75] = { 32,      8,   9, 5, 0 },
  141:     [0x45] = { 32,      16,  9, 5, NAND_BUSWIDTH_16 },
  142:     [0x55] = { 32,      16,  9, 5, NAND_BUSWIDTH_16 },
  143: 
  144:     [0x36] = { 64,      8,   9, 5, 0 },
  145:     [0x76] = { 64,      8,   9, 5, 0 },
  146:     [0x46] = { 64,      16,  9, 5, NAND_BUSWIDTH_16 },
  147:     [0x56] = { 64,      16,  9, 5, NAND_BUSWIDTH_16 },
  148: 
  149:     [0x78] = { 128,     8,  9, 5, 0 },
  150:     [0x39] = { 128,     8,  9, 5, 0 },
  151:     [0x79] = { 128,     8,  9, 5, 0 },
  152:     [0x72] = { 128,     16, 9, 5, NAND_BUSWIDTH_16 },
  153:     [0x49] = { 128,     16, 9, 5, NAND_BUSWIDTH_16 },
  154:     [0x74] = { 128,     16, 9, 5, NAND_BUSWIDTH_16 },
  155:     [0x59] = { 128,     16, 9, 5, NAND_BUSWIDTH_16 },
  156: 
  157:     [0x71] = { 256,     8,  9, 5, 0 },
  158: 
  159:     /*
  160:      * These are the new chips with large page size. The pagesize and the
  161:      * erasesize is determined from the extended id bytes
  162:      */
  163: # define LP_OPTIONS     (NAND_SAMSUNG_LP | NAND_NO_READRDY | NAND_NO_AUTOINCR)
  164: # define LP_OPTIONS16   (LP_OPTIONS | NAND_BUSWIDTH_16)
  165: 
  166:     /* 512 Megabit */
  167:     [0xa2] = { 64,      8,   0, 0, LP_OPTIONS },
  168:     [0xf2] = { 64,      8,   0, 0, LP_OPTIONS },
  169:     [0xb2] = { 64,      16,  0, 0, LP_OPTIONS16 },
  170:     [0xc2] = { 64,      16,  0, 0, LP_OPTIONS16 },
  171: 
  172:     /* 1 Gigabit */
  173:     [0xa1] = { 128,     8,  0, 0, LP_OPTIONS },
  174:     [0xf1] = { 128,     8,  0, 0, LP_OPTIONS },
  175:     [0xb1] = { 128,     16, 0, 0, LP_OPTIONS16 },
  176:     [0xc1] = { 128,     16, 0, 0, LP_OPTIONS16 },
  177: 
  178:     /* 2 Gigabit */
  179:     [0xaa] = { 256,     8,  0, 0, LP_OPTIONS },
  180:     [0xda] = { 256,     8,  0, 0, LP_OPTIONS },
  181:     [0xba] = { 256,     16, 0, 0, LP_OPTIONS16 },
  182:     [0xca] = { 256,     16, 0, 0, LP_OPTIONS16 },
  183: 
  184:     /* 4 Gigabit */
  185:     [0xac] = { 512,     8,  0, 0, LP_OPTIONS },
  186:     [0xdc] = { 512,     8,  0, 0, LP_OPTIONS },
  187:     [0xbc] = { 512,     16, 0, 0, LP_OPTIONS16 },
  188:     [0xcc] = { 512,     16, 0, 0, LP_OPTIONS16 },
  189: 
  190:     /* 8 Gigabit */
  191:     [0xa3] = { 1024,    8, 0, 0, LP_OPTIONS },
  192:     [0xd3] = { 1024,    8, 0, 0, LP_OPTIONS },
  193:     [0xb3] = { 1024,    16,        0, 0, LP_OPTIONS16 },
  194:     [0xc3] = { 1024,    16,        0, 0, LP_OPTIONS16 },
  195: 
  196:     /* 16 Gigabit */
  197:     [0xa5] = { 2048,    8, 0, 0, LP_OPTIONS },
  198:     [0xd5] = { 2048,    8, 0, 0, LP_OPTIONS },
  199:     [0xb5] = { 2048,    16,        0, 0, LP_OPTIONS16 },
  200:     [0xc5] = { 2048,    16,        0, 0, LP_OPTIONS16 },
  201: };
  202: 
  203: static void nand_reset(struct nand_flash_s *s)
  204: {
  205:     s->cmd = NAND_CMD_READ0;
  206:     s->addr = 0;
  207:     s->addrlen = 0;
  208:     s->iolen = 0;
  209:     s->offset = 0;
  210:     s->status &= NAND_IOSTATUS_UNPROTCT;
  211: }
  212: 
  213: static void nand_command(struct nand_flash_s *s)
  214: {
  215:     switch (s->cmd) {
  216:     case NAND_CMD_READ0:
  217:         s->iolen = 0;
  218:         break;
  219: 
  220:     case NAND_CMD_READID:
  221:         s->io[0] = s->manf_id;
  222:         s->io[1] = s->chip_id;
  223:         s->io[2] = 'Q';         /* Don't-care byte (often 0xa5) */
  224:         if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP)
  225:             s->io[3] = 0x15;    /* Page Size, Block Size, Spare Size.. */
  226:         else
  227:             s->io[3] = 0xc0;    /* Multi-plane */
  228:         s->ioaddr = s->io;
  229:         s->iolen = 4;
  230:         break;
  231: 
  232:     case NAND_CMD_RANDOMREAD2:
  233:     case NAND_CMD_NOSERIALREAD2:
  234:         if (!(nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP))
  235:             break;
  236: 
  237:         s->blk_load(s, s->addr, s->addr & ((1 << s->addr_shift) - 1));
  238:         break;
  239: 
  240:     case NAND_CMD_RESET:
  241:         nand_reset(s);
  242:         break;
  243: 
  244:     case NAND_CMD_PAGEPROGRAM1:
  245:         s->ioaddr = s->io;
  246:         s->iolen = 0;
  247:         break;
  248: 
  249:     case NAND_CMD_PAGEPROGRAM2:
  250:         if (s->wp) {
  251:             s->blk_write(s);
  252:         }
  253:         break;
  254: 
  255:     case NAND_CMD_BLOCKERASE1:
  256:         break;
  257: 
  258:     case NAND_CMD_BLOCKERASE2:
  259:         if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP)
  260:             s->addr <<= 16;
  261:         else
  262:             s->addr <<= 8;
  263: 
  264:         if (s->wp) {
  265:             s->blk_erase(s);
  266:         }
  267:         break;
  268: 
  269:     case NAND_CMD_READSTATUS:
  270:         s->io[0] = s->status;
  271:         s->ioaddr = s->io;
  272:         s->iolen = 1;
  273:         break;
  274: 
  275:     default:
  276:         printf("%s: Unknown NAND command 0x%02x\n", __FUNCTION__, s->cmd);
  277:     }
  278: }
  279: 
  280: static void nand_save(QEMUFile *f, void *opaque)
  281: {
  282:     struct nand_flash_s *s = (struct nand_flash_s *) opaque;
  283:     qemu_put_byte(f, s->cle);
  284:     qemu_put_byte(f, s->ale);
  285:     qemu_put_byte(f, s->ce);
  286:     qemu_put_byte(f, s->wp);
  287:     qemu_put_byte(f, s->gnd);
  288:     qemu_put_buffer(f, s->io, sizeof(s->io));
  289:     qemu_put_be32(f, s->ioaddr - s->io);
  290:     qemu_put_be32(f, s->iolen);
  291: 
  292:     qemu_put_be32s(f, &s->cmd);
  293:     qemu_put_be32s(f, &s->addr);
  294:     qemu_put_be32(f, s->addrlen);
  295:     qemu_put_be32(f, s->status);
  296:     qemu_put_be32(f, s->offset);
  297:     /* XXX: do we want to save s->storage too? */
  298: }
  299: 
  300: static int nand_load(QEMUFile *f, void *opaque, int version_id)
  301: {
  302:     struct nand_flash_s *s = (struct nand_flash_s *) opaque;
  303:     s->cle = qemu_get_byte(f);
  304:     s->ale = qemu_get_byte(f);
  305:     s->ce = qemu_get_byte(f);
  306:     s->wp = qemu_get_byte(f);
  307:     s->gnd = qemu_get_byte(f);
  308:     qemu_get_buffer(f, s->io, sizeof(s->io));
  309:     s->ioaddr = s->io + qemu_get_be32(f);
  310:     s->iolen = qemu_get_be32(f);
  311:     if (s->ioaddr >= s->io + sizeof(s->io) || s->ioaddr < s->io)
  312:         return -EINVAL;
  313: 
  314:     qemu_get_be32s(f, &s->cmd);
  315:     qemu_get_be32s(f, &s->addr);
  316:     s->addrlen = qemu_get_be32(f);
  317:     s->status = qemu_get_be32(f);
  318:     s->offset = qemu_get_be32(f);
  319:     return 0;
  320: }
  321: 
  322: static int nand_iid = 0;
  323: 
  324: /*
  325:  * Chip inputs are CLE, ALE, CE, WP, GND and eight I/O pins.  Chip
  326:  * outputs are R/B and eight I/O pins.
  327:  *
  328:  * CE, WP and R/B are active low.
  329:  */
  330: void nand_setpins(struct nand_flash_s *s,
  331:                 int cle, int ale, int ce, int wp, int gnd)
  332: {
  333:     s->cle = cle;
  334:     s->ale = ale;
  335:     s->ce = ce;
  336:     s->wp = wp;
  337:     s->gnd = gnd;
  338:     if (wp)
  339:         s->status |= NAND_IOSTATUS_UNPROTCT;
  340:     else
  341:         s->status &= ~NAND_IOSTATUS_UNPROTCT;
  342: }
  343: 
  344: void nand_getpins(struct nand_flash_s *s, int *rb)
  345: {
  346:     *rb = 1;
  347: }
  348: 
  349: void nand_setio(struct nand_flash_s *s, uint8_t value)
  350: {
  351:     if (!s->ce && s->cle) {
  352:         if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) {
  353:             if (s->cmd == NAND_CMD_READ0 && value == NAND_CMD_LPREAD2)
  354:                 return;
  355:             if (value == NAND_CMD_RANDOMREAD1) {
  356:                 s->addr &= ~((1 << s->addr_shift) - 1);
  357:                 s->addrlen = 0;
  358:                 return;
  359:             }
  360:         }
  361:         if (value == NAND_CMD_READ0)
  362:             s->offset = 0;
  363:         else if (value == NAND_CMD_READ1) {
  364:             s->offset = 0x100;
  365:             value = NAND_CMD_READ0;
  366:         }
  367:         else if (value == NAND_CMD_READ2) {
  368:             s->offset = 1 << s->page_shift;
  369:             value = NAND_CMD_READ0;
  370:         }
  371: 
  372:         s->cmd = value;
  373: 
  374:         if (s->cmd == NAND_CMD_READSTATUS ||
  375:                 s->cmd == NAND_CMD_PAGEPROGRAM2 ||
  376:                 s->cmd == NAND_CMD_BLOCKERASE1 ||
  377:                 s->cmd == NAND_CMD_BLOCKERASE2 ||
  378:                 s->cmd == NAND_CMD_NOSERIALREAD2 ||
  379:                 s->cmd == NAND_CMD_RANDOMREAD2 ||
  380:                 s->cmd == NAND_CMD_RESET)
  381:             nand_command(s);
  382: 
  383:         if (s->cmd != NAND_CMD_RANDOMREAD2) {
  384:             s->addrlen = 0;
  385:             s->addr = 0;
  386:         }
  387:     }
  388: 
  389:     if (s->ale) {
  390:         s->addr |= value << (s->addrlen * 8);
  391:         s->addrlen ++;
  392: 
  393:         if (s->addrlen == 1 && s->cmd == NAND_CMD_READID)
  394:             nand_command(s);
  395: 
  396:         if (!(nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) &&
  397:                 s->addrlen == 3 && (
  398:                     s->cmd == NAND_CMD_READ0 ||
  399:                     s->cmd == NAND_CMD_PAGEPROGRAM1))
  400:             nand_command(s);
  401:         if ((nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) &&
  402:                s->addrlen == 4 && (
  403:                     s->cmd == NAND_CMD_READ0 ||
  404:                     s->cmd == NAND_CMD_PAGEPROGRAM1))
  405:             nand_command(s);
  406:     }
  407: 
  408:     if (!s->cle && !s->ale && s->cmd == NAND_CMD_PAGEPROGRAM1) {
  409:         if (s->iolen < (1 << s->page_shift) + (1 << s->oob_shift))
  410:             s->io[s->iolen ++] = value;
  411:     } else if (!s->cle && !s->ale && s->cmd == NAND_CMD_COPYBACKPRG1) {
  412:         if ((s->addr & ((1 << s->addr_shift) - 1)) <
  413:                 (1 << s->page_shift) + (1 << s->oob_shift)) {
  414:             s->io[s->iolen + (s->addr & ((1 << s->addr_shift) - 1))] = value;
  415:             s->addr ++;
  416:         }
  417:     }
  418: }
  419: 
  420: uint8_t nand_getio(struct nand_flash_s *s)
  421: {
  422:     int offset;
  423: 
  424:     /* Allow sequential reading */
  425:     if (!s->iolen && s->cmd == NAND_CMD_READ0) {
  426:         offset = (s->addr & ((1 << s->addr_shift) - 1)) + s->offset;
  427:         s->offset = 0;
  428: 
  429:         s->blk_load(s, s->addr, offset);
  430:         if (s->gnd)
  431:             s->iolen = (1 << s->page_shift) - offset;
  432:         else
  433:             s->iolen = (1 << s->page_shift) + (1 << s->oob_shift) - offset;
  434:     }
  435: 
  436:     if (s->ce || s->iolen <= 0)
  437:         return 0;
  438: 
  439:     s->iolen --;
  440:     return *(s->ioaddr ++);
  441: }
  442: 
  443: struct nand_flash_s *nand_init(int manf_id, int chip_id)
  444: {
  445:     int pagesize;
  446:     struct nand_flash_s *s;
  447:     int index;
  448: 
  449:     if (nand_flash_ids[chip_id].size == 0) {
  450:         cpu_abort(cpu_single_env, "%s: Unsupported NAND chip ID.\n",
  451:                         __FUNCTION__);
  452:     }
  453:     index = drive_get_index(IF_MTD, 0, 0);
  454:     if (index == -1) {
  455:         cpu_abort(cpu_single_env, "%s: missing MTD device\n",
  456:                         __FUNCTION__);
  457:     }
  458: 
  459:     s = (struct nand_flash_s *) qemu_mallocz(sizeof(struct nand_flash_s));
  460:     s->bdrv = drives_table[index].bdrv;
  461:     s->manf_id = manf_id;
  462:     s->chip_id = chip_id;
  463:     s->size = nand_flash_ids[s->chip_id].size << 20;
  464:     if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) {
  465:         s->page_shift = 11;
  466:         s->erase_shift = 6;
  467:     } else {
  468:         s->page_shift = nand_flash_ids[s->chip_id].page_shift;
  469:         s->erase_shift = nand_flash_ids[s->chip_id].erase_shift;
  470:     }
  471: 
  472:     switch (1 << s->page_shift) {
  473:     case 256:
  474:         nand_init_256(s);
  475:         break;
  476:     case 512:
  477:         nand_init_512(s);
  478:         break;
  479:     case 2048:
  480:         nand_init_2048(s);
  481:         break;
  482:     default:
  483:         cpu_abort(cpu_single_env, "%s: Unsupported NAND block size.\n",
  484:                         __FUNCTION__);
  485:     }
  486: 
  487:     pagesize = 1 << s->oob_shift;
  488:     s->mem_oob = 1;
  489:     if (s->bdrv && bdrv_getlength(s->bdrv) >=
  490:                     (s->pages << s->page_shift) + (s->pages << s->oob_shift)) {
  491:         pagesize = 0;
  492:         s->mem_oob = 0;
  493:     }
  494: 
  495:     if (!s->bdrv)
  496:         pagesize += 1 << s->page_shift;
  497:     if (pagesize)
  498:         s->storage = (uint8_t *) memset(qemu_malloc(s->pages * pagesize),
  499:                         0xff, s->pages * pagesize);
  500: 
  501:     register_savevm("nand", nand_iid ++, 0, nand_save, nand_load, s);
  502: 
  503:     return s;
  504: }
  505: 
  506: void nand_done(struct nand_flash_s *s)
  507: {
  508:     if (s->bdrv) {
  509:         bdrv_close(s->bdrv);
  510:         bdrv_delete(s->bdrv);
  511:     }
  512: 
  513:     if (!s->bdrv || s->mem_oob)
  514:         free(s->storage);
  515: 
  516:     free(s);
  517: }
  518: 
  519: #else
  520: 
  521: /* Program a single page */
  522: static void glue(nand_blk_write_, PAGE_SIZE)(struct nand_flash_s *s)
  523: {
  524:     uint32_t off, page, sector, soff;
  525:     uint8_t iobuf[(PAGE_SECTORS + <