From 6e57fd96b912b9708a88a72fe3688dd4195cd6e6 Mon Sep 17 00:00:00 2001 From: none Date: Sat, 18 Jan 2020 16:23:09 +0100 Subject: [PATCH] ddupdate test version --- apps/flashprog.c | 90 +---- apps/octonet/ddflash.c | 536 +---------------------------- apps/octonet/ddtest.c | 28 +- apps/octonet/ddupdate.c | 245 +++++++++++++ apps/octonet/flash.c | 740 ++++++++++++++++++++++++++++++++++++---- apps/octonet/flash.h | 31 +- 6 files changed, 985 insertions(+), 685 deletions(-) create mode 100644 apps/octonet/ddupdate.c diff --git a/apps/flashprog.c b/apps/flashprog.c index 399df7e..8546f9d 100644 --- a/apps/flashprog.c +++ b/apps/flashprog.c @@ -32,10 +32,12 @@ #include #include #include +#include #include "flash.h" +#include "flash.c" -void get_id(int ddb, struct ddb_id *ddbid) { +void get_ddid(int ddb, struct ddb_id *ddbid) { uint8_t id[4]; if (ioctl(ddb, IOCTL_DDB_ID, ddbid)>=0) @@ -147,8 +149,8 @@ int main(int argc, char **argv) } Flash = flashdetect(ddb, &SectorSize, &FlashSize); - get_id(ddb, &ddbid); -#if 1 + get_ddid(ddb, &ddbid); +#if 0 printf("%04x %04x %04x %04x %08x %08x\n", ddbid.vendor, ddbid.device, ddbid.subvendor, ddbid.subdevice, @@ -202,85 +204,13 @@ int main(int argc, char **argv) } else { int fh, i; int fsize; + char *name; if (!fname) - switch (ddbid.device) { - case 0x0002: - fname="DVBBridgeV1A_DVBBridgeV1A.bit"; - printf("Octopus 35\n"); - break; - case 0x0003: - fname="DVBBridgeV1B_DVBBridgeV1B.fpga"; - printf("Octopus\n"); - break; - case 0x0005: - fname="DVBBridgeV2A_DD01_0005_STD.fpga"; - printf("Octopus Classic\n"); - break; - case 0x0006: - fname="DVBBridgeV2A_DD01_0006_STD.fpga"; - printf("CineS2 V7\n"); - break; - case 0x0007: - fname="DVBBridgeV2A_DD01_0007_MXL.fpga"; - printf("Octopus 4/8\n"); - break; - case 0x0008: - fname="DVBBridgeV2A_DD01_0008_CXD.fpga"; - printf("Octopus 4/8\n"); - break; - case 0x0009: - fname="DVBBridgeV2A_DD01_0009_SX8.fpga"; - printf("Octopus MAXSX8\n"); - break; - case 0x000a: - fname="DVBBridgeV2A_DD01_000A_M4.fpga"; - printf("Octopus MAXM4\n"); - break; - case 0x0011: - fname="DVBBridgeV2B_DD01_0011.fpga"; - printf("Octopus CI\n"); - break; - case 0x0012: - fname="DVBBridgeV2B_DD01_0012_STD.fpga"; - printf("Octopus CI\n"); - break; - case 0x0013: - fname="DVBBridgeV2B_DD01_0013_PRO.fpga"; - printf("Octopus PRO\n"); - break; - case 0x0020: - fname="DVBBridgeV2C_DD01_0020.fpga"; - printf("Octopus GT Mini\n"); - break; - case 0x0201: - fname="DVBModulatorV1B_DVBModulatorV1B.bit"; - printf("Modulator\n"); - break; - case 0x0203: - fname="DVBModulatorV1B_DD01_0203.fpga"; - printf("Modulator Test\n"); - break; - case 0x0210: - fname="DVBModulatorV2A_DD01_0210.fpga"; - printf("Modulator V2\n"); - break; - case 0x0220: - fname="SDRModulatorV1A_DD01_0220.fpga"; - printf("SDRModulator ATV\n"); - break; - case 0x0221: - fname="SDRModulatorV1A_DD01_0221_IQ.fpga"; - printf("SDRModulator IQ\n"); - break; - case 0x0222: - fname="SDRModulatorV1A_DD01_0222_DVBT.fpga"; - printf("SDRModulator DVBT\n"); - break; - default: - printf("UNKNOWN\n"); - break; - } + fname = devid2fname(ddbid.device, &name); + if (name) + printf("Card: %s\n", name); + fh = open(fname, O_RDONLY); if (fh < 0 ) { printf("File %s not found \n", fname); diff --git a/apps/octonet/ddflash.c b/apps/octonet/ddflash.c index 0b2865c..3d32c42 100644 --- a/apps/octonet/ddflash.c +++ b/apps/octonet/ddflash.c @@ -36,6 +36,7 @@ #include #include "flash.h" +#include "flash.c" static int reboot(uint32_t off) { @@ -55,540 +56,6 @@ static int reboot(uint32_t off) return 0; } -struct ddflash { - int fd; - struct ddb_id id; - uint32_t version; - - uint32_t flash_type; - uint32_t sector_size; - uint32_t size; - - uint32_t bufsize; - uint32_t block_erase; - - uint8_t *buffer; -}; - -int flashwrite_pagemode(struct ddflash *ddf, int dev, uint32_t FlashOffset, - uint8_t LockBits, uint32_t fw_off) -{ - int err = 0; - uint8_t cmd[260]; - int i, j; - uint32_t flen, blen; - - blen = flen = lseek(dev, 0, SEEK_END) - fw_off; - if (blen % 0xff) - blen = (blen + 0xff) & 0xffffff00; - printf("blen = %u, flen = %u\n", blen, flen); - - do { - cmd[0] = 0x50; // EWSR - err = flashio(ddf->fd, cmd, 1, NULL, 0); - if (err < 0) - break; - - cmd[0] = 0x01; // WRSR - cmd[1] = 0x00; // BPx = 0, Unlock all blocks - err = flashio(ddf->fd, cmd, 2, NULL, 0); - if (err < 0) - break; - - for (i = 0; i < flen; i += 4096) { - if ((i & 0xFFFF) == 0) - printf(" Erase %08x\n", FlashOffset + i); - - cmd[0] = 0x06; // WREN - err = flashio(ddf->fd, cmd, 1, NULL, 0); - if (err < 0) - break; - - cmd[0] = 0x20; // Sector erase ( 4Kb) - cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); - cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF ); - cmd[3] = 0x00; - err = flashio(ddf->fd, cmd, 4, NULL, 0); - if (err < 0) - break; - - while (1) { - cmd[0] = 0x05; // RDRS - err = flashio(ddf->fd, cmd, 1, &cmd[0], 1); - if (err < 0) - break; - if ((cmd[0] & 0x01) == 0) - break; - } - if (err < 0) - break; - - } - if (err < 0) - break; - - for (j = blen - 256; j >= 0; j -= 256 ) { - uint32_t len = 256; - ssize_t rlen; - - if (lseek(dev, j + fw_off, SEEK_SET) < 0) { - printf("seek error\n"); - return -1; - } - if (flen - j < 256) { - len = flen - j; - memset(ddf->buffer, 0xff, 256); - } - rlen = read(dev, ddf->buffer, len); - if (rlen < 0 || rlen != len) { - printf("file read error %d,%d at %u\n", rlen, errno, j); - return -1; - } - printf ("write %u bytes at %08x\n", len, j); - - - if ((j & 0xFFFF) == 0) - printf(" Programm %08x\n", FlashOffset + j); - - cmd[0] = 0x06; // WREN - err = flashio(ddf->fd, cmd, 1, NULL, 0); - if (err < 0) - break; - - cmd[0] = 0x02; // PP - cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF ); - cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF ); - cmd[3] = 0x00; - memcpy(&cmd[4], ddf->buffer, 256); - err = flashio(ddf->fd, cmd, 260, NULL, 0); - if (err < 0) - break; - - while(1) { - cmd[0] = 0x05; // RDRS - err = flashio(ddf->fd, cmd,1, &cmd[0], 1); - if (err < 0) - break; - if ((cmd[0] & 0x01) == 0) - break; - } - if (err < 0) - break; - - } - if (err < 0) - break; - - cmd[0] = 0x50; // EWSR - err = flashio(ddf->fd, cmd, 1, NULL, 0); - if (err < 0) - break; - - cmd[0] = 0x01; // WRSR - cmd[1] = LockBits; // BPx = 0, Lock all blocks - err = flashio(ddf->fd, cmd, 2, NULL, 0); - } while(0); - return err; -} - - -static int flashwrite_SSTI(struct ddflash *ddf, int fs, uint32_t FlashOffset, uint32_t maxlen, uint32_t fw_off) -{ - int err = 0; - uint8_t cmd[6]; - int i, j; - uint32_t flen, blen; - - blen = flen = lseek(fs, 0, SEEK_END) - fw_off; - if (blen % 0xfff) - blen = (blen + 0xfff) & 0xfffff000; - printf("blen = %u, flen = %u\n", blen, flen); - do { -#if 1 - cmd[0] = 0x50; // EWSR - err = flashio(ddf->fd, cmd, 1, NULL, 0); - if (err < 0) - break; - - cmd[0] = 0x01; // WRSR - cmd[1] = 0x00; // BPx = 0, Unlock all blocks - err = flashio(ddf->fd, cmd, 2, NULL, 0); - if (err < 0 ) - break; - - for (i = 0; i < flen; i += 4096) { - if ((i & 0xFFFF) == 0 ) - printf("Erase %08x\n", FlashOffset + i); - cmd[0] = 0x06; // WREN - err = flashio(ddf->fd, cmd, 1, NULL, 0); - if (err < 0 ) - break; - - cmd[0] = 0x20; // Sector erase ( 4Kb) - cmd[1] = (((FlashOffset + i ) >> 16) & 0xFF); - cmd[2] = (((FlashOffset + i ) >> 8) & 0xFF); - cmd[3] = 0x00; - err = flashio(ddf->fd,cmd,4,NULL,0); - if (err < 0 ) - break; - - while(1) { - cmd[0] = 0x05; // RDRS - err = flashio(ddf->fd,cmd,1,&cmd[0],1); - if (err < 0 ) break; - if ((cmd[0] & 0x01) == 0 ) break; - } - if (err < 0 ) break; - } - if (err < 0 ) - break; -#endif - for (j = blen - 4096; j >= 0; j -= 4096 ) { - uint32_t len = 4096; - ssize_t rlen; - - if (lseek(fs, j + fw_off, SEEK_SET) < 0) { - printf("seek error\n"); - return -1; - } - if (flen - j < 4096) { - len = flen - j; - memset(ddf->buffer, 0xff, 4096); - } - rlen = read(fs, ddf->buffer, len); - if (rlen < 0 || rlen != len) { - printf("file read error %d,%d at %u\n", rlen, errno, j); - return -1; - } - printf ("write %u bytes at %08x\n", len, j); - - if ((j & 0xFFFF) == 0 ) - printf(" Program %08x\n",FlashOffset + j); -#if 1 - for (i = 0; i < 4096; i += 2) { - if (i == 0) { - cmd[0] = 0x06; // WREN - err = flashio(ddf->fd, cmd, 1, NULL, 0); - if (err < 0 ) - break; - - cmd[0] = 0xAD; // AAI - cmd[1] = ((( FlashOffset + j ) >> 16) & 0xFF ); - cmd[2] = ((( FlashOffset + j ) >> 8) & 0xFF ); - cmd[3] = 0x00; - cmd[4] = ddf->buffer[i]; - cmd[5] = ddf->buffer[i + 1]; - err = flashio(ddf->fd,cmd,6,NULL,0); - } else { - cmd[0] = 0xAD; // AAI - cmd[1] = ddf->buffer[i]; - cmd[2] = ddf->buffer[i + 1]; - err = flashio(ddf->fd,cmd,3,NULL,0); - } - if (err < 0 ) - break; - - while(1) { - cmd[0] = 0x05; // RDRS - err = flashio(ddf->fd,cmd,1,&cmd[0],1); - if (err < 0 ) break; - if ((cmd[0] & 0x01) == 0 ) break; - } - if (err < 0 ) - break; - } - if (err < 0) - break; - - cmd[0] = 0x04; // WDIS - err = flashio(ddf->fd, cmd, 1, NULL, 0); - if (err < 0 ) - break; -#endif - } - if (err < 0 ) break; - - cmd[0] = 0x50; // EWSR - err = flashio(ddf->fd,cmd,1,NULL,0); - if (err < 0 ) break; - - cmd[0] = 0x01; // WRSR - cmd[1] = 0x1C; // BPx = 0, Lock all blocks - err = flashio(ddf->fd,cmd,2,NULL,0); - } while(0); - return err; -} - - -static int flashwrite(struct ddflash *ddf, int fs, uint32_t addr, uint32_t maxlen, uint32_t fw_off) -{ - switch (ddf->flash_type) { - case SSTI_SST25VF016B: - case SSTI_SST25VF032B: - return flashwrite_SSTI(ddf, fs, addr, maxlen, fw_off); - case SSTI_SST25VF064C: - return flashwrite_pagemode(ddf, fs, addr, 0x3c, fw_off); - case SPANSION_S25FL116K: - case SPANSION_S25FL132K: - case SPANSION_S25FL164K: - return flashwrite_pagemode(ddf, fs, addr, 0x1c, fw_off); - } - return -1; -} - -static int flashcmp(struct ddflash *ddf, int fs, uint32_t addr, uint32_t maxlen, uint32_t fw_off) -{ - off_t off; - uint32_t len; - int i, j, rlen; - uint8_t buf[256], buf2[256]; - int bl = sizeof(buf); - - off = lseek(fs, 0, SEEK_END); - if (off < 0) - return -1; - len = off - fw_off; - lseek(fs, fw_off, SEEK_SET); - if (len > maxlen) { - printf("file too big\n"); - return -1; - } - printf("flash file len %u, compare to %08x in flash\n", len, addr); - for (j = 0; j < len; j += bl, addr += bl) { - if (len - j < bl) - bl = len - j; - flashread(ddf->fd, buf, addr, bl); - rlen = read(fs, buf2, bl); - if (rlen < 0 || rlen != bl) { - printf("read error\n"); - return -1; - } - - if (memcmp(buf, buf2, bl)) { - printf("flash differs at %08x (offset %u)\n", addr, j); - dump(buf, 32); - dump(buf2, 32); - return addr; - } - } - printf("flash same as file\n"); - return -2; -} - - -static int flash_detect(struct ddflash *ddf) -{ - uint8_t cmd = 0x9F; - uint8_t id[3]; - - int r = flashio(ddf->fd, &cmd, 1, id, 3); - if (r < 0) - return r; - - if (id[0] == 0xBF && id[1] == 0x25 && id[2] == 0x41) { - ddf->flash_type = SSTI_SST25VF016B; - printf("Flash: SSTI SST25VF016B 16 MBit\n"); - ddf->sector_size = 4096; - ddf->size = 0x200000; - } else if (id[0] == 0xBF && id[1] == 0x25 && id[2] == 0x4A) { - ddf->flash_type = SSTI_SST25VF032B; - printf("Flash: SSTI SST25VF032B 32 MBit\n"); - ddf->sector_size = 4096; - ddf->size = 0x400000; - } else if (id[0] == 0xBF && id[1] == 0x25 && id[2] == 0x4B) { - ddf->flash_type = SSTI_SST25VF064C; - printf("Flash: SSTI SST25VF064C 64 MBit\n"); - ddf->sector_size = 4096; - ddf->size = 0x800000; - } else if (id[0] == 0x01 && id[1] == 0x40 && id[2] == 0x15) { - ddf->flash_type = SPANSION_S25FL116K; - printf("Flash: SPANSION S25FL116K 16 MBit\n"); - ddf->sector_size = 4096; - ddf->size = 0x200000; - } else if (id[0] == 0x01 && id[1] == 0x40 && id[2] == 0x16) { - ddf->flash_type = SPANSION_S25FL132K; - printf("Flash: SPANSION S25FL132K 32 MBit\n"); - ddf->sector_size = 4096; - ddf->size = 0x400000; - } else if (id[0] == 0x01 && id[1] == 0x40 && id[2] == 0x17) { - ddf->flash_type = SPANSION_S25FL164K; - printf("Flash: SPANSION S25FL164K 64 MBit\n"); - ddf->sector_size = 4096; - ddf->size = 0x800000; - } else if (id[0] == 0x1F && id[1] == 0x28) { - ddf->flash_type = ATMEL_AT45DB642D; - printf("Flash: Atmel AT45DB642D 64 MBit\n"); - ddf->sector_size = 1024; - ddf->size = 0x800000; - } else { - printf("Unknown Flash Flash ID = %02x %02x %02x\n", id[0], id[1], id[2]); - return -1; - } - if (ddf->sector_size) { - ddf->buffer = malloc(ddf->sector_size); - //printf("allocated buffer %08x@%08x\n", ddf->sector_size, (uint32_t) ddf->buffer); - if (!ddf->buffer) - return -1; - } - return 0; -} - - -static int get_id(struct ddflash *ddf) { - uint8_t id[4]; - - if (ioctl(ddf->fd, IOCTL_DDB_ID, &ddf->id) < 0) - return -1; -#if 1 - printf("%04x %04x %04x %04x %08x %08x\n", - ddf->id.vendor, ddf->id.device, - ddf->id.subvendor, ddf->id.subdevice, - ddf->id.hw, ddf->id.regmap); -#endif - return 0; -} - -static int check_fw(struct ddflash *ddf, char *fn, uint32_t *fw_off) -{ - int fd, fsize, ret = 0; - off_t off; - uint32_t p, i; - uint8_t *buf; - uint8_t hdr[256]; - unsigned int devid, version, length; - unsigned int cid[8]; - int cids = 0; - uint32_t maxlen = 1024 * 1024; - - fd = open(fn, O_RDONLY); - if (fd < 0) { - printf("%s: not found\n", fn); - return -1; - } - off = lseek(fd, 0, SEEK_END); - if (off < 0) - return -1; - fsize = off; - if (fsize > maxlen) { - close(fd); - return -1; - } - lseek(fd, 0, SEEK_SET); - buf = malloc(fsize); - if (!buf) - return -1; - read(fd, buf, fsize); - close(fd); - - for (p = 0; p < fsize && buf[p]; p++) { - char *key = &buf[p], *val = NULL; - - for (; p < fsize && buf[p] != 0x0a; p++) { - if (buf[p] == ':') { - buf[p] = 0; - val = &buf[p + 1]; - } - } - if (val == NULL || p == fsize) - break; - buf[p] = 0; - //printf("%-20s:%s\n", key, val); - if (!strcasecmp(key, "Devid")) { - sscanf(val, "%x", &devid); - } else if (!strcasecmp(key, "Compat")) { - cids = sscanf(val, "%x,%x,%x,%x,%x,%x,%x,%x", - &cid[0], &cid[1], &cid[2], &cid[3], - &cid[4], &cid[5], &cid[6], &cid[7]); - if (cids < 1) - break; - for (i = 0; i < cids; i++) - if (cid[i] == ddf->id.device) - break; - if (i == cids) { - printf("%s: no compatible id\n", fn); - ret = -2; /* no compatible ID */ - goto out; - } - } else if (!strcasecmp(key, "Version")) { - if (strchr(val,'.')) { - int major = 0, minor = 0; - sscanf(val,"%d.%d",&major,&minor); - version = (major << 16) + minor; - } else - sscanf(val, "%x", &version); - } else if (!strcasecmp(key, "Length")) { - sscanf(val, "%u", &length); - } - } - p++; - *fw_off = p; - printf("devid = %04x\n", devid); - printf("version = %08x %08x\n", version, ddf->id.hw); - printf("length = %u\n", length); - printf("fsize = %u, p = %u, f-p = %u\n", fsize, p, fsize - p); - if (devid == ddf->id.device) { - if (version <= (ddf->id.hw & 0xffffff)) { - printf("%s: old version\n", fn); - ret = -3; /* same id but no newer version */ - } - } else - ret = 1; - -out: - free(buf); - printf("check_fw = %d\n", ret); - return ret; - -} - -static int update_image(struct ddflash *ddf, char *fn, - uint32_t adr, uint32_t len, - int has_header, int no_change) -{ - int fs, res = 0; - uint32_t fw_off = 0; - - printf("Check %s\n", fn); - if (has_header) { - int ck; - - ck = check_fw(ddf, fn, &fw_off); - if (ck < 0) - return ck; - if (ck == 1 && no_change) - return 0; - } - fs = open(fn, O_RDONLY); - if (fs < 0 ) { - printf("File %s not found \n", fn); - return -1; - } - res = flashcmp(ddf, fs, adr, len, fw_off); - if (res == -2) { - printf("%s: same as flash\n", fn); - } - if (res < 0) - goto out; - res = flashwrite(ddf, fs, adr, len, fw_off); - if (res == 0) { - res = flashcmp(ddf, fs, adr, len, fw_off); - if (res == -2) { - res = 1; - } - } - -out: - close(fs); - return res; -} - - -static int fexists(char *fn) -{ - struct stat b; - - return (!stat(fn, &b)); -} static int update_flash(struct ddflash *ddf) { @@ -730,6 +197,7 @@ int main(int argc, char **argv) return -1; } } + ddf.link = 0; flash = flash_detect(&ddf); if (flash < 0) return -1; diff --git a/apps/octonet/ddtest.c b/apps/octonet/ddtest.c index fd5efe9..ba8e9fe 100644 --- a/apps/octonet/ddtest.c +++ b/apps/octonet/ddtest.c @@ -10,8 +10,10 @@ #include #include #include +#include #include "flash.h" +#include "flash.c" typedef int (*COMMAND_FUNCTION)(int dev, int argc, char* argv[], uint32_t Flags); @@ -108,12 +110,12 @@ int FlashChipEraseAtmel(int dev) Cmd[1] = ( (( i ) >> 16) & 0xFF ); Cmd[2] = ( (( i ) >> 8) & 0xFF ); Cmd[3] = 0x00; - err = flashio(dev,Cmd,4,NULL,0); + err = flashio(dev,linknr, Cmd,4,NULL,0); if( err < 0 ) break; while (1) { Cmd[0] = 0xD7; // Read Status register - err = flashio(dev,Cmd,1,&Cmd[0],1); + err = flashio(dev,linknr, Cmd,1,&Cmd[0],1); if( err < 0 ) break; if( (Cmd[0] & 0x80) == 0x80 ) break; } @@ -131,25 +133,25 @@ int FlashChipEraseSSTI(int dev) do { Cmd[0] = 0x50; // EWSR - err = flashio(dev,Cmd,1,NULL,0); + err = flashio(dev, linknr, Cmd,1,NULL,0); if( err < 0 ) break; Cmd[0] = 0x01; // WRSR Cmd[1] = 0x00; // BPx = 0, Unlock all blocks - err = flashio(dev,Cmd,2,NULL,0); + err = flashio(dev, linknr, Cmd,2,NULL,0); if( err < 0 ) break; Cmd[0] = 0x06; // WREN - err = flashio(dev,Cmd,1,NULL,0); + err = flashio(dev, linknr, Cmd,1,NULL,0); if( err < 0 ) break; Cmd[0] = 0x60; // CHIP Erase - err = flashio(dev,Cmd,1,NULL,0); + err = flashio(dev, linknr, Cmd,1,NULL,0); if( err < 0 ) break; while(1) { Cmd[0] = 0x05; // RDRS - err = flashio(dev,Cmd,1,&Cmd[0],1); + err = flashio(dev, linknr, Cmd,1,&Cmd[0],1); if( err < 0 ) break; if( (Cmd[0] & 0x01) == 0 ) break; } @@ -157,12 +159,12 @@ int FlashChipEraseSSTI(int dev) break; Cmd[0] = 0x50; // EWSR - err = flashio(dev,Cmd,1,NULL,0); + err = flashio(dev, linknr, Cmd,1,NULL,0); if( err < 0 ) break; Cmd[0] = 0x01; // WRSR Cmd[1] = 0x1C; // BPx = 0, Lock all blocks - err = flashio(dev,Cmd,2,NULL,0); + err = flashio(dev, linknr, Cmd,2,NULL,0); } while(0); @@ -332,7 +334,7 @@ int flashioc(int dev,int argc, char* argv[],uint32_t Flags) Buffer[i] = (uint8_t) tmp; } - if( flashio(dev,Buffer,WriteLen,Buffer,ReadLen) < 0 ) + if( flashio(dev, linknr, Buffer,WriteLen,Buffer,ReadLen) < 0 ) { return 0; } @@ -1289,7 +1291,7 @@ static int read_sfpd(int dev, uint8_t adr, uint8_t *val) uint8_t cmd[5] = { 0x5a, 0, 0, adr, 0 }; int r; - r = flashio(dev, cmd, 5, val, 1); + r = flashio(dev, linknr, cmd, 5, val, 1); if (r < 0) return r; return 0; @@ -1301,7 +1303,7 @@ static int read_sst_id(int dev, uint8_t *id) uint8_t buf[9]; int r; - r = flashio(dev, cmd, 2, buf, 9); + r = flashio(dev, linknr, cmd, 2, buf, 9); if (r < 0) return r; memcpy(id, buf + 1, 8); @@ -1313,7 +1315,7 @@ static int read_winbd(int dev, uint8_t *val) uint8_t cmd[5] = { 0x4b, 0, 0, 0, 0 }; int r; - r = flashio(dev, cmd, 5, val, 8); + r = flashio(dev, linknr, cmd, 5, val, 8); if (r < 0) return r; return 0; diff --git a/apps/octonet/ddupdate.c b/apps/octonet/ddupdate.c new file mode 100644 index 0000000..71596b2 --- /dev/null +++ b/apps/octonet/ddupdate.c @@ -0,0 +1,245 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "flash.h" +#include "flash.c" + +static int verbose = 0; + + +static int update_flash(struct ddflash *ddf) +{ + char *fname; + int res, stat = 0; + char *name; + + switch (ddf->id.device) { + case 0x300: + case 0x301: + case 0x302: + case 0x307: + if ((res = update_image(ddf, "/boot/bs.img", 0x4000, 0x1000, 0, 0)) == 1) + stat |= 4; + if ((res = update_image(ddf, "/boot/uboot.img", 0xb0000, 0xb0000, 0, 0)) == 1) + stat |= 2; + if (fexists("/config/gtl.enabled")) { + if ((res = update_image(ddf, "/config/fpga_gtl.img", 0x10000, 0xa0000, 1, 0)) == 1) + stat |= 1; + if (res == -1) + if ((res = update_image(ddf, "/boot/fpga_gtl.img", 0x10000, 0xa0000, 1, 0)) == 1) + stat |= 1; + } else if (fexists("/config/gtl.disabled")) { + if ((res = update_image(ddf, "/config/fpga.img", 0x10000, 0xa0000, 1, 0)) == 1) + stat |= 1; + if (res == -1) + if ((res = update_image(ddf, "/boot/fpga.img", 0x10000, 0xa0000, 1, 0)) == 1) + stat |= 1; + } else { + if (ddf->id.device == 0x0307) { + if (res == -1) + if ((res = update_image(ddf, "/config/fpga_gtl.img", 0x10000, 0xa0000, 1, 1)) == 1) + stat |= 1; + if (res == -1) + if ((res = update_image(ddf, "/boot/fpga_gtl.img", 0x10000, 0xa0000, 1, 1)) == 1) + stat |= 1; + } else { + if ((res = update_image(ddf, "/config/fpga.img", 0x10000, 0xa0000, 1, 1)) == 1) + stat |= 1; + if (res == -1) + if ((res = update_image(ddf, "/boot/fpga.img", 0x10000, 0xa0000, 1, 1)) == 1) + stat |= 1; + } + } +#if 1 + if ( (stat&1) && (ddf->id.hw & 0xffffff) <= 0x010001) { + if (ddf->id.device == 0x0307) { + if ((res = update_image(ddf, "/config/fpga_gtl.img", 0x160000, 0x80000, 1, 0)) == 1) + stat |= 1; + if (res == -1) + if ((res = update_image(ddf, "/boot/fpga_gtl.img", 0x160000, 0x80000, 1, 0)) == 1) + stat |= 1; + } else { + if ((res = update_image(ddf, "/config/fpga.img", 0x160000, 0x80000, 1, 0)) == 1) + stat |= 1; + if (res == -1) + if ((res = update_image(ddf, "/boot/fpga.img", 0x160000, 0x80000, 1, 0)) == 1) + stat |= 1; + + } + } +#endif + + break; + case 0x320: + //fname="/boot/DVBNetV1A_DD01_0300.bit"; + fname="/boot/fpga.img"; + if ((res = update_image(ddf, fname, 0x10000, 0x100000, 1, 0)) == 1) + stat |= 1; + return stat; + break; + case 0x322: + //fname="/boot/DVBNetV1A_DD01_0300.bit"; + fname="/boot/fpga.img"; + if ((res = update_image(ddf, fname, 0x10000, 0x100000, 1, 0)) == 1) + stat |= 1; + return stat; + break; + default: + fname = ddf->fname; + if (!fname) + fname = devid2fname(ddf->id.device, &name); + if (name) + printf("Card: %s\n", name); + if ((res = update_image(ddf, fname, 0x10000, 0x100000, 1, 0)) == 1) + stat |= 1; + return stat; + } + return stat; +} + +static int ddupdate(struct ddflash *ddf) +{ + int ret; + + if (verbose >= 2) + printf("Detect flash type\n"); + ret = flash_detect(ddf); + if (ret < 0) + return ret; + ret = update_flash(ddf); + + if (ddf->buffer) + free(ddf->buffer); + + return ret; +} + +static int proc_card(int ddbnum, char *fname) +{ + struct ddflash ddf; + char ddbname[80]; + struct ddb_id ddbid; + int ddb, ret, link, links; + + sprintf(ddbname, "/dev/ddbridge/card%d", ddbnum); + if (verbose >= 2) + printf("Update card %s\n", ddbname); + ddb = open(ddbname, O_RDWR); + if (ddb < 0) + return -3; + ddf.fd = ddb; + ddf.link = 0; + ddf.fname = fname; + links = 1; + + for (link = 0; link < links; link++) { + ddf.link = link; + if (verbose >= 2) + printf("Get id card %u link %u\n", ddbnum, link); + ret = get_id(&ddf); + if (ret < 0) + goto out; + if (!link) { + switch (ddf.id.device) { + case 0x20: + links = 4; + break; + case 0x300: + case 0x301: + case 0x307: + links = 1; + break; + + default: + break; + } + } + + //printf("%08x %08x\n", ddf.id.device, ddf.id.subdevice); + if (ddf.id.device) { + ret = ddupdate(&ddf); + if (ret < 0) + break; + } + } + +out: + close(ddb); + return ret; +} + + +int main(int argc, char **argv) +{ + int ddbnum = 0, all = 0, i, force = 0; + char *fname; + + while (1) { + int option_index = 0; + int c; + static struct option long_options[] = { + {"help", no_argument , NULL, 'h'}, + {0, 0, 0, 0} + }; + c = getopt_long(argc, argv, + "n:havfb:", + long_options, &option_index); + if (c==-1) + break; + + switch (c) { + case 'b': + fname = optarg; + break; + case 'n': + ddbnum = strtol(optarg, NULL, 0); + break; + case 'a': + all = 1; + break; + case 'v': + verbose++; + break; + case 'h': + printf("ddupdate [OPTION]\n\n" + "-n N\n only update card N (default with N=0)\n\n" + "-a \n update all cards\n\n" + "-b file\n fpga image file override (not if -a is used)\n\n" + "-v \n more verbose (up to -v -v -v)\n\n" + ); + break; + default: + break; + + } + } + if (optind < argc) { + printf("Warning: unused arguments\n"); + } + + if (!all) + return proc_card(ddbnum, fname); + + for (i = 0; i < 20; i++) { + int ret = proc_card(i, 0); + + if (ret == -3) /* could not open, no more cards! */ + break; + if (ret < 0) + return i; /* fatal error */ + if (verbose >= 1) + printf("card %d up to date\n", i); + } + return 0; +} diff --git a/apps/octonet/flash.c b/apps/octonet/flash.c index 82621d7..b8f2234 100644 --- a/apps/octonet/flash.c +++ b/apps/octonet/flash.c @@ -1,25 +1,14 @@ -enum { - UNKNOWN_FLASH = 0, - ATMEL_AT45DB642D = 1, - SSTI_SST25VF016B = 2, - SSTI_SST25VF032B = 3, - SSTI_SST25VF064C = 4, - SPANSION_S25FL116K = 5, - SPANSION_S25FL132K = 6, - SPANSION_S25FL164K = 7, - WINBOND_W25Q16JV = 8, -}; - static uint32_t linknr = 0; -int flashio(int ddb, uint8_t *wbuf, uint32_t wlen, uint8_t *rbuf, uint32_t rlen) +int flashio(int ddb, int link, + uint8_t *wbuf, uint32_t wlen, uint8_t *rbuf, uint32_t rlen) { struct ddb_flashio fio = { .write_buf=wbuf, .write_len=wlen, .read_buf=rbuf, .read_len=rlen, - .link=linknr, + .link=link, }; return ioctl(ddb, IOCTL_DDB_FLASHIO, &fio); @@ -30,7 +19,7 @@ int FlashDetect(int dev) uint8_t Cmd = 0x9F; uint8_t Id[3]; - int r = flashio(dev, &Cmd, 1, Id, 3); + int r = flashio(dev, linknr, &Cmd, 1, Id, 3); if (r < 0) return r; @@ -92,7 +81,7 @@ static int flashdetect(int fd, uint32_t *sector_size, uint32_t *flash_size) uint8_t id[3]; int flash_type; - int r = flashio(fd, &cmd, 1, id, 3); + int r = flashio(fd, linknr, &cmd, 1, id, 3); if (r < 0) return r; @@ -161,7 +150,7 @@ int flashread(int ddb, uint8_t *buf, uint32_t addr, uint32_t len) l = 1024; else l = len; - ret = flashio(ddb, cmd, 4, buf, l); + ret = flashio(ddb, linknr, cmd, 4, buf, l); if (ret < 0) return ret; addr += l; @@ -176,7 +165,7 @@ static int flashread(int ddb, uint8_t *buf, uint32_t addr, uint32_t len) uint8_t cmd[4]= {0x03, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff}; - return flashio(ddb, cmd, 4, buf, len); + return flashio(ddb, linknr, cmd, 4, buf, len); } #endif @@ -273,13 +262,13 @@ int FlashWriteAtmel(int dev,uint32_t FlashOffset, uint8_t *Buffer,int BufferSize Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF ); Cmd[3] = 0x00; - err = flashio(dev,Cmd,4,NULL,0); + err = flashio(dev,linknr, Cmd,4,NULL,0); if( err < 0 ) break; while( 1 ) { Cmd[0] = 0xD7; // Read Status register - err = flashio(dev,Cmd,1,&Cmd[0],1); + err = flashio(dev,linknr, Cmd,1,&Cmd[0],1); if( err < 0 ) break; if( (Cmd[0] & 0x80) == 0x80 ) break; } @@ -299,7 +288,7 @@ int FlashWriteAtmel(int dev,uint32_t FlashOffset, uint8_t *Buffer,int BufferSize Cmd[3] = 0x00; memcpy(&Cmd[4],&Buffer[i],1024); - err = flashio(dev,Cmd,4 + 1024,NULL,0); + err = flashio(dev,linknr, Cmd,4 + 1024,NULL,0); if( err < 0 ) break; Cmd[0] = BlockErase ? 0x88 : 0x83; // Buffer to Main Memory (with Erase) @@ -307,13 +296,13 @@ int FlashWriteAtmel(int dev,uint32_t FlashOffset, uint8_t *Buffer,int BufferSize Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF ); Cmd[3] = 0x00; - err = flashio(dev,Cmd,4,NULL,0); + err = flashio(dev,linknr, Cmd,4,NULL,0); if( err < 0 ) break; while( 1 ) { Cmd[0] = 0xD7; // Read Status register - err = flashio(dev,Cmd,1,&Cmd[0],1); + err = flashio(dev,linknr, Cmd,1,&Cmd[0],1); if( err < 0 ) break; if( (Cmd[0] & 0x80) == 0x80 ) break; } @@ -335,13 +324,13 @@ int FlashWriteSSTI(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferSiz do { cmd[0] = 0x50; // EWSR - err = flashio(dev,cmd,1,NULL,0); + err = flashio(dev,linknr, cmd,1,NULL,0); if (err < 0 ) break; cmd[0] = 0x01; // WRSR cmd[1] = 0x00; // BPx = 0, Unlock all blocks - err = flashio(dev,cmd,2,NULL,0); + err = flashio(dev,linknr, cmd,2,NULL,0); if (err < 0 ) break; @@ -349,7 +338,7 @@ int FlashWriteSSTI(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferSiz if ((i & 0xFFFF) == 0 ) printf(" Erase %08x\n",FlashOffset + i); cmd[0] = 0x06; // WREN - err = flashio(dev,cmd,1,NULL,0); + err = flashio(dev,linknr, cmd,1,NULL,0); if (err < 0 ) break; @@ -357,13 +346,13 @@ int FlashWriteSSTI(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferSiz cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF ); cmd[3] = 0x00; - err = flashio(dev,cmd,4,NULL,0); + err = flashio(dev,linknr, cmd,4,NULL,0); if (err < 0 ) break; while(1) { cmd[0] = 0x05; // RDRS - err = flashio(dev,cmd,1,&cmd[0],1); + err = flashio(dev,linknr, cmd,1,&cmd[0],1); if (err < 0 ) break; if ((cmd[0] & 0x01) == 0 ) break; } @@ -378,7 +367,7 @@ int FlashWriteSSTI(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferSiz for (i = 0; i < 4096; i += 2 ) { if (i == 0 ) { cmd[0] = 0x06; // WREN - err = flashio(dev,cmd,1,NULL,0); + err = flashio(dev,linknr, cmd,1,NULL,0); if (err < 0 ) break; @@ -388,19 +377,19 @@ int FlashWriteSSTI(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferSiz cmd[3] = 0x00; cmd[4] = Buffer[j+i]; cmd[5] = Buffer[j+i+1]; - err = flashio(dev,cmd,6,NULL,0); + err = flashio(dev,linknr, cmd,6,NULL,0); } else { cmd[0] = 0xAD; // AAI cmd[1] = Buffer[j+i]; cmd[2] = Buffer[j+i+1]; - err = flashio(dev,cmd,3,NULL,0); + err = flashio(dev,linknr, cmd,3,NULL,0); } if (err < 0 ) break; while(1) { cmd[0] = 0x05; // RDRS - err = flashio(dev,cmd,1,&cmd[0],1); + err = flashio(dev,linknr, cmd,1,&cmd[0],1); if (err < 0 ) break; if ((cmd[0] & 0x01) == 0 ) break; } @@ -409,19 +398,19 @@ int FlashWriteSSTI(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferSiz if (err < 0 ) break; cmd[0] = 0x04; // WDIS - err = flashio(dev,cmd,1,NULL,0); + err = flashio(dev,linknr, cmd,1,NULL,0); if (err < 0 ) break; } if (err < 0 ) break; cmd[0] = 0x50; // EWSR - err = flashio(dev,cmd,1,NULL,0); + err = flashio(dev,linknr, cmd,1,NULL,0); if (err < 0 ) break; cmd[0] = 0x01; // WRSR cmd[1] = 0x1C; // BPx = 0, Lock all blocks - err = flashio(dev,cmd,2,NULL,0); + err = flashio(dev,linknr, cmd,2,NULL,0); } while(0); return err; } @@ -438,13 +427,13 @@ int FlashWriteSSTI_B(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferS do { Cmd[0] = 0x50; // EWSR - err = flashio(dev,Cmd,1,NULL,0); + err = flashio(dev,linknr, Cmd,1,NULL,0); if( err < 0 ) break; Cmd[0] = 0x01; // WRSR Cmd[1] = 0x00; // BPx = 0, Unlock all blocks - err = flashio(dev,Cmd,2,NULL,0); + err = flashio(dev,linknr, Cmd,2,NULL,0); if( err < 0 ) break; @@ -452,7 +441,7 @@ int FlashWriteSSTI_B(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferS if( (i & 0xFFFF) == 0 ) printf(" Erase %08x\n",FlashOffset + i); Cmd[0] = 0x06; // WREN - err = flashio(dev,Cmd,1,NULL,0); + err = flashio(dev,linknr, Cmd,1,NULL,0); if( err < 0 ) break; @@ -460,13 +449,13 @@ int FlashWriteSSTI_B(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferS Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF ); Cmd[3] = 0x00; - err = flashio(dev,Cmd,4,NULL,0); + err = flashio(dev,linknr, Cmd,4,NULL,0); if( err < 0 ) break; while(1) { Cmd[0] = 0x05; // RDRS - err = flashio(dev,Cmd,1,&Cmd[0],1); + err = flashio(dev,linknr, Cmd,1,&Cmd[0],1); if( err < 0 ) break; if( (Cmd[0] & 0x01) == 0 ) break; } @@ -481,7 +470,7 @@ int FlashWriteSSTI_B(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferS for(i = 0; i < 4096; i += 2 ) { if( i == 0 ) { Cmd[0] = 0x06; // WREN - err = flashio(dev,Cmd,1,NULL,0); + err = flashio(dev,linknr, Cmd,1,NULL,0); if( err < 0 ) break; @@ -491,19 +480,19 @@ int FlashWriteSSTI_B(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferS Cmd[3] = 0x00; Cmd[4] = Buffer[j+i]; Cmd[5] = Buffer[j+i+1]; - err = flashio(dev,Cmd,6,NULL,0); + err = flashio(dev,linknr, Cmd,6,NULL,0); } else { Cmd[0] = 0xAD; // AAI Cmd[1] = Buffer[j+i]; Cmd[2] = Buffer[j+i+1]; - err = flashio(dev,Cmd,3,NULL,0); + err = flashio(dev,linknr, Cmd,3,NULL,0); } if( err < 0 ) break; while(1) { Cmd[0] = 0x05; // RDRS - err = flashio(dev,Cmd,1,&Cmd[0],1); + err = flashio(dev,linknr, Cmd,1,&Cmd[0],1); if( err < 0 ) break; if( (Cmd[0] & 0x01) == 0 ) break; } @@ -512,19 +501,19 @@ int FlashWriteSSTI_B(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferS if( err < 0 ) break; Cmd[0] = 0x04; // WDIS - err = flashio(dev,Cmd,1,NULL,0); + err = flashio(dev,linknr, Cmd,1,NULL,0); if( err < 0 ) break; } if( err < 0 ) break; Cmd[0] = 0x50; // EWSR - err = flashio(dev,Cmd,1,NULL,0); + err = flashio(dev,linknr, Cmd,1,NULL,0); if( err < 0 ) break; Cmd[0] = 0x01; // WRSR Cmd[1] = 0x1C; // BPx = 0, Lock all blocks - err = flashio(dev,Cmd,2,NULL,0); + err = flashio(dev,linknr, Cmd,2,NULL,0); } while(0); return err; } @@ -541,12 +530,12 @@ int FlashWritePageMode(int dev, uint32_t FlashOffset, do { Cmd[0] = 0x50; // EWSR - err = flashio(dev,Cmd,1,NULL,0); + err = flashio(dev,linknr, Cmd,1,NULL,0); if( err < 0 ) break; Cmd[0] = 0x01; // WRSR Cmd[1] = 0x00; // BPx = 0, Unlock all blocks - err = flashio(dev,Cmd,2,NULL,0); + err = flashio(dev,linknr, Cmd,2,NULL,0); if( err < 0 ) break; for(i = 0; i < BufferSize; i += 4096 ) @@ -557,20 +546,20 @@ int FlashWritePageMode(int dev, uint32_t FlashOffset, } Cmd[0] = 0x06; // WREN - err = flashio(dev,Cmd,1,NULL,0); + err = flashio(dev,linknr, Cmd,1,NULL,0); if( err < 0 ) break; Cmd[0] = 0x20; // Sector erase ( 4Kb) Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF ); Cmd[3] = 0x00; - err = flashio(dev,Cmd,4,NULL,0); + err = flashio(dev,linknr, Cmd,4,NULL,0); if( err < 0 ) break; while(1) { Cmd[0] = 0x05; // RDRS - err = flashio(dev,Cmd,1,&Cmd[0],1); + err = flashio(dev,linknr, Cmd,1,&Cmd[0],1); if( err < 0 ) break; if( (Cmd[0] & 0x01) == 0 ) break; } @@ -588,7 +577,7 @@ int FlashWritePageMode(int dev, uint32_t FlashOffset, } Cmd[0] = 0x06; // WREN - err = flashio(dev,Cmd,1,NULL,0); + err = flashio(dev,linknr, Cmd,1,NULL,0); if( err < 0 ) break; Cmd[0] = 0x02; // PP @@ -596,13 +585,13 @@ int FlashWritePageMode(int dev, uint32_t FlashOffset, Cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF ); Cmd[3] = 0x00; memcpy(&Cmd[4],&Buffer[j],256); - err = flashio(dev,Cmd,260,NULL,0); + err = flashio(dev,linknr, Cmd,260,NULL,0); if( err < 0 ) break; while(1) { Cmd[0] = 0x05; // RDRS - err = flashio(dev,Cmd,1,&Cmd[0],1); + err = flashio(dev,linknr, Cmd,1,&Cmd[0],1); if( err < 0 ) break; if( (Cmd[0] & 0x01) == 0 ) break; } @@ -612,14 +601,651 @@ int FlashWritePageMode(int dev, uint32_t FlashOffset, if( err < 0 ) break; Cmd[0] = 0x50; // EWSR - err = flashio(dev,Cmd,1,NULL,0); + err = flashio(dev,linknr, Cmd,1,NULL,0); if( err < 0 ) break; Cmd[0] = 0x01; // WRSR Cmd[1] = LockBits; // BPx = 0, Lock all blocks - err = flashio(dev,Cmd,2,NULL,0); + err = flashio(dev,linknr, Cmd,2,NULL,0); } while(0); return err; } + +int flashwrite_pagemode(struct ddflash *ddf, int dev, uint32_t FlashOffset, + uint8_t LockBits, uint32_t fw_off) +{ + int err = 0; + uint8_t cmd[260]; + int i, j; + uint32_t flen, blen; + + blen = flen = lseek(dev, 0, SEEK_END) - fw_off; + if (blen % 0xff) + blen = (blen + 0xff) & 0xffffff00; + printf("blen = %u, flen = %u\n", blen, flen); + + do { + cmd[0] = 0x50; // EWSR + err = flashio(ddf->fd, ddf->link, cmd, 1, NULL, 0); + if (err < 0) + break; + + cmd[0] = 0x01; // WRSR + cmd[1] = 0x00; // BPx = 0, Unlock all blocks + err = flashio(ddf->fd, ddf->link, cmd, 2, NULL, 0); + if (err < 0) + break; + + for (i = 0; i < flen; i += 4096) { + if ((i & 0xFFFF) == 0) + printf(" Erase %08x\n", FlashOffset + i); + + cmd[0] = 0x06; // WREN + err = flashio(ddf->fd, ddf->link, cmd, 1, NULL, 0); + if (err < 0) + break; + + cmd[0] = 0x20; // Sector erase ( 4Kb) + cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); + cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF ); + cmd[3] = 0x00; + err = flashio(ddf->fd, ddf->link, cmd, 4, NULL, 0); + if (err < 0) + break; + + while (1) { + cmd[0] = 0x05; // RDRS + err = flashio(ddf->fd, ddf->link, cmd, 1, &cmd[0], 1); + if (err < 0) + break; + if ((cmd[0] & 0x01) == 0) + break; + } + if (err < 0) + break; + + } + if (err < 0) + break; + + for (j = blen - 256; j >= 0; j -= 256 ) { + uint32_t len = 256; + ssize_t rlen; + + if (lseek(dev, j + fw_off, SEEK_SET) < 0) { + printf("seek error\n"); + return -1; + } + if (flen - j < 256) { + len = flen - j; + memset(ddf->buffer, 0xff, 256); + } + rlen = read(dev, ddf->buffer, len); + if (rlen < 0 || rlen != len) { + printf("file read error %d,%d at %u\n", rlen, errno, j); + return -1; + } + printf ("write %u bytes at %08x\n", len, j); + + + if ((j & 0xFFFF) == 0) + printf(" Programm %08x\n", FlashOffset + j); + + cmd[0] = 0x06; // WREN + err = flashio(ddf->fd, ddf->link, cmd, 1, NULL, 0); + if (err < 0) + break; + + cmd[0] = 0x02; // PP + cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF ); + cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF ); + cmd[3] = 0x00; + memcpy(&cmd[4], ddf->buffer, 256); + err = flashio(ddf->fd, ddf->link, cmd, 260, NULL, 0); + if (err < 0) + break; + + while(1) { + cmd[0] = 0x05; // RDRS + err = flashio(ddf->fd, ddf->link, cmd,1, &cmd[0], 1); + if (err < 0) + break; + if ((cmd[0] & 0x01) == 0) + break; + } + if (err < 0) + break; + + } + if (err < 0) + break; + + cmd[0] = 0x50; // EWSR + err = flashio(ddf->fd, ddf->link, cmd, 1, NULL, 0); + if (err < 0) + break; + + cmd[0] = 0x01; // WRSR + cmd[1] = LockBits; // BPx = 0, Lock all blocks + err = flashio(ddf->fd, ddf->link, cmd, 2, NULL, 0); + } while(0); + return err; +} + + +static int flashwrite_SSTI(struct ddflash *ddf, int fs, uint32_t FlashOffset, uint32_t maxlen, uint32_t fw_off) +{ + int err = 0; + uint8_t cmd[6]; + int i, j; + uint32_t flen, blen; + + blen = flen = lseek(fs, 0, SEEK_END) - fw_off; + if (blen % 0xfff) + blen = (blen + 0xfff) & 0xfffff000; + printf("blen = %u, flen = %u\n", blen, flen); + do { +#if 1 + cmd[0] = 0x50; // EWSR + err = flashio(ddf->fd, ddf->link, cmd, 1, NULL, 0); + if (err < 0) + break; + + cmd[0] = 0x01; // WRSR + cmd[1] = 0x00; // BPx = 0, Unlock all blocks + err = flashio(ddf->fd, ddf->link, cmd, 2, NULL, 0); + if (err < 0 ) + break; + + for (i = 0; i < flen; i += 4096) { + if ((i & 0xFFFF) == 0 ) + printf("Erase %08x\n", FlashOffset + i); + cmd[0] = 0x06; // WREN + err = flashio(ddf->fd, ddf->link, cmd, 1, NULL, 0); + if (err < 0 ) + break; + + cmd[0] = 0x20; // Sector erase ( 4Kb) + cmd[1] = (((FlashOffset + i ) >> 16) & 0xFF); + cmd[2] = (((FlashOffset + i ) >> 8) & 0xFF); + cmd[3] = 0x00; + err = flashio(ddf->fd,ddf->link, cmd,4,NULL,0); + if (err < 0 ) + break; + + while(1) { + cmd[0] = 0x05; // RDRS + err = flashio(ddf->fd,ddf->link, cmd,1,&cmd[0],1); + if (err < 0 ) break; + if ((cmd[0] & 0x01) == 0 ) break; + } + if (err < 0 ) break; + } + if (err < 0 ) + break; +#endif + for (j = blen - 4096; j >= 0; j -= 4096 ) { + uint32_t len = 4096; + ssize_t rlen; + + if (lseek(fs, j + fw_off, SEEK_SET) < 0) { + printf("seek error\n"); + return -1; + } + if (flen - j < 4096) { + len = flen - j; + memset(ddf->buffer, 0xff, 4096); + } + rlen = read(fs, ddf->buffer, len); + if (rlen < 0 || rlen != len) { + printf("file read error %d,%d at %u\n", rlen, errno, j); + return -1; + } + printf ("write %u bytes at %08x\n", len, j); + + if ((j & 0xFFFF) == 0 ) + printf(" Program %08x\n",FlashOffset + j); +#if 1 + for (i = 0; i < 4096; i += 2) { + if (i == 0) { + cmd[0] = 0x06; // WREN + err = flashio(ddf->fd, ddf->link, cmd, 1, NULL, 0); + if (err < 0 ) + break; + + cmd[0] = 0xAD; // AAI + cmd[1] = ((( FlashOffset + j ) >> 16) & 0xFF ); + cmd[2] = ((( FlashOffset + j ) >> 8) & 0xFF ); + cmd[3] = 0x00; + cmd[4] = ddf->buffer[i]; + cmd[5] = ddf->buffer[i + 1]; + err = flashio(ddf->fd,ddf->link, cmd,6,NULL,0); + } else { + cmd[0] = 0xAD; // AAI + cmd[1] = ddf->buffer[i]; + cmd[2] = ddf->buffer[i + 1]; + err = flashio(ddf->fd,ddf->link, cmd,3,NULL,0); + } + if (err < 0 ) + break; + + while(1) { + cmd[0] = 0x05; // RDRS + err = flashio(ddf->fd,ddf->link, cmd,1,&cmd[0],1); + if (err < 0 ) break; + if ((cmd[0] & 0x01) == 0 ) break; + } + if (err < 0 ) + break; + } + if (err < 0) + break; + + cmd[0] = 0x04; // WDIS + err = flashio(ddf->fd, ddf->link, cmd, 1, NULL, 0); + if (err < 0 ) + break; +#endif + } + if (err < 0 ) break; + + cmd[0] = 0x50; // EWSR + err = flashio(ddf->fd,ddf->link, cmd,1,NULL,0); + if (err < 0 ) break; + + cmd[0] = 0x01; // WRSR + cmd[1] = 0x1C; // BPx = 0, Lock all blocks + err = flashio(ddf->fd,ddf->link, cmd,2,NULL,0); + } while(0); + return err; +} + + +static int flashwrite(struct ddflash *ddf, int fs, uint32_t addr, uint32_t maxlen, uint32_t fw_off) +{ + switch (ddf->flash_type) { + case SSTI_SST25VF016B: + case SSTI_SST25VF032B: + return flashwrite_SSTI(ddf, fs, addr, maxlen, fw_off); + case SSTI_SST25VF064C: + return flashwrite_pagemode(ddf, fs, addr, 0x3c, fw_off); + case SPANSION_S25FL116K: + case SPANSION_S25FL132K: + case SPANSION_S25FL164K: + case WINBOND_W25Q16JV: + return flashwrite_pagemode(ddf, fs, addr, 0x1c, fw_off); + } + return -1; +} + + +static int flash_detect(struct ddflash *ddf) +{ + uint8_t cmd = 0x9F; + uint8_t id[3]; + + int r = flashio(ddf->fd, ddf->link, &cmd, 1, id, 3); + if (r < 0) + return r; + + if (id[0] == 0xBF && id[1] == 0x25 && id[2] == 0x41) { + ddf->flash_type = SSTI_SST25VF016B; + printf("Flash: SSTI SST25VF016B 16 MBit\n"); + ddf->sector_size = 4096; + ddf->size = 0x200000; + } else if (id[0] == 0xBF && id[1] == 0x25 && id[2] == 0x4A) { + ddf->flash_type = SSTI_SST25VF032B; + printf("Flash: SSTI SST25VF032B 32 MBit\n"); + ddf->sector_size = 4096; + ddf->size = 0x400000; + } else if (id[0] == 0xBF && id[1] == 0x25 && id[2] == 0x4B) { + ddf->flash_type = SSTI_SST25VF064C; + printf("Flash: SSTI SST25VF064C 64 MBit\n"); + ddf->sector_size = 4096; + ddf->size = 0x800000; + } else if (id[0] == 0x01 && id[1] == 0x40 && id[2] == 0x15) { + ddf->flash_type = SPANSION_S25FL116K; + printf("Flash: SPANSION S25FL116K 16 MBit\n"); + ddf->sector_size = 4096; + ddf->size = 0x200000; + } else if (id[0] == 0x01 && id[1] == 0x40 && id[2] == 0x16) { + ddf->flash_type = SPANSION_S25FL132K; + printf("Flash: SPANSION S25FL132K 32 MBit\n"); + ddf->sector_size = 4096; + ddf->size = 0x400000; + } else if (id[0] == 0x01 && id[1] == 0x40 && id[2] == 0x17) { + ddf->flash_type = SPANSION_S25FL164K; + printf("Flash: SPANSION S25FL164K 64 MBit\n"); + ddf->sector_size = 4096; + ddf->size = 0x800000; + } else if (id[0] == 0x1F && id[1] == 0x28) { + ddf->flash_type = ATMEL_AT45DB642D; + printf("Flash: Atmel AT45DB642D 64 MBit\n"); + ddf->sector_size = 1024; + ddf->size = 0x800000; + } else if (id[0] == 0xef && id[1] == 0x40 && id[2] == 0x15) { + ddf->flash_type = WINBOND_W25Q16JV; + printf("Flash: Winbond W25Q16JV 16 MBit\n"); + ddf->sector_size = 4096; + ddf->size = 0x200000; + } else { + printf("Unknown Flash Flash ID = %02x %02x %02x\n", id[0], id[1], id[2]); + return -1; + } + if (ddf->sector_size) { + ddf->buffer = malloc(ddf->sector_size); + //printf("allocated buffer %08x@%08x\n", ddf->sector_size, (uint32_t) ddf->buffer); + if (!ddf->buffer) + return -1; + } + return 0; +} + +static int get_id(struct ddflash *ddf) +{ + uint8_t id[4]; + struct ddb_reg ddbreg; + + if (ddf->link == 0) { + if (ioctl(ddf->fd, IOCTL_DDB_ID, &ddf->id) < 0) + return -1; + return 0; + } + ddbreg.reg = 8 + (ddf->link << 28); + if (ioctl(ddf->fd, IOCTL_DDB_READ_REG, &ddbreg) < 0) + return -1; + ddf->id.vendor = ddbreg.val; + ddf->id.device = ddbreg.val >> 16; + + ddbreg.reg = 12 + (ddf->link << 28); + if (ioctl(ddf->fd, IOCTL_DDB_READ_REG, &ddbreg) < 0) + return -1; + ddf->id.subvendor = ddbreg.val; + ddf->id.subdevice = ddbreg.val >> 16; + + ddbreg.reg = 0 + (ddf->link << 28); + if (ioctl(ddf->fd, IOCTL_DDB_READ_REG, &ddbreg) < 0) + return -1; + ddf->id.hw = ddbreg.val; + + ddbreg.reg = 4 + (ddf->link << 28); + if (ioctl(ddf->fd, IOCTL_DDB_READ_REG, &ddbreg) < 0) + return -1; + ddf->id.regmap = ddbreg.val; + return 0; +} + + +static char *devid2fname(uint16_t devid, char **name) +{ + char *fname = 0; + + switch (devid) { + case 0x0002: + fname="DVBBridgeV1A_DVBBridgeV1A.bit"; + *name = "Octopus 35\n"; + break; + case 0x0003: + fname="DVBBridgeV1B_DVBBridgeV1B.fpga"; + *name = "Octopus\n"; + break; + case 0x0005: + fname="DVBBridgeV2A_DD01_0005_STD.fpga"; + *name = "Octopus Classic\n"; + break; + case 0x0006: + fname="DVBBridgeV2A_DD01_0006_STD.fpga"; + *name = "CineS2 V7\n"; + break; + case 0x0007: + fname="DVBBridgeV2A_DD01_0007_MXL.fpga"; + *name = "Octopus 4/8\n"; + break; + case 0x0008: + fname="DVBBridgeV2A_DD01_0008_CXD.fpga"; + *name = "Octopus 4/8\n"; + break; + case 0x0009: + fname="DVBBridgeV2A_DD01_0009_SX8.fpga"; + *name = "Octopus MAXSX8\n"; + break; + case 0x000b: + fname="DVBBridgeV2A_DD01_000B_SX8.fpga"; + *name = "Octopus MAXSX8 Basic\n"; + break; + case 0x000a: + fname="DVBBridgeV2A_DD01_000A_M4.fpga"; + *name = "Octopus MAXM4\n"; + break; + case 0x0011: + fname="DVBBridgeV2B_DD01_0011.fpga"; + *name = "Octopus CI\n"; + break; + case 0x0012: + fname="DVBBridgeV2B_DD01_0012_STD.fpga"; + *name = "Octopus CI\n"; + break; + case 0x0013: + fname="DVBBridgeV2B_DD01_0013_PRO.fpga"; + *name = "Octopus PRO\n"; + break; + case 0x0020: + fname="DVBBridgeV2C_DD01_0020.fpga"; + *name = "Octopus GT Mini\n"; + break; + case 0x0201: + fname="DVBModulatorV1B_DVBModulatorV1B.bit"; + *name = "Modulator\n"; + break; + case 0x0203: + fname="DVBModulatorV1B_DD01_0203.fpga"; + *name = "Modulator Test\n"; + break; + case 0x0210: + fname="DVBModulatorV2A_DD01_0210.fpga"; + *name = "Modulator V2\n"; + break; + case 0x0220: + fname="SDRModulatorV1A_DD01_0220.fpga"; + *name = "SDRModulator ATV\n"; + break; + case 0x0221: + fname="SDRModulatorV1A_DD01_0221_IQ.fpga"; + *name = "SDRModulator IQ\n"; + break; + case 0x0222: + fname="SDRModulatorV1A_DD01_0222_DVBT.fpga"; + *name = "SDRModulator DVBT\n"; + break; + default: + *name = "UNKNOWN\n"; + break; + } + return fname; +} + + + +static int flashcmp(struct ddflash *ddf, int fs, uint32_t addr, uint32_t maxlen, uint32_t fw_off) +{ + off_t off; + uint32_t len; + int i, j, rlen; + uint8_t buf[256], buf2[256]; + int bl = sizeof(buf); + + off = lseek(fs, 0, SEEK_END); + if (off < 0) + return -1; + len = off - fw_off; + lseek(fs, fw_off, SEEK_SET); + if (len > maxlen) { + printf("file too big\n"); + return -1; + } + printf("flash file len %u, compare to %08x in flash\n", len, addr); + for (j = 0; j < len; j += bl, addr += bl) { + if (len - j < bl) + bl = len - j; + flashread(ddf->fd, buf, addr, bl); + rlen = read(fs, buf2, bl); + if (rlen < 0 || rlen != bl) { + printf("read error\n"); + return -1; + } + + if (memcmp(buf, buf2, bl)) { + printf("flash differs at %08x (offset %u)\n", addr, j); + dump(buf, 32); + dump(buf2, 32); + return addr; + } + } + printf("flash same as file\n"); + return -2; +} + +static int check_fw(struct ddflash *ddf, char *fn, uint32_t *fw_off) +{ + int fd, fsize, ret = 0; + off_t off; + uint32_t p, i; + uint8_t *buf; + uint8_t hdr[256]; + unsigned int devid, version, length; + unsigned int cid[8]; + int cids = 0; + uint32_t maxlen = 1024 * 1024; + + fd = open(fn, O_RDONLY); + if (fd < 0) { + printf("%s: not found\n", fn); + return -1; + } + off = lseek(fd, 0, SEEK_END); + if (off < 0) + return -1; + fsize = off; + if (fsize > maxlen) { + close(fd); + return -1; + } + lseek(fd, 0, SEEK_SET); + buf = malloc(fsize); + if (!buf) + return -1; + read(fd, buf, fsize); + close(fd); + + for (p = 0; p < fsize && buf[p]; p++) { + char *key = &buf[p], *val = NULL; + + for (; p < fsize && buf[p] != 0x0a; p++) { + if (buf[p] == ':') { + buf[p] = 0; + val = &buf[p + 1]; + } + } + if (val == NULL || p == fsize) + break; + buf[p] = 0; + //printf("%-20s:%s\n", key, val); + if (!strcasecmp(key, "Devid")) { + sscanf(val, "%x", &devid); + } else if (!strcasecmp(key, "Compat")) { + cids = sscanf(val, "%x,%x,%x,%x,%x,%x,%x,%x", + &cid[0], &cid[1], &cid[2], &cid[3], + &cid[4], &cid[5], &cid[6], &cid[7]); + if (cids < 1) + break; + for (i = 0; i < cids; i++) + if (cid[i] == ddf->id.device) + break; + if (i == cids) { + printf("%s: no compatible id found\n", fn); + ret = -2; /* no compatible ID */ + goto out; + } + } else if (!strcasecmp(key, "Version")) { + if (strchr(val,'.')) { + int major = 0, minor = 0; + sscanf(val,"%d.%d",&major,&minor); + version = (major << 16) + minor; + } else + sscanf(val, "%x", &version); + } else if (!strcasecmp(key, "Length")) { + sscanf(val, "%u", &length); + } + } + p++; + *fw_off = p; + printf("devid = %04x\n", devid); + printf("version = %08x %08x\n", version, ddf->id.hw); + printf("length = %u\n", length); + printf("fsize = %u, p = %u, f-p = %u\n", fsize, p, fsize - p); + if (devid == ddf->id.device) { + if (version <= (ddf->id.hw & 0xffffff)) { + printf("%s: older or same version\n", fn); + ret = -3; /* same id but no newer version */ + } + } else + ret = 1; + +out: + free(buf); + printf("check_fw = %d\n", ret); + return ret; + +} + +static int update_image(struct ddflash *ddf, char *fn, + uint32_t adr, uint32_t len, + int has_header, int no_change) +{ + int fs, res = 0; + uint32_t fw_off = 0; + + printf("Check %s\n", fn); + if (has_header) { + int ck; + + ck = check_fw(ddf, fn, &fw_off); + if (ck < 0) + return ck; + if (ck == 1 && no_change) + return 0; + } + fs = open(fn, O_RDONLY); + if (fs < 0 ) { + printf("File %s not found \n", fn); + return -1; + } + res = flashcmp(ddf, fs, adr, len, fw_off); + if (res == -2) { + printf("%s: same as flash\n", fn); + } + if (res < 0) + goto out; + res = flashwrite(ddf, fs, adr, len, fw_off); + if (res == 0) { + res = flashcmp(ddf, fs, adr, len, fw_off); + if (res == -2) { + res = 1; + } + } + +out: + close(fs); + return res; +} + + +static int fexists(char *fn) +{ + struct stat b; + + return (!stat(fn, &b)); +} + diff --git a/apps/octonet/flash.h b/apps/octonet/flash.h index 3b8c4c2..60c5235 100644 --- a/apps/octonet/flash.h +++ b/apps/octonet/flash.h @@ -62,4 +62,33 @@ struct ddb_i2c_msg { #define IOCTL_DDB_READ_I2C _IOWR(DDB_MAGIC, 0x0a, struct ddb_i2c_msg) #define IOCTL_DDB_WRITE_I2C _IOR(DDB_MAGIC, 0x0b, struct ddb_i2c_msg) -#include "flash.c" +enum { + UNKNOWN_FLASH = 0, + ATMEL_AT45DB642D = 1, + SSTI_SST25VF016B = 2, + SSTI_SST25VF032B = 3, + SSTI_SST25VF064C = 4, + SPANSION_S25FL116K = 5, + SPANSION_S25FL132K = 6, + SPANSION_S25FL164K = 7, + WINBOND_W25Q16JV = 8, +}; + +struct ddflash { + int fd; + uint32_t link; + char *fname; + + struct ddb_id id; + uint32_t version; + + uint32_t flash_type; + uint32_t sector_size; + uint32_t size; + + uint32_t bufsize; + uint32_t block_erase; + + uint8_t *buffer; +}; +