No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ddflash.c 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747
  1. /*
  2. /* ddflash - Programmer for flash on Digital Devices devices
  3. *
  4. * Copyright (C) 2013 Digital Devices GmbH
  5. * Ralph Metzler <rmetzler@digitaldevices.de>
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * version 3 only, as published by the Free Software Foundation.
  10. *
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  21. * 02110-1301, USA
  22. * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
  23. */
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <stdint.h>
  27. #include <unistd.h>
  28. #include <getopt.h>
  29. #include <errno.h>
  30. #include <sys/types.h>
  31. #include <sys/stat.h>
  32. #include <fcntl.h>
  33. #include <string.h>
  34. #include <sys/ioctl.h>
  35. #include <linux/types.h>
  36. #include "flash.h"
  37. static int reboot(uint32_t off)
  38. {
  39. FILE *f;
  40. uint32_t time;
  41. if ((f = fopen ("/sys/class/rtc/rtc0/since_epoch", "r")) == NULL)
  42. return -1;
  43. fscanf(f, "%u", &time);
  44. fclose(f);
  45. if ((f = fopen ("/sys/class/rtc/rtc0/wakealarm", "r+")) == NULL)
  46. return -1;
  47. fprintf(f, "%u", time + off);
  48. fclose(f);
  49. system("/sbin/poweroff");
  50. return 0;
  51. }
  52. struct ddflash {
  53. int fd;
  54. struct ddb_id id;
  55. uint32_t version;
  56. uint32_t flash_type;
  57. uint32_t sector_size;
  58. uint32_t size;
  59. uint32_t bufsize;
  60. uint32_t block_erase;
  61. uint8_t *buffer;
  62. };
  63. int flashwrite_pagemode(struct ddflash *ddf, int dev, uint32_t FlashOffset,
  64. uint8_t LockBits, uint32_t fw_off)
  65. {
  66. int err = 0;
  67. uint8_t cmd[260];
  68. int i, j;
  69. uint32_t flen, blen;
  70. blen = flen = lseek(dev, 0, SEEK_END) - fw_off;
  71. if (blen % 0xff)
  72. blen = (blen + 0xff) & 0xffffff00;
  73. printf("blen = %u, flen = %u\n", blen, flen);
  74. do {
  75. cmd[0] = 0x50; // EWSR
  76. err = flashio(ddf->fd, cmd, 1, NULL, 0);
  77. if (err < 0)
  78. break;
  79. cmd[0] = 0x01; // WRSR
  80. cmd[1] = 0x00; // BPx = 0, Unlock all blocks
  81. err = flashio(ddf->fd, cmd, 2, NULL, 0);
  82. if (err < 0)
  83. break;
  84. for (i = 0; i < flen; i += 4096) {
  85. if ((i & 0xFFFF) == 0)
  86. printf(" Erase %08x\n", FlashOffset + i);
  87. cmd[0] = 0x06; // WREN
  88. err = flashio(ddf->fd, cmd, 1, NULL, 0);
  89. if (err < 0)
  90. break;
  91. cmd[0] = 0x20; // Sector erase ( 4Kb)
  92. cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
  93. cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
  94. cmd[3] = 0x00;
  95. err = flashio(ddf->fd, cmd, 4, NULL, 0);
  96. if (err < 0)
  97. break;
  98. while (1) {
  99. cmd[0] = 0x05; // RDRS
  100. err = flashio(ddf->fd, cmd, 1, &cmd[0], 1);
  101. if (err < 0)
  102. break;
  103. if ((cmd[0] & 0x01) == 0)
  104. break;
  105. }
  106. if (err < 0)
  107. break;
  108. }
  109. if (err < 0)
  110. break;
  111. for (j = blen - 256; j >= 0; j -= 256 ) {
  112. uint32_t len = 256;
  113. ssize_t rlen;
  114. if (lseek(dev, j + fw_off, SEEK_SET) < 0) {
  115. printf("seek error\n");
  116. return -1;
  117. }
  118. if (flen - j < 256) {
  119. len = flen - j;
  120. memset(ddf->buffer, 0xff, 256);
  121. }
  122. rlen = read(dev, ddf->buffer, len);
  123. if (rlen < 0 || rlen != len) {
  124. printf("file read error %d,%d at %u\n", rlen, errno, j);
  125. return -1;
  126. }
  127. printf ("write %u bytes at %08x\n", len, j);
  128. if ((j & 0xFFFF) == 0)
  129. printf(" Programm %08x\n", FlashOffset + j);
  130. cmd[0] = 0x06; // WREN
  131. err = flashio(ddf->fd, cmd, 1, NULL, 0);
  132. if (err < 0)
  133. break;
  134. cmd[0] = 0x02; // PP
  135. cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF );
  136. cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF );
  137. cmd[3] = 0x00;
  138. memcpy(&cmd[4], ddf->buffer, 256);
  139. err = flashio(ddf->fd, cmd, 260, NULL, 0);
  140. if (err < 0)
  141. break;
  142. while(1) {
  143. cmd[0] = 0x05; // RDRS
  144. err = flashio(ddf->fd, cmd,1, &cmd[0], 1);
  145. if (err < 0)
  146. break;
  147. if ((cmd[0] & 0x01) == 0)
  148. break;
  149. }
  150. if (err < 0)
  151. break;
  152. }
  153. if (err < 0)
  154. break;
  155. cmd[0] = 0x50; // EWSR
  156. err = flashio(ddf->fd, cmd, 1, NULL, 0);
  157. if (err < 0)
  158. break;
  159. cmd[0] = 0x01; // WRSR
  160. cmd[1] = LockBits; // BPx = 0, Lock all blocks
  161. err = flashio(ddf->fd, cmd, 2, NULL, 0);
  162. } while(0);
  163. return err;
  164. }
  165. static int flashwrite_SSTI(struct ddflash *ddf, int fs, uint32_t FlashOffset, uint32_t maxlen, uint32_t fw_off)
  166. {
  167. int err = 0;
  168. uint8_t cmd[6];
  169. int i, j;
  170. uint32_t flen, blen;
  171. blen = flen = lseek(fs, 0, SEEK_END) - fw_off;
  172. if (blen % 0xfff)
  173. blen = (blen + 0xfff) & 0xfffff000;
  174. printf("blen = %u, flen = %u\n", blen, flen);
  175. do {
  176. #if 1
  177. cmd[0] = 0x50; // EWSR
  178. err = flashio(ddf->fd, cmd, 1, NULL, 0);
  179. if (err < 0)
  180. break;
  181. cmd[0] = 0x01; // WRSR
  182. cmd[1] = 0x00; // BPx = 0, Unlock all blocks
  183. err = flashio(ddf->fd, cmd, 2, NULL, 0);
  184. if (err < 0 )
  185. break;
  186. for (i = 0; i < flen; i += 4096) {
  187. if ((i & 0xFFFF) == 0 )
  188. printf("Erase %08x\n", FlashOffset + i);
  189. cmd[0] = 0x06; // WREN
  190. err = flashio(ddf->fd, cmd, 1, NULL, 0);
  191. if (err < 0 )
  192. break;
  193. cmd[0] = 0x20; // Sector erase ( 4Kb)
  194. cmd[1] = (((FlashOffset + i ) >> 16) & 0xFF);
  195. cmd[2] = (((FlashOffset + i ) >> 8) & 0xFF);
  196. cmd[3] = 0x00;
  197. err = flashio(ddf->fd,cmd,4,NULL,0);
  198. if (err < 0 )
  199. break;
  200. while(1) {
  201. cmd[0] = 0x05; // RDRS
  202. err = flashio(ddf->fd,cmd,1,&cmd[0],1);
  203. if (err < 0 ) break;
  204. if ((cmd[0] & 0x01) == 0 ) break;
  205. }
  206. if (err < 0 ) break;
  207. }
  208. if (err < 0 )
  209. break;
  210. #endif
  211. for (j = blen - 4096; j >= 0; j -= 4096 ) {
  212. uint32_t len = 4096;
  213. ssize_t rlen;
  214. if (lseek(fs, j + fw_off, SEEK_SET) < 0) {
  215. printf("seek error\n");
  216. return -1;
  217. }
  218. if (flen - j < 4096) {
  219. len = flen - j;
  220. memset(ddf->buffer, 0xff, 4096);
  221. }
  222. rlen = read(fs, ddf->buffer, len);
  223. if (rlen < 0 || rlen != len) {
  224. printf("file read error %d,%d at %u\n", rlen, errno, j);
  225. return -1;
  226. }
  227. printf ("write %u bytes at %08x\n", len, j);
  228. if ((j & 0xFFFF) == 0 )
  229. printf(" Program %08x\n",FlashOffset + j);
  230. #if 1
  231. for (i = 0; i < 4096; i += 2) {
  232. if (i == 0) {
  233. cmd[0] = 0x06; // WREN
  234. err = flashio(ddf->fd, cmd, 1, NULL, 0);
  235. if (err < 0 )
  236. break;
  237. cmd[0] = 0xAD; // AAI
  238. cmd[1] = ((( FlashOffset + j ) >> 16) & 0xFF );
  239. cmd[2] = ((( FlashOffset + j ) >> 8) & 0xFF );
  240. cmd[3] = 0x00;
  241. cmd[4] = ddf->buffer[i];
  242. cmd[5] = ddf->buffer[i + 1];
  243. err = flashio(ddf->fd,cmd,6,NULL,0);
  244. } else {
  245. cmd[0] = 0xAD; // AAI
  246. cmd[1] = ddf->buffer[i];
  247. cmd[2] = ddf->buffer[i + 1];
  248. err = flashio(ddf->fd,cmd,3,NULL,0);
  249. }
  250. if (err < 0 )
  251. break;
  252. while(1) {
  253. cmd[0] = 0x05; // RDRS
  254. err = flashio(ddf->fd,cmd,1,&cmd[0],1);
  255. if (err < 0 ) break;
  256. if ((cmd[0] & 0x01) == 0 ) break;
  257. }
  258. if (err < 0 )
  259. break;
  260. }
  261. if (err < 0)
  262. break;
  263. cmd[0] = 0x04; // WDIS
  264. err = flashio(ddf->fd, cmd, 1, NULL, 0);
  265. if (err < 0 )
  266. break;
  267. #endif
  268. }
  269. if (err < 0 ) break;
  270. cmd[0] = 0x50; // EWSR
  271. err = flashio(ddf->fd,cmd,1,NULL,0);
  272. if (err < 0 ) break;
  273. cmd[0] = 0x01; // WRSR
  274. cmd[1] = 0x1C; // BPx = 0, Lock all blocks
  275. err = flashio(ddf->fd,cmd,2,NULL,0);
  276. } while(0);
  277. return err;
  278. }
  279. static int flashwrite(struct ddflash *ddf, int fs, uint32_t addr, uint32_t maxlen, uint32_t fw_off)
  280. {
  281. switch (ddf->flash_type) {
  282. case SSTI_SST25VF016B:
  283. case SSTI_SST25VF032B:
  284. return flashwrite_SSTI(ddf, fs, addr, maxlen, fw_off);
  285. case SSTI_SST25VF064C:
  286. return flashwrite_pagemode(ddf, fs, addr, 0x3c, fw_off);
  287. case SPANSION_S25FL116K:
  288. case SPANSION_S25FL132K:
  289. case SPANSION_S25FL164K:
  290. return flashwrite_pagemode(ddf, fs, addr, 0x1c, fw_off);
  291. }
  292. return -1;
  293. }
  294. static int flashcmp(struct ddflash *ddf, int fs, uint32_t addr, uint32_t maxlen, uint32_t fw_off)
  295. {
  296. off_t off;
  297. uint32_t len;
  298. int i, j, rlen;
  299. uint8_t buf[256], buf2[256];
  300. int bl = sizeof(buf);
  301. off = lseek(fs, 0, SEEK_END);
  302. if (off < 0)
  303. return -1;
  304. len = off - fw_off;
  305. lseek(fs, fw_off, SEEK_SET);
  306. if (len > maxlen) {
  307. printf("file too big\n");
  308. return -1;
  309. }
  310. printf("flash file len %u, compare to %08x in flash\n", len, addr);
  311. for (j = 0; j < len; j += bl, addr += bl) {
  312. if (len - j < bl)
  313. bl = len - j;
  314. flashread(ddf->fd, buf, addr, bl);
  315. rlen = read(fs, buf2, bl);
  316. if (rlen < 0 || rlen != bl) {
  317. printf("read error\n");
  318. return -1;
  319. }
  320. if (memcmp(buf, buf2, bl)) {
  321. printf("flash differs at %08x (offset %u)\n", addr, j);
  322. dump(buf, 32);
  323. dump(buf2, 32);
  324. return addr;
  325. }
  326. }
  327. printf("flash same as file\n");
  328. return -2;
  329. }
  330. static int flash_detect(struct ddflash *ddf)
  331. {
  332. uint8_t cmd = 0x9F;
  333. uint8_t id[3];
  334. int r = flashio(ddf->fd, &cmd, 1, id, 3);
  335. if (r < 0)
  336. return r;
  337. if (id[0] == 0xBF && id[1] == 0x25 && id[2] == 0x41) {
  338. ddf->flash_type = SSTI_SST25VF016B;
  339. printf("Flash: SSTI SST25VF016B 16 MBit\n");
  340. ddf->sector_size = 4096;
  341. ddf->size = 0x200000;
  342. } else if (id[0] == 0xBF && id[1] == 0x25 && id[2] == 0x4A) {
  343. ddf->flash_type = SSTI_SST25VF032B;
  344. printf("Flash: SSTI SST25VF032B 32 MBit\n");
  345. ddf->sector_size = 4096;
  346. ddf->size = 0x400000;
  347. } else if (id[0] == 0xBF && id[1] == 0x25 && id[2] == 0x4B) {
  348. ddf->flash_type = SSTI_SST25VF064C;
  349. printf("Flash: SSTI SST25VF064C 64 MBit\n");
  350. ddf->sector_size = 4096;
  351. ddf->size = 0x800000;
  352. } else if (id[0] == 0x01 && id[1] == 0x40 && id[2] == 0x15) {
  353. ddf->flash_type = SPANSION_S25FL116K;
  354. printf("Flash: SPANSION S25FL116K 16 MBit\n");
  355. ddf->sector_size = 4096;
  356. ddf->size = 0x200000;
  357. } else if (id[0] == 0x01 && id[1] == 0x40 && id[2] == 0x16) {
  358. ddf->flash_type = SPANSION_S25FL132K;
  359. printf("Flash: SPANSION S25FL132K 32 MBit\n");
  360. ddf->sector_size = 4096;
  361. ddf->size = 0x400000;
  362. } else if (id[0] == 0x01 && id[1] == 0x40 && id[2] == 0x17) {
  363. ddf->flash_type = SPANSION_S25FL164K;
  364. printf("Flash: SPANSION S25FL164K 64 MBit\n");
  365. ddf->sector_size = 4096;
  366. ddf->size = 0x800000;
  367. } else if (id[0] == 0x1F && id[1] == 0x28) {
  368. ddf->flash_type = ATMEL_AT45DB642D;
  369. printf("Flash: Atmel AT45DB642D 64 MBit\n");
  370. ddf->sector_size = 1024;
  371. ddf->size = 0x800000;
  372. } else {
  373. printf("Unknown Flash Flash ID = %02x %02x %02x\n", id[0], id[1], id[2]);
  374. return -1;
  375. }
  376. if (ddf->sector_size) {
  377. ddf->buffer = malloc(ddf->sector_size);
  378. //printf("allocated buffer %08x@%08x\n", ddf->sector_size, (uint32_t) ddf->buffer);
  379. if (!ddf->buffer)
  380. return -1;
  381. }
  382. return 0;
  383. }
  384. static int get_id(struct ddflash *ddf) {
  385. uint8_t id[4];
  386. if (ioctl(ddf->fd, IOCTL_DDB_ID, &ddf->id) < 0)
  387. return -1;
  388. #if 1
  389. printf("%04x %04x %04x %04x %08x %08x\n",
  390. ddf->id.vendor, ddf->id.device,
  391. ddf->id.subvendor, ddf->id.subdevice,
  392. ddf->id.hw, ddf->id.regmap);
  393. #endif
  394. return 0;
  395. }
  396. static int check_fw(struct ddflash *ddf, char *fn, uint32_t *fw_off)
  397. {
  398. int fd, fsize, ret = 0;
  399. off_t off;
  400. uint32_t p, i;
  401. uint8_t *buf;
  402. uint8_t hdr[256];
  403. unsigned int devid, version, length;
  404. unsigned int cid[8];
  405. int cids = 0;
  406. uint32_t maxlen = 1024 * 1024;
  407. fd = open(fn, O_RDONLY);
  408. if (fd < 0) {
  409. printf("%s: not found\n", fn);
  410. return -1;
  411. }
  412. off = lseek(fd, 0, SEEK_END);
  413. if (off < 0)
  414. return -1;
  415. fsize = off;
  416. if (fsize > maxlen) {
  417. close(fd);
  418. return -1;
  419. }
  420. lseek(fd, 0, SEEK_SET);
  421. buf = malloc(fsize);
  422. if (!buf)
  423. return -1;
  424. read(fd, buf, fsize);
  425. close(fd);
  426. for (p = 0; p < fsize && buf[p]; p++) {
  427. char *key = &buf[p], *val = NULL;
  428. for (; p < fsize && buf[p] != 0x0a; p++) {
  429. if (buf[p] == ':') {
  430. buf[p] = 0;
  431. val = &buf[p + 1];
  432. }
  433. }
  434. if (val == NULL || p == fsize)
  435. break;
  436. buf[p] = 0;
  437. //printf("%-20s:%s\n", key, val);
  438. if (!strcasecmp(key, "Devid")) {
  439. sscanf(val, "%x", &devid);
  440. } else if (!strcasecmp(key, "Compat")) {
  441. cids = sscanf(val, "%x,%x,%x,%x,%x,%x,%x,%x",
  442. &cid[0], &cid[1], &cid[2], &cid[3],
  443. &cid[4], &cid[5], &cid[6], &cid[7]);
  444. if (cids < 1)
  445. break;
  446. for (i = 0; i < cids; i++)
  447. if (cid[i] == ddf->id.device)
  448. break;
  449. if (i == cids) {
  450. printf("%s: no compatible id\n", fn);
  451. ret = -2; /* no compatible ID */
  452. goto out;
  453. }
  454. } else if (!strcasecmp(key, "Version")) {
  455. if (strchr(val,'.')) {
  456. int major = 0, minor = 0;
  457. sscanf(val,"%d.%d",&major,&minor);
  458. version = (major << 16) + minor;
  459. } else
  460. sscanf(val, "%x", &version);
  461. } else if (!strcasecmp(key, "Length")) {
  462. sscanf(val, "%u", &length);
  463. }
  464. }
  465. p++;
  466. *fw_off = p;
  467. printf("devid = %04x\n", devid);
  468. printf("version = %08x %08x\n", version, ddf->id.hw);
  469. printf("length = %u\n", length);
  470. printf("fsize = %u, p = %u, f-p = %u\n", fsize, p, fsize - p);
  471. if (devid == ddf->id.device) {
  472. if (version <= (ddf->id.hw & 0xffffff)) {
  473. printf("%s: old version\n", fn);
  474. ret = -3; /* same id but no newer version */
  475. }
  476. } else
  477. ret = 1;
  478. out:
  479. free(buf);
  480. printf("check_fw = %d\n", ret);
  481. return ret;
  482. }
  483. static int update_image(struct ddflash *ddf, char *fn,
  484. uint32_t adr, uint32_t len,
  485. int has_header, int no_change)
  486. {
  487. int fs, res = 0;
  488. uint32_t fw_off = 0;
  489. printf("Check %s\n", fn);
  490. if (has_header) {
  491. int ck;
  492. ck = check_fw(ddf, fn, &fw_off);
  493. if (ck < 0)
  494. return ck;
  495. if (ck == 1 && no_change)
  496. return 0;
  497. }
  498. fs = open(fn, O_RDONLY);
  499. if (fs < 0 ) {
  500. printf("File %s not found \n", fn);
  501. return -1;
  502. }
  503. res = flashcmp(ddf, fs, adr, len, fw_off);
  504. if (res == -2) {
  505. printf("%s: same as flash\n", fn);
  506. }
  507. if (res < 0)
  508. goto out;
  509. res = flashwrite(ddf, fs, adr, len, fw_off);
  510. if (res == 0) {
  511. res = flashcmp(ddf, fs, adr, len, fw_off);
  512. if (res == -2) {
  513. res = 1;
  514. }
  515. }
  516. out:
  517. close(fs);
  518. return res;
  519. }
  520. static int fexists(char *fn)
  521. {
  522. struct stat b;
  523. return (!stat(fn, &b));
  524. }
  525. static int update_flash(struct ddflash *ddf)
  526. {
  527. char *fname;
  528. int res, stat = 0;
  529. switch (ddf->id.device) {
  530. case 0x300:
  531. case 0x301:
  532. case 0x302:
  533. case 0x307:
  534. if ((res = update_image(ddf, "/boot/bs.img", 0x4000, 0x1000, 0, 0)) == 1)
  535. stat |= 4;
  536. if ((res = update_image(ddf, "/boot/uboot.img", 0xb0000, 0xb0000, 0, 0)) == 1)
  537. stat |= 2;
  538. if (fexists("/config/gtl.enabled")) {
  539. if ((res = update_image(ddf, "/config/fpga_gtl.img", 0x10000, 0xa0000, 1, 0)) == 1)
  540. stat |= 1;
  541. if (res == -1)
  542. if ((res = update_image(ddf, "/boot/fpga_gtl.img", 0x10000, 0xa0000, 1, 0)) == 1)
  543. stat |= 1;
  544. } else if (fexists("/config/gtl.disabled")) {
  545. if ((res = update_image(ddf, "/config/fpga.img", 0x10000, 0xa0000, 1, 0)) == 1)
  546. stat |= 1;
  547. if (res == -1)
  548. if ((res = update_image(ddf, "/boot/fpga.img", 0x10000, 0xa0000, 1, 0)) == 1)
  549. stat |= 1;
  550. } else {
  551. if (ddf->id.device == 0x0307) {
  552. if (res == -1)
  553. if ((res = update_image(ddf, "/config/fpga_gtl.img", 0x10000, 0xa0000, 1, 1)) == 1)
  554. stat |= 1;
  555. if (res == -1)
  556. if ((res = update_image(ddf, "/boot/fpga_gtl.img", 0x10000, 0xa0000, 1, 1)) == 1)
  557. stat |= 1;
  558. } else {
  559. if ((res = update_image(ddf, "/config/fpga.img", 0x10000, 0xa0000, 1, 1)) == 1)
  560. stat |= 1;
  561. if (res == -1)
  562. if ((res = update_image(ddf, "/boot/fpga.img", 0x10000, 0xa0000, 1, 1)) == 1)
  563. stat |= 1;
  564. }
  565. }
  566. #if 1
  567. if ( (stat&1) && (ddf->id.hw & 0xffffff) <= 0x010001) {
  568. if (ddf->id.device == 0x0307) {
  569. if ((res = update_image(ddf, "/config/fpga_gtl.img", 0x160000, 0x80000, 1, 0)) == 1)
  570. stat |= 1;
  571. if (res == -1)
  572. if ((res = update_image(ddf, "/boot/fpga_gtl.img", 0x160000, 0x80000, 1, 0)) == 1)
  573. stat |= 1;
  574. } else {
  575. if ((res = update_image(ddf, "/config/fpga.img", 0x160000, 0x80000, 1, 0)) == 1)
  576. stat |= 1;
  577. if (res == -1)
  578. if ((res = update_image(ddf, "/boot/fpga.img", 0x160000, 0x80000, 1, 0)) == 1)
  579. stat |= 1;
  580. }
  581. }
  582. #endif
  583. break;
  584. case 0x320:
  585. //fname="/boot/DVBNetV1A_DD01_0300.bit";
  586. fname="/boot/fpga.img";
  587. if ((res = update_image(ddf, fname, 0x10000, 0x100000, 1, 0)) == 1)
  588. stat |= 1;
  589. return stat;
  590. break;
  591. case 0x322:
  592. //fname="/boot/DVBNetV1A_DD01_0300.bit";
  593. fname="/boot/fpga.img";
  594. if ((res = update_image(ddf, fname, 0x10000, 0x100000, 1, 0)) == 1)
  595. stat |= 1;
  596. return stat;
  597. break;
  598. default:
  599. return 0;
  600. }
  601. return stat;
  602. }
  603. int main(int argc, char **argv)
  604. {
  605. struct ddflash ddf;
  606. char ddbname[80];
  607. uint8_t *buffer = 0;
  608. uint32_t FlashOffset = 0x10000;
  609. int i, err, res;
  610. int ddbnum = 0;
  611. uint32_t svid, jump, flash;
  612. memset(&ddf, 0, sizeof(ddf));
  613. while (1) {
  614. int option_index = 0;
  615. int c;
  616. static struct option long_options[] = {
  617. {"svid", required_argument, NULL, 's'},
  618. {"help", no_argument , NULL, 'h'},
  619. {0, 0, 0, 0}
  620. };
  621. c = getopt_long(argc, argv,
  622. "d:n:s:o:l:dfhj",
  623. long_options, &option_index);
  624. if (c==-1)
  625. break;
  626. switch (c) {
  627. case 's':
  628. svid = strtoul(optarg, NULL, 16);
  629. break;
  630. case 'o':
  631. FlashOffset = strtoul(optarg, NULL, 16);
  632. break;
  633. case 'n':
  634. ddbnum = strtol(optarg, NULL, 0);
  635. break;
  636. case 'j':
  637. jump = 1;
  638. break;
  639. case 'h':
  640. default:
  641. break;
  642. }
  643. }
  644. if (optind < argc) {
  645. printf("Warning: unused arguments\n");
  646. }
  647. sprintf(ddbname, "/dev/ddbridge/card%d", ddbnum);
  648. while ((ddf.fd = open(ddbname, O_RDWR)) < 0) {
  649. if (errno == EBUSY)
  650. usleep(100000);
  651. else {
  652. printf("Could not open device\n");
  653. return -1;
  654. }
  655. }
  656. flash = flash_detect(&ddf);
  657. if (flash < 0)
  658. return -1;
  659. get_id(&ddf);
  660. res = update_flash(&ddf);
  661. if (ddf.buffer)
  662. free(ddf.buffer);
  663. if (res < 0)
  664. return res;
  665. if (res & 1)
  666. reboot(40);
  667. return res;
  668. }