⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nand.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
/* * Flash NAND memory emulation.  Based on "16M x 8 Bit NAND Flash * Memory" datasheet for the KM29U128AT / K9F2808U0A chips from * Samsung Electronic. * * Copyright (c) 2006 Openedhand Ltd. * Written by Andrzej Zaborowski <balrog@zabor.org> * * This code is licensed under the GNU GPL v2. */#ifndef NAND_IO# include "hw.h"# include "flash.h"# include "block.h"/* FIXME: Pass block device as an argument.  */# include "sysemu.h"# define NAND_CMD_READ0		0x00# define NAND_CMD_READ1		0x01# define NAND_CMD_READ2		0x50# define NAND_CMD_LPREAD2	0x30# define NAND_CMD_NOSERIALREAD2	0x35# define NAND_CMD_RANDOMREAD1	0x05# define NAND_CMD_RANDOMREAD2	0xe0# define NAND_CMD_READID	0x90# define NAND_CMD_RESET		0xff# define NAND_CMD_PAGEPROGRAM1	0x80# define NAND_CMD_PAGEPROGRAM2	0x10# define NAND_CMD_CACHEPROGRAM2	0x15# define NAND_CMD_BLOCKERASE1	0x60# define NAND_CMD_BLOCKERASE2	0xd0# define NAND_CMD_READSTATUS	0x70# define NAND_CMD_COPYBACKPRG1	0x85# define NAND_IOSTATUS_ERROR	(1 << 0)# define NAND_IOSTATUS_PLANE0	(1 << 1)# define NAND_IOSTATUS_PLANE1	(1 << 2)# define NAND_IOSTATUS_PLANE2	(1 << 3)# define NAND_IOSTATUS_PLANE3	(1 << 4)# define NAND_IOSTATUS_BUSY	(1 << 6)# define NAND_IOSTATUS_UNPROTCT	(1 << 7)# define MAX_PAGE		0x800# define MAX_OOB		0x40struct nand_flash_s {    uint8_t manf_id, chip_id;    int size, pages;    int page_shift, oob_shift, erase_shift, addr_shift;    uint8_t *storage;    BlockDriverState *bdrv;    int mem_oob;    int cle, ale, ce, wp, gnd;    uint8_t io[MAX_PAGE + MAX_OOB + 0x400];    uint8_t *ioaddr;    int iolen;    uint32_t cmd, addr;    int addrlen;    int status;    int offset;    void (*blk_write)(struct nand_flash_s *s);    void (*blk_erase)(struct nand_flash_s *s);    void (*blk_load)(struct nand_flash_s *s, uint32_t addr, int offset);};# define NAND_NO_AUTOINCR	0x00000001# define NAND_BUSWIDTH_16	0x00000002# define NAND_NO_PADDING	0x00000004# define NAND_CACHEPRG		0x00000008# define NAND_COPYBACK		0x00000010# define NAND_IS_AND		0x00000020# define NAND_4PAGE_ARRAY	0x00000040# define NAND_NO_READRDY	0x00000100# define NAND_SAMSUNG_LP	(NAND_NO_PADDING | NAND_COPYBACK)# define NAND_IO# define PAGE(addr)		((addr) >> ADDR_SHIFT)# define PAGE_START(page)	(PAGE(page) * (PAGE_SIZE + OOB_SIZE))# define PAGE_MASK		((1 << ADDR_SHIFT) - 1)# define OOB_SHIFT		(PAGE_SHIFT - 5)# define OOB_SIZE		(1 << OOB_SHIFT)# define SECTOR(addr)		((addr) >> (9 + ADDR_SHIFT - PAGE_SHIFT))# define SECTOR_OFFSET(addr)	((addr) & ((511 >> PAGE_SHIFT) << 8))# define PAGE_SIZE		256# define PAGE_SHIFT		8# define PAGE_SECTORS		1# define ADDR_SHIFT		8# include "nand.c"# define PAGE_SIZE		512# define PAGE_SHIFT		9# define PAGE_SECTORS		1# define ADDR_SHIFT		8# include "nand.c"# define PAGE_SIZE		2048# define PAGE_SHIFT		11# define PAGE_SECTORS		4# define ADDR_SHIFT		16# include "nand.c"/* Information based on Linux drivers/mtd/nand/nand_ids.c */struct nand_info_s {    int size;    int width;    int page_shift;    int erase_shift;    uint32_t options;} nand_flash_ids[0x100] = {    [0 ... 0xff] = { 0 },    [0x6e] = { 1,	8,	8, 4, 0 },    [0x64] = { 2,	8,	8, 4, 0 },    [0x6b] = { 4,	8,	9, 4, 0 },    [0xe8] = { 1,	8,	8, 4, 0 },    [0xec] = { 1,	8,	8, 4, 0 },    [0xea] = { 2,	8,	8, 4, 0 },    [0xd5] = { 4,	8,	9, 4, 0 },    [0xe3] = { 4,	8,	9, 4, 0 },    [0xe5] = { 4,	8,	9, 4, 0 },    [0xd6] = { 8,	8,	9, 4, 0 },    [0x39] = { 8,	8,	9, 4, 0 },    [0xe6] = { 8,	8,	9, 4, 0 },    [0x49] = { 8,	16,	9, 4, NAND_BUSWIDTH_16 },    [0x59] = { 8,	16,	9, 4, NAND_BUSWIDTH_16 },    [0x33] = { 16,	8,	9, 5, 0 },    [0x73] = { 16,	8,	9, 5, 0 },    [0x43] = { 16,	16,	9, 5, NAND_BUSWIDTH_16 },    [0x53] = { 16,	16,	9, 5, NAND_BUSWIDTH_16 },    [0x35] = { 32,	8,	9, 5, 0 },    [0x75] = { 32,	8,	9, 5, 0 },    [0x45] = { 32,	16,	9, 5, NAND_BUSWIDTH_16 },    [0x55] = { 32,	16,	9, 5, NAND_BUSWIDTH_16 },    [0x36] = { 64,	8,	9, 5, 0 },    [0x76] = { 64,	8,	9, 5, 0 },    [0x46] = { 64,	16,	9, 5, NAND_BUSWIDTH_16 },    [0x56] = { 64,	16,	9, 5, NAND_BUSWIDTH_16 },    [0x78] = { 128,	8,	9, 5, 0 },    [0x39] = { 128,	8,	9, 5, 0 },    [0x79] = { 128,	8,	9, 5, 0 },    [0x72] = { 128,	16,	9, 5, NAND_BUSWIDTH_16 },    [0x49] = { 128,	16,	9, 5, NAND_BUSWIDTH_16 },    [0x74] = { 128,	16,	9, 5, NAND_BUSWIDTH_16 },    [0x59] = { 128,	16,	9, 5, NAND_BUSWIDTH_16 },    [0x71] = { 256,	8,	9, 5, 0 },    /*     * These are the new chips with large page size. The pagesize and the     * erasesize is determined from the extended id bytes     */# define LP_OPTIONS	(NAND_SAMSUNG_LP | NAND_NO_READRDY | NAND_NO_AUTOINCR)# define LP_OPTIONS16	(LP_OPTIONS | NAND_BUSWIDTH_16)    /* 512 Megabit */    [0xa2] = { 64,	8,	0, 0, LP_OPTIONS },    [0xf2] = { 64,	8,	0, 0, LP_OPTIONS },    [0xb2] = { 64,	16,	0, 0, LP_OPTIONS16 },    [0xc2] = { 64,	16,	0, 0, LP_OPTIONS16 },    /* 1 Gigabit */    [0xa1] = { 128,	8,	0, 0, LP_OPTIONS },    [0xf1] = { 128,	8,	0, 0, LP_OPTIONS },    [0xb1] = { 128,	16,	0, 0, LP_OPTIONS16 },    [0xc1] = { 128,	16,	0, 0, LP_OPTIONS16 },    /* 2 Gigabit */    [0xaa] = { 256,	8,	0, 0, LP_OPTIONS },    [0xda] = { 256,	8,	0, 0, LP_OPTIONS },    [0xba] = { 256,	16,	0, 0, LP_OPTIONS16 },    [0xca] = { 256,	16,	0, 0, LP_OPTIONS16 },    /* 4 Gigabit */    [0xac] = { 512,	8,	0, 0, LP_OPTIONS },    [0xdc] = { 512,	8,	0, 0, LP_OPTIONS },    [0xbc] = { 512,	16,	0, 0, LP_OPTIONS16 },    [0xcc] = { 512,	16,	0, 0, LP_OPTIONS16 },    /* 8 Gigabit */    [0xa3] = { 1024,	8,	0, 0, LP_OPTIONS },    [0xd3] = { 1024,	8,	0, 0, LP_OPTIONS },    [0xb3] = { 1024,	16,	0, 0, LP_OPTIONS16 },    [0xc3] = { 1024,	16,	0, 0, LP_OPTIONS16 },    /* 16 Gigabit */    [0xa5] = { 2048,	8,	0, 0, LP_OPTIONS },    [0xd5] = { 2048,	8,	0, 0, LP_OPTIONS },    [0xb5] = { 2048,	16,	0, 0, LP_OPTIONS16 },    [0xc5] = { 2048,	16,	0, 0, LP_OPTIONS16 },};static void nand_reset(struct nand_flash_s *s){    s->cmd = NAND_CMD_READ0;    s->addr = 0;    s->addrlen = 0;    s->iolen = 0;    s->offset = 0;    s->status &= NAND_IOSTATUS_UNPROTCT;}static void nand_command(struct nand_flash_s *s){    switch (s->cmd) {    case NAND_CMD_READ0:        s->iolen = 0;        break;    case NAND_CMD_READID:        s->io[0] = s->manf_id;        s->io[1] = s->chip_id;        s->io[2] = 'Q';		/* Don't-care byte (often 0xa5) */        if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP)            s->io[3] = 0x15;	/* Page Size, Block Size, Spare Size.. */        else            s->io[3] = 0xc0;	/* Multi-plane */        s->ioaddr = s->io;        s->iolen = 4;        break;    case NAND_CMD_RANDOMREAD2:    case NAND_CMD_NOSERIALREAD2:        if (!(nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP))            break;        s->blk_load(s, s->addr, s->addr & ((1 << s->addr_shift) - 1));        break;    case NAND_CMD_RESET:        nand_reset(s);        break;    case NAND_CMD_PAGEPROGRAM1:        s->ioaddr = s->io;        s->iolen = 0;        break;    case NAND_CMD_PAGEPROGRAM2:        if (s->wp) {            s->blk_write(s);        }        break;    case NAND_CMD_BLOCKERASE1:        break;    case NAND_CMD_BLOCKERASE2:        if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP)            s->addr <<= 16;        else            s->addr <<= 8;        if (s->wp) {            s->blk_erase(s);        }        break;    case NAND_CMD_READSTATUS:        s->io[0] = s->status;        s->ioaddr = s->io;        s->iolen = 1;        break;    default:        printf("%s: Unknown NAND command 0x%02x\n", __FUNCTION__, s->cmd);    }}static void nand_save(QEMUFile *f, void *opaque){    struct nand_flash_s *s = (struct nand_flash_s *) opaque;    qemu_put_byte(f, s->cle);    qemu_put_byte(f, s->ale);    qemu_put_byte(f, s->ce);    qemu_put_byte(f, s->wp);    qemu_put_byte(f, s->gnd);    qemu_put_buffer(f, s->io, sizeof(s->io));    qemu_put_be32(f, s->ioaddr - s->io);    qemu_put_be32(f, s->iolen);    qemu_put_be32s(f, &s->cmd);    qemu_put_be32s(f, &s->addr);    qemu_put_be32(f, s->addrlen);    qemu_put_be32(f, s->status);    qemu_put_be32(f, s->offset);    /* XXX: do we want to save s->storage too? */}static int nand_load(QEMUFile *f, void *opaque, int version_id){    struct nand_flash_s *s = (struct nand_flash_s *) opaque;    s->cle = qemu_get_byte(f);    s->ale = qemu_get_byte(f);    s->ce = qemu_get_byte(f);    s->wp = qemu_get_byte(f);    s->gnd = qemu_get_byte(f);    qemu_get_buffer(f, s->io, sizeof(s->io));    s->ioaddr = s->io + qemu_get_be32(f);    s->iolen = qemu_get_be32(f);    if (s->ioaddr >= s->io + sizeof(s->io) || s->ioaddr < s->io)        return -EINVAL;    qemu_get_be32s(f, &s->cmd);    qemu_get_be32s(f, &s->addr);    s->addrlen = qemu_get_be32(f);    s->status = qemu_get_be32(f);    s->offset = qemu_get_be32(f);    return 0;}static int nand_iid = 0;/* * Chip inputs are CLE, ALE, CE, WP, GND and eight I/O pins.  Chip * outputs are R/B and eight I/O pins. * * CE, WP and R/B are active low. */void nand_setpins(struct nand_flash_s *s,                int cle, int ale, int ce, int wp, int gnd)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -