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

📄 nand.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
{    s->cle = cle;    s->ale = ale;    s->ce = ce;    s->wp = wp;    s->gnd = gnd;    if (wp)        s->status |= NAND_IOSTATUS_UNPROTCT;    else        s->status &= ~NAND_IOSTATUS_UNPROTCT;}void nand_getpins(struct nand_flash_s *s, int *rb){    *rb = 1;}void nand_setio(struct nand_flash_s *s, uint8_t value){    if (!s->ce && s->cle) {        if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) {            if (s->cmd == NAND_CMD_READ0 && value == NAND_CMD_LPREAD2)                return;            if (value == NAND_CMD_RANDOMREAD1) {                s->addr &= ~((1 << s->addr_shift) - 1);                s->addrlen = 0;                return;            }        }        if (value == NAND_CMD_READ0)            s->offset = 0;	else if (value == NAND_CMD_READ1) {            s->offset = 0x100;            value = NAND_CMD_READ0;        }	else if (value == NAND_CMD_READ2) {            s->offset = 1 << s->page_shift;            value = NAND_CMD_READ0;        }        s->cmd = value;        if (s->cmd == NAND_CMD_READSTATUS ||                s->cmd == NAND_CMD_PAGEPROGRAM2 ||                s->cmd == NAND_CMD_BLOCKERASE1 ||                s->cmd == NAND_CMD_BLOCKERASE2 ||                s->cmd == NAND_CMD_NOSERIALREAD2 ||                s->cmd == NAND_CMD_RANDOMREAD2 ||                s->cmd == NAND_CMD_RESET)            nand_command(s);        if (s->cmd != NAND_CMD_RANDOMREAD2) {            s->addrlen = 0;            s->addr = 0;        }    }    if (s->ale) {        s->addr |= value << (s->addrlen * 8);        s->addrlen ++;        if (s->addrlen == 1 && s->cmd == NAND_CMD_READID)            nand_command(s);        if (!(nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) &&                s->addrlen == 3 && (                    s->cmd == NAND_CMD_READ0 ||                    s->cmd == NAND_CMD_PAGEPROGRAM1))            nand_command(s);        if ((nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) &&               s->addrlen == 4 && (                    s->cmd == NAND_CMD_READ0 ||                    s->cmd == NAND_CMD_PAGEPROGRAM1))            nand_command(s);    }    if (!s->cle && !s->ale && s->cmd == NAND_CMD_PAGEPROGRAM1) {        if (s->iolen < (1 << s->page_shift) + (1 << s->oob_shift))            s->io[s->iolen ++] = value;    } else if (!s->cle && !s->ale && s->cmd == NAND_CMD_COPYBACKPRG1) {        if ((s->addr & ((1 << s->addr_shift) - 1)) <                (1 << s->page_shift) + (1 << s->oob_shift)) {            s->io[s->iolen + (s->addr & ((1 << s->addr_shift) - 1))] = value;            s->addr ++;        }    }}uint8_t nand_getio(struct nand_flash_s *s){    int offset;    /* Allow sequential reading */    if (!s->iolen && s->cmd == NAND_CMD_READ0) {        offset = (s->addr & ((1 << s->addr_shift) - 1)) + s->offset;        s->offset = 0;        s->blk_load(s, s->addr, offset);        if (s->gnd)            s->iolen = (1 << s->page_shift) - offset;        else            s->iolen = (1 << s->page_shift) + (1 << s->oob_shift) - offset;    }    if (s->ce || s->iolen <= 0)        return 0;    s->iolen --;    return *(s->ioaddr ++);}struct nand_flash_s *nand_init(int manf_id, int chip_id){    int pagesize;    struct nand_flash_s *s;    int index;    if (nand_flash_ids[chip_id].size == 0) {        cpu_abort(cpu_single_env, "%s: Unsupported NAND chip ID.\n",                        __FUNCTION__);    }    index = drive_get_index(IF_MTD, 0, 0);    if (index == -1) {        cpu_abort(cpu_single_env, "%s: missing MTD device\n",                        __FUNCTION__);    }    s = (struct nand_flash_s *) qemu_mallocz(sizeof(struct nand_flash_s));    s->bdrv = drives_table[index].bdrv;    s->manf_id = manf_id;    s->chip_id = chip_id;    s->size = nand_flash_ids[s->chip_id].size << 20;    if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) {        s->page_shift = 11;        s->erase_shift = 6;    } else {        s->page_shift = nand_flash_ids[s->chip_id].page_shift;        s->erase_shift = nand_flash_ids[s->chip_id].erase_shift;    }    switch (1 << s->page_shift) {    case 256:        nand_init_256(s);        break;    case 512:        nand_init_512(s);        break;    case 2048:        nand_init_2048(s);        break;    default:        cpu_abort(cpu_single_env, "%s: Unsupported NAND block size.\n",                        __FUNCTION__);    }    pagesize = 1 << s->oob_shift;    s->mem_oob = 1;    if (s->bdrv && bdrv_getlength(s->bdrv) >=                    (s->pages << s->page_shift) + (s->pages << s->oob_shift)) {        pagesize = 0;        s->mem_oob = 0;    }    if (!s->bdrv)        pagesize += 1 << s->page_shift;    if (pagesize)        s->storage = (uint8_t *) memset(qemu_malloc(s->pages * pagesize),                        0xff, s->pages * pagesize);    register_savevm("nand", nand_iid ++, 0, nand_save, nand_load, s);    return s;}void nand_done(struct nand_flash_s *s){    if (s->bdrv) {        bdrv_close(s->bdrv);        bdrv_delete(s->bdrv);    }    if (!s->bdrv || s->mem_oob)        free(s->storage);    free(s);}#else/* Program a single page */static void glue(nand_blk_write_, PAGE_SIZE)(struct nand_flash_s *s){    uint32_t off, page, sector, soff;    uint8_t iobuf[(PAGE_SECTORS + 2) * 0x200];    if (PAGE(s->addr) >= s->pages)        return;    if (!s->bdrv) {        memcpy(s->storage + PAGE_START(s->addr) + (s->addr & PAGE_MASK) +                        s->offset, s->io, s->iolen);    } else if (s->mem_oob) {        sector = SECTOR(s->addr);        off = (s->addr & PAGE_MASK) + s->offset;        soff = SECTOR_OFFSET(s->addr);        if (bdrv_read(s->bdrv, sector, iobuf, PAGE_SECTORS) == -1) {            printf("%s: read error in sector %i\n", __FUNCTION__, sector);            return;        }        memcpy(iobuf + (soff | off), s->io, MIN(s->iolen, PAGE_SIZE - off));        if (off + s->iolen > PAGE_SIZE) {            page = PAGE(s->addr);            memcpy(s->storage + (page << OOB_SHIFT), s->io + PAGE_SIZE - off,                            MIN(OOB_SIZE, off + s->iolen - PAGE_SIZE));        }        if (bdrv_write(s->bdrv, sector, iobuf, PAGE_SECTORS) == -1)            printf("%s: write error in sector %i\n", __FUNCTION__, sector);    } else {        off = PAGE_START(s->addr) + (s->addr & PAGE_MASK) + s->offset;        sector = off >> 9;        soff = off & 0x1ff;        if (bdrv_read(s->bdrv, sector, iobuf, PAGE_SECTORS + 2) == -1) {            printf("%s: read error in sector %i\n", __FUNCTION__, sector);            return;        }        memcpy(iobuf + soff, s->io, s->iolen);        if (bdrv_write(s->bdrv, sector, iobuf, PAGE_SECTORS + 2) == -1)            printf("%s: write error in sector %i\n", __FUNCTION__, sector);    }    s->offset = 0;}/* Erase a single block */static void glue(nand_blk_erase_, PAGE_SIZE)(struct nand_flash_s *s){    uint32_t i, page, addr;    uint8_t iobuf[0x200] = { [0 ... 0x1ff] = 0xff, };    addr = s->addr & ~((1 << (ADDR_SHIFT + s->erase_shift)) - 1);    if (PAGE(addr) >= s->pages)        return;    if (!s->bdrv) {        memset(s->storage + PAGE_START(addr),                        0xff, (PAGE_SIZE + OOB_SIZE) << s->erase_shift);    } else if (s->mem_oob) {        memset(s->storage + (PAGE(addr) << OOB_SHIFT),                        0xff, OOB_SIZE << s->erase_shift);        i = SECTOR(addr);        page = SECTOR(addr + (ADDR_SHIFT + s->erase_shift));        for (; i < page; i ++)            if (bdrv_write(s->bdrv, i, iobuf, 1) == -1)                printf("%s: write error in sector %i\n", __FUNCTION__, i);    } else {        addr = PAGE_START(addr);        page = addr >> 9;        if (bdrv_read(s->bdrv, page, iobuf, 1) == -1)            printf("%s: read error in sector %i\n", __FUNCTION__, page);        memset(iobuf + (addr & 0x1ff), 0xff, (~addr & 0x1ff) + 1);        if (bdrv_write(s->bdrv, page, iobuf, 1) == -1)            printf("%s: write error in sector %i\n", __FUNCTION__, page);        memset(iobuf, 0xff, 0x200);        i = (addr & ~0x1ff) + 0x200;        for (addr += ((PAGE_SIZE + OOB_SIZE) << s->erase_shift) - 0x200;                        i < addr; i += 0x200)            if (bdrv_write(s->bdrv, i >> 9, iobuf, 1) == -1)                printf("%s: write error in sector %i\n", __FUNCTION__, i >> 9);        page = i >> 9;        if (bdrv_read(s->bdrv, page, iobuf, 1) == -1)            printf("%s: read error in sector %i\n", __FUNCTION__, page);        memset(iobuf, 0xff, ((addr - 1) & 0x1ff) + 1);        if (bdrv_write(s->bdrv, page, iobuf, 1) == -1)            printf("%s: write error in sector %i\n", __FUNCTION__, page);    }}static void glue(nand_blk_load_, PAGE_SIZE)(struct nand_flash_s *s,                uint32_t addr, int offset){    if (PAGE(addr) >= s->pages)        return;    if (s->bdrv) {        if (s->mem_oob) {            if (bdrv_read(s->bdrv, SECTOR(addr), s->io, PAGE_SECTORS) == -1)                printf("%s: read error in sector %i\n",                                __FUNCTION__, SECTOR(addr));            memcpy(s->io + SECTOR_OFFSET(s->addr) + PAGE_SIZE,                            s->storage + (PAGE(s->addr) << OOB_SHIFT),                            OOB_SIZE);            s->ioaddr = s->io + SECTOR_OFFSET(s->addr) + offset;        } else {            if (bdrv_read(s->bdrv, PAGE_START(addr) >> 9,                                    s->io, (PAGE_SECTORS + 2)) == -1)                printf("%s: read error in sector %i\n",                                __FUNCTION__, PAGE_START(addr) >> 9);            s->ioaddr = s->io + (PAGE_START(addr) & 0x1ff) + offset;        }    } else {        memcpy(s->io, s->storage + PAGE_START(s->addr) +                        offset, PAGE_SIZE + OOB_SIZE - offset);        s->ioaddr = s->io;    }    s->addr &= PAGE_SIZE - 1;    s->addr += PAGE_SIZE;}static void glue(nand_init_, PAGE_SIZE)(struct nand_flash_s *s){    s->oob_shift = PAGE_SHIFT - 5;    s->pages = s->size >> PAGE_SHIFT;    s->addr_shift = ADDR_SHIFT;    s->blk_erase = glue(nand_blk_erase_, PAGE_SIZE);    s->blk_write = glue(nand_blk_write_, PAGE_SIZE);    s->blk_load = glue(nand_blk_load_, PAGE_SIZE);}# undef PAGE_SIZE# undef PAGE_SHIFT# undef PAGE_SECTORS# undef ADDR_SHIFT#endif	/* NAND_IO */

⌨️ 快捷键说明

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