?? flash.c
字號:
#include "types.h"#include "bioscall.h"#include "flash.h"const struct flash_info table[] = { { mfr_id: MANUFACTURER_SST, dev_id: SST39VF040, name: "SST SST39VF040", size: 0x00080000, erasesize: 0x01000 }, { mfr_id: MANUFACTURER_SST, dev_id: SST39VF080, name: "SST SST39VF080", size: 0x00100000, erasesize: 0x01000 }, { mfr_id: MANUFACTURER_SST, dev_id: SST39VF016, name: "SST SST39VF016", size: 0x00200000, erasesize: 0x01000 }, { mfr_id: MANUFACTURER_HY, dev_id: HY29LV320B, name: "HY29LV320B", size: 0x00400000, erasesize: 0x02000 }};
struct mtd_info mtd;static unsigned char read8(struct mtd_info *mtd, unsigned long adr){ return *(unsigned char *)((mtd->offset + adr) | NOCACHE_BIT);}static unsigned short read16(struct mtd_info *mtd, unsigned long adr){ return *(unsigned short *)((mtd->offset + adr) | NOCACHE_BIT);}static unsigned long read32(struct mtd_info *mtd, unsigned long adr){ return *(unsigned long *)((mtd->offset + adr) | NOCACHE_BIT);}static void write8(struct mtd_info *mtd, unsigned char d, unsigned long adr){ *(unsigned char *)((mtd->offset + adr) | NOCACHE_BIT) = d;}static void write16(struct mtd_info *mtd, unsigned short d, unsigned long adr){ *(unsigned short *)((mtd->offset + adr) | NOCACHE_BIT) = d;}static void write32(struct mtd_info *mtd, unsigned long d, unsigned long adr){ *(unsigned long *)((mtd->offset + adr) | NOCACHE_BIT) = d;}static wide_read(struct mtd_info *mtd, unsigned long addr){ if (mtd->buswidth == 1) { return read8(mtd, addr); } else if (mtd->buswidth == 2) { return read16(mtd, addr); } else if (mtd->buswidth == 4) { return read32(mtd, addr); } return 0;}static void wide_write(struct mtd_info *mtd, unsigned long val, unsigned long addr){ if (mtd->buswidth == 1) { write8(mtd, val, addr); } else if (mtd->buswidth == 2) { write16(mtd, val, addr); } else if (mtd->buswidth == 4) { write32(mtd, val, addr); }}static unsigned long make_cmd(struct mtd_info *mtd, unsigned long cmd){ return cmd;}static void send_unlock(struct mtd_info *mtd, unsigned long base){ wide_write(mtd, (CMD_UNLOCK_DATA_1 << 16) | CMD_UNLOCK_DATA_1, base + (mtd->buswidth * ADDR_UNLOCK_1)); wide_write(mtd, (CMD_UNLOCK_DATA_2 << 16) | CMD_UNLOCK_DATA_2, base + (mtd->buswidth * ADDR_UNLOCK_2));}static void send_cmd(struct mtd_info *mtd, unsigned long base, unsigned long cmd){ send_unlock(mtd, base); wide_write(mtd, make_cmd(mtd, cmd), base + (mtd->buswidth * ADDR_UNLOCK_1));}static void send_cmd_to_addr(struct mtd_info *mtd, unsigned long base, unsigned long cmd, unsigned long addr){ send_unlock(mtd, base); wide_write(mtd, make_cmd(mtd, cmd), addr);}static int probe_chip(struct mtd_info *mtd, unsigned long base, struct flchip *chip){ unsigned long mfr_id; unsigned long dev_id; int table_size = sizeof(table) / sizeof(table[0]); int i; /* Enter autoselect mode. */ send_cmd(mtd, base, CMD_RESET_DATA); send_cmd(mtd, base, CMD_MANUFACTURER_UNLOCK_DATA); mfr_id = wide_read(mtd, base + (mtd->buswidth * ADDR_MANUFACTURER)); dev_id = wide_read(mtd, base + (mtd->buswidth * ADDR_DEVICE_ID)); /* Exit autoselect mode. */ send_cmd(mtd, base, CMD_RESET_DATA);#if 0//HHTECH wing.z for (i = 0; i < table_size; i++) { if ((mfr_id == table[i].mfr_id) && (dev_id == table[i].dev_id)) { if (chip) { chip->start = base; chip->size = table[i].size; chip->erasesize = table[i].erasesize; printf("Found "); printf(table[i].name); printf(" at %08x\r\n", base); } break; } }#endif if (chip) { chip->start = 0x00000000; chip->size = 0x00200000; chip->erasesize = 0x10000;//erasesize should not larger then 8K for the begining of 64k flash. }//HHTECH modified by wing.z if (i == table_size) return -1; return 0;}static int flash_is_busy(struct mtd_info *mtd, unsigned long addr){ return ((wide_read(mtd, addr) & D6_MASK) != (wide_read(mtd, addr) & D6_MASK));}static int erase_one_block(struct mtd_info *mtd, struct flchip *chip, unsigned long adr, unsigned long size){ int times_left; int ret = 0; adr += chip->start; send_cmd(mtd, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA); send_cmd_to_addr(mtd, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA_2, adr); times_left = 250000;//times_left = 500000; while (times_left-- && flash_is_busy(mtd, adr)); if (!times_left) { ret = -1; } return 0;}static int flash_erase_internal(struct mtd_info *mtd, unsigned long adr, unsigned long size){ struct flchip *chip; int chip_start, chip_end; int i, n; printf("Flash Erasing\r\n"); for (i = 0; i < mtd->numchips; i++) { chip = &mtd->chips[i]; chip_start = chip->start; chip_end = chip->start + chip->size; if ((adr >= chip_end) || (adr + size <= chip_start)) continue; if (chip_start < adr) chip_start = adr; if (chip_end > adr + size) chip_end = adr + size;//HHTECH erase begining 64K flash with 8k erasesizefor(n=chip_start; n<0x0010000; n +=0x2000){ erase_one_block(mtd, chip, n - chip->start, mtd->erasesize);}//by HHTECH wing.z#if 0 for (n = chip_start; n < chip_end; n += mtd->erasesize) { erase_one_block(mtd, chip, n - chip->start, mtd->erasesize); }#endif for (n = 0x0010000; n < chip_end; n += mtd->erasesize) { erase_one_block(mtd, chip, n - chip->start, mtd->erasesize); } } return 0;}static int flash_read_internal(struct mtd_info *mtd, unsigned long from, unsigned long len, unsigned long *retlen, unsigned char *buf){ if ((from + len) > mtd->size) return -1; memcpy(buf, (char *)((mtd->offset + from) | NOCACHE_BIT), len); *retlen = len; return 0;}static int write_one_word(struct mtd_info *mtd, struct flchip *chip, unsigned long adr, unsigned long datum){ int times_left; int ret = 0; adr += chip->start; send_cmd(mtd, chip->start, CMD_PROGRAM_UNLOCK_DATA); wide_write(mtd, datum, adr); times_left = 500000; while (times_left-- && flash_is_busy(mtd, adr)); if (!times_left) { ret = -1; } return ret;}static int flash_write_internal(struct mtd_info *mtd, unsigned long to, unsigned long len, unsigned long *retlen, const unsigned char *buf){ struct flchip *chip; int chip_start, chip_end; int i, n; *retlen = 0; for (i = 0; i < mtd->numchips; i++) { chip = &mtd->chips[i]; chip_start = chip->start; chip_end = chip->start + chip->size; if ((to >= chip_end) || (to + len <= chip_start)) continue; if (chip_start < to) chip_start = to; if (chip_end > to + len) chip_end = to + len; for (n = chip_start; n < chip_end; n=n+2) { write_one_word(mtd, chip, n - chip->start, buf[n+1 - to]*256 + buf[n - to]); } *retlen += chip_end - chip_start; } return 0;}int flash_init(void){ unsigned long flash_base; struct flchip *chip; int i; mtd.offset = bios_rom_base(); mtd.buswidth = 2; mtd.size = 0; mtd.numchips = 0; flash_base = 0; for (i = 0; i < MAX_CHIPS; i++) { chip = &mtd.chips[i]; if (probe_chip(&mtd, flash_base, chip) == 0) { if (i == 0) mtd.erasesize = chip->erasesize; else { if (mtd.erasesize != chip->erasesize) break; } mtd.size += chip->size; mtd.numchips++; flash_base+= chip->size; } else break; } return 0;}int flash_erase(unsigned long adr, unsigned long size){ return flash_erase_internal(&mtd, adr, size);}int flash_read(unsigned long from, unsigned long len, unsigned long *retlen, unsigned char *buf){ return flash_read_internal(&mtd, from, len, retlen, buf);}int flash_write(unsigned long to, unsigned long len, unsigned long *retlen, const unsigned char *buf){ return flash_write_internal(&mtd, to, len, retlen, buf);}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -