spartan3.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660
  1. /*
  2. * (C) Copyright 2002
  3. * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  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., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. *
  23. */
  24. /*
  25. * Configuration support for Xilinx Spartan3 devices. Based
  26. * on spartan2.c (Rich Ireland, rireland@enterasys.com).
  27. */
  28. #include <common.h> /* core U-Boot definitions */
  29. #include <spartan3.h> /* Spartan-II device family */
  30. /* Define FPGA_DEBUG to get debug printf's */
  31. #ifdef FPGA_DEBUG
  32. #define PRINTF(fmt,args...) printf (fmt ,##args)
  33. #else
  34. #define PRINTF(fmt,args...)
  35. #endif
  36. #undef CONFIG_SYS_FPGA_CHECK_BUSY
  37. #undef CONFIG_SYS_FPGA_PROG_FEEDBACK
  38. /* Note: The assumption is that we cannot possibly run fast enough to
  39. * overrun the device (the Slave Parallel mode can free run at 50MHz).
  40. * If there is a need to operate slower, define CONFIG_FPGA_DELAY in
  41. * the board config file to slow things down.
  42. */
  43. #ifndef CONFIG_FPGA_DELAY
  44. #define CONFIG_FPGA_DELAY()
  45. #endif
  46. #ifndef CONFIG_SYS_FPGA_WAIT
  47. #define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/100 /* 10 ms */
  48. #endif
  49. static int Spartan3_sp_load( Xilinx_desc *desc, void *buf, size_t bsize );
  50. static int Spartan3_sp_dump( Xilinx_desc *desc, void *buf, size_t bsize );
  51. /* static int Spartan3_sp_info( Xilinx_desc *desc ); */
  52. static int Spartan3_sp_reloc( Xilinx_desc *desc, ulong reloc_offset );
  53. static int Spartan3_ss_load( Xilinx_desc *desc, void *buf, size_t bsize );
  54. static int Spartan3_ss_dump( Xilinx_desc *desc, void *buf, size_t bsize );
  55. /* static int Spartan3_ss_info( Xilinx_desc *desc ); */
  56. static int Spartan3_ss_reloc( Xilinx_desc *desc, ulong reloc_offset );
  57. /* ------------------------------------------------------------------------- */
  58. /* Spartan-II Generic Implementation */
  59. int Spartan3_load (Xilinx_desc * desc, void *buf, size_t bsize)
  60. {
  61. int ret_val = FPGA_FAIL;
  62. switch (desc->iface) {
  63. case slave_serial:
  64. PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__);
  65. ret_val = Spartan3_ss_load (desc, buf, bsize);
  66. break;
  67. case slave_parallel:
  68. PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__);
  69. ret_val = Spartan3_sp_load (desc, buf, bsize);
  70. break;
  71. default:
  72. printf ("%s: Unsupported interface type, %d\n",
  73. __FUNCTION__, desc->iface);
  74. }
  75. return ret_val;
  76. }
  77. int Spartan3_dump (Xilinx_desc * desc, void *buf, size_t bsize)
  78. {
  79. int ret_val = FPGA_FAIL;
  80. switch (desc->iface) {
  81. case slave_serial:
  82. PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__);
  83. ret_val = Spartan3_ss_dump (desc, buf, bsize);
  84. break;
  85. case slave_parallel:
  86. PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__);
  87. ret_val = Spartan3_sp_dump (desc, buf, bsize);
  88. break;
  89. default:
  90. printf ("%s: Unsupported interface type, %d\n",
  91. __FUNCTION__, desc->iface);
  92. }
  93. return ret_val;
  94. }
  95. int Spartan3_info( Xilinx_desc *desc )
  96. {
  97. return FPGA_SUCCESS;
  98. }
  99. int Spartan3_reloc (Xilinx_desc * desc, ulong reloc_offset)
  100. {
  101. int ret_val = FPGA_FAIL; /* assume a failure */
  102. if (desc->family != Xilinx_Spartan3) {
  103. printf ("%s: Unsupported family type, %d\n",
  104. __FUNCTION__, desc->family);
  105. return FPGA_FAIL;
  106. } else
  107. switch (desc->iface) {
  108. case slave_serial:
  109. ret_val = Spartan3_ss_reloc (desc, reloc_offset);
  110. break;
  111. case slave_parallel:
  112. ret_val = Spartan3_sp_reloc (desc, reloc_offset);
  113. break;
  114. default:
  115. printf ("%s: Unsupported interface type, %d\n",
  116. __FUNCTION__, desc->iface);
  117. }
  118. return ret_val;
  119. }
  120. /* ------------------------------------------------------------------------- */
  121. /* Spartan-II Slave Parallel Generic Implementation */
  122. static int Spartan3_sp_load (Xilinx_desc * desc, void *buf, size_t bsize)
  123. {
  124. int ret_val = FPGA_FAIL; /* assume the worst */
  125. Xilinx_Spartan3_Slave_Parallel_fns *fn = desc->iface_fns;
  126. PRINTF ("%s: start with interface functions @ 0x%p\n",
  127. __FUNCTION__, fn);
  128. if (fn) {
  129. size_t bytecount = 0;
  130. unsigned char *data = (unsigned char *) buf;
  131. int cookie = desc->cookie; /* make a local copy */
  132. unsigned long ts; /* timestamp */
  133. PRINTF ("%s: Function Table:\n"
  134. "ptr:\t0x%p\n"
  135. "struct: 0x%p\n"
  136. "pre: 0x%p\n"
  137. "pgm:\t0x%p\n"
  138. "init:\t0x%p\n"
  139. "err:\t0x%p\n"
  140. "clk:\t0x%p\n"
  141. "cs:\t0x%p\n"
  142. "wr:\t0x%p\n"
  143. "read data:\t0x%p\n"
  144. "write data:\t0x%p\n"
  145. "busy:\t0x%p\n"
  146. "abort:\t0x%p\n",
  147. "post:\t0x%p\n\n",
  148. __FUNCTION__, &fn, fn, fn->pre, fn->pgm, fn->init, fn->err,
  149. fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, fn->busy,
  150. fn->abort, fn->post);
  151. /*
  152. * This code is designed to emulate the "Express Style"
  153. * Continuous Data Loading in Slave Parallel Mode for
  154. * the Spartan-II Family.
  155. */
  156. #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
  157. printf ("Loading FPGA Device %d...\n", cookie);
  158. #endif
  159. /*
  160. * Run the pre configuration function if there is one.
  161. */
  162. if (*fn->pre) {
  163. (*fn->pre) (cookie);
  164. }
  165. /* Establish the initial state */
  166. (*fn->pgm) (TRUE, TRUE, cookie); /* Assert the program, commit */
  167. /* Get ready for the burn */
  168. CONFIG_FPGA_DELAY ();
  169. (*fn->pgm) (FALSE, TRUE, cookie); /* Deassert the program, commit */
  170. ts = get_timer (0); /* get current time */
  171. /* Now wait for INIT and BUSY to go high */
  172. do {
  173. CONFIG_FPGA_DELAY ();
  174. if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
  175. puts ("** Timeout waiting for INIT to clear.\n");
  176. (*fn->abort) (cookie); /* abort the burn */
  177. return FPGA_FAIL;
  178. }
  179. } while ((*fn->init) (cookie) && (*fn->busy) (cookie));
  180. (*fn->wr) (TRUE, TRUE, cookie); /* Assert write, commit */
  181. (*fn->cs) (TRUE, TRUE, cookie); /* Assert chip select, commit */
  182. (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */
  183. /* Load the data */
  184. while (bytecount < bsize) {
  185. /* XXX - do we check for an Ctrl-C press in here ??? */
  186. /* XXX - Check the error bit? */
  187. (*fn->wdata) (data[bytecount++], TRUE, cookie); /* write the data */
  188. CONFIG_FPGA_DELAY ();
  189. (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */
  190. CONFIG_FPGA_DELAY ();
  191. (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */
  192. #ifdef CONFIG_SYS_FPGA_CHECK_BUSY
  193. ts = get_timer (0); /* get current time */
  194. while ((*fn->busy) (cookie)) {
  195. /* XXX - we should have a check in here somewhere to
  196. * make sure we aren't busy forever... */
  197. CONFIG_FPGA_DELAY ();
  198. (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */
  199. CONFIG_FPGA_DELAY ();
  200. (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */
  201. if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
  202. puts ("** Timeout waiting for BUSY to clear.\n");
  203. (*fn->abort) (cookie); /* abort the burn */
  204. return FPGA_FAIL;
  205. }
  206. }
  207. #endif
  208. #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
  209. if (bytecount % (bsize / 40) == 0)
  210. putc ('.'); /* let them know we are alive */
  211. #endif
  212. }
  213. CONFIG_FPGA_DELAY ();
  214. (*fn->cs) (FALSE, TRUE, cookie); /* Deassert the chip select */
  215. (*fn->wr) (FALSE, TRUE, cookie); /* Deassert the write pin */
  216. #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
  217. putc ('\n'); /* terminate the dotted line */
  218. #endif
  219. /* now check for done signal */
  220. ts = get_timer (0); /* get current time */
  221. ret_val = FPGA_SUCCESS;
  222. while ((*fn->done) (cookie) == FPGA_FAIL) {
  223. /* XXX - we should have a check in here somewhere to
  224. * make sure we aren't busy forever... */
  225. CONFIG_FPGA_DELAY ();
  226. (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */
  227. CONFIG_FPGA_DELAY ();
  228. (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */
  229. if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
  230. puts ("** Timeout waiting for DONE to clear.\n");
  231. (*fn->abort) (cookie); /* abort the burn */
  232. ret_val = FPGA_FAIL;
  233. break;
  234. }
  235. }
  236. /*
  237. * Run the post configuration function if there is one.
  238. */
  239. if (*fn->post)
  240. (*fn->post) (cookie);
  241. #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
  242. if (ret_val == FPGA_SUCCESS)
  243. puts ("Done.\n");
  244. else
  245. puts ("Fail.\n");
  246. #endif
  247. } else {
  248. printf ("%s: NULL Interface function table!\n", __FUNCTION__);
  249. }
  250. return ret_val;
  251. }
  252. static int Spartan3_sp_dump (Xilinx_desc * desc, void *buf, size_t bsize)
  253. {
  254. int ret_val = FPGA_FAIL; /* assume the worst */
  255. Xilinx_Spartan3_Slave_Parallel_fns *fn = desc->iface_fns;
  256. if (fn) {
  257. unsigned char *data = (unsigned char *) buf;
  258. size_t bytecount = 0;
  259. int cookie = desc->cookie; /* make a local copy */
  260. printf ("Starting Dump of FPGA Device %d...\n", cookie);
  261. (*fn->cs) (TRUE, TRUE, cookie); /* Assert chip select, commit */
  262. (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */
  263. /* dump the data */
  264. while (bytecount < bsize) {
  265. /* XXX - do we check for an Ctrl-C press in here ??? */
  266. (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */
  267. (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */
  268. (*fn->rdata) (&(data[bytecount++]), cookie); /* read the data */
  269. #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
  270. if (bytecount % (bsize / 40) == 0)
  271. putc ('.'); /* let them know we are alive */
  272. #endif
  273. }
  274. (*fn->cs) (FALSE, FALSE, cookie); /* Deassert the chip select */
  275. (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */
  276. (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */
  277. #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
  278. putc ('\n'); /* terminate the dotted line */
  279. #endif
  280. puts ("Done.\n");
  281. /* XXX - checksum the data? */
  282. } else {
  283. printf ("%s: NULL Interface function table!\n", __FUNCTION__);
  284. }
  285. return ret_val;
  286. }
  287. static int Spartan3_sp_reloc (Xilinx_desc * desc, ulong reloc_offset)
  288. {
  289. int ret_val = FPGA_FAIL; /* assume the worst */
  290. Xilinx_Spartan3_Slave_Parallel_fns *fn_r, *fn =
  291. (Xilinx_Spartan3_Slave_Parallel_fns *) (desc->iface_fns);
  292. if (fn) {
  293. ulong addr;
  294. /* Get the relocated table address */
  295. addr = (ulong) fn + reloc_offset;
  296. fn_r = (Xilinx_Spartan3_Slave_Parallel_fns *) addr;
  297. if (!fn_r->relocated) {
  298. if (memcmp (fn_r, fn,
  299. sizeof (Xilinx_Spartan3_Slave_Parallel_fns))
  300. == 0) {
  301. /* good copy of the table, fix the descriptor pointer */
  302. desc->iface_fns = fn_r;
  303. } else {
  304. PRINTF ("%s: Invalid function table at 0x%p\n",
  305. __FUNCTION__, fn_r);
  306. return FPGA_FAIL;
  307. }
  308. PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__,
  309. desc);
  310. addr = (ulong) (fn->pre) + reloc_offset;
  311. fn_r->pre = (Xilinx_pre_fn) addr;
  312. addr = (ulong) (fn->pgm) + reloc_offset;
  313. fn_r->pgm = (Xilinx_pgm_fn) addr;
  314. addr = (ulong) (fn->init) + reloc_offset;
  315. fn_r->init = (Xilinx_init_fn) addr;
  316. addr = (ulong) (fn->done) + reloc_offset;
  317. fn_r->done = (Xilinx_done_fn) addr;
  318. addr = (ulong) (fn->clk) + reloc_offset;
  319. fn_r->clk = (Xilinx_clk_fn) addr;
  320. addr = (ulong) (fn->err) + reloc_offset;
  321. fn_r->err = (Xilinx_err_fn) addr;
  322. addr = (ulong) (fn->cs) + reloc_offset;
  323. fn_r->cs = (Xilinx_cs_fn) addr;
  324. addr = (ulong) (fn->wr) + reloc_offset;
  325. fn_r->wr = (Xilinx_wr_fn) addr;
  326. addr = (ulong) (fn->rdata) + reloc_offset;
  327. fn_r->rdata = (Xilinx_rdata_fn) addr;
  328. addr = (ulong) (fn->wdata) + reloc_offset;
  329. fn_r->wdata = (Xilinx_wdata_fn) addr;
  330. addr = (ulong) (fn->busy) + reloc_offset;
  331. fn_r->busy = (Xilinx_busy_fn) addr;
  332. addr = (ulong) (fn->abort) + reloc_offset;
  333. fn_r->abort = (Xilinx_abort_fn) addr;
  334. addr = (ulong) (fn->post) + reloc_offset;
  335. fn_r->post = (Xilinx_post_fn) addr;
  336. fn_r->relocated = TRUE;
  337. } else {
  338. /* this table has already been moved */
  339. /* XXX - should check to see if the descriptor is correct */
  340. desc->iface_fns = fn_r;
  341. }
  342. ret_val = FPGA_SUCCESS;
  343. } else {
  344. printf ("%s: NULL Interface function table!\n", __FUNCTION__);
  345. }
  346. return ret_val;
  347. }
  348. /* ------------------------------------------------------------------------- */
  349. static int Spartan3_ss_load (Xilinx_desc * desc, void *buf, size_t bsize)
  350. {
  351. int ret_val = FPGA_FAIL; /* assume the worst */
  352. Xilinx_Spartan3_Slave_Serial_fns *fn = desc->iface_fns;
  353. int i;
  354. unsigned char val;
  355. PRINTF ("%s: start with interface functions @ 0x%p\n",
  356. __FUNCTION__, fn);
  357. if (fn) {
  358. size_t bytecount = 0;
  359. unsigned char *data = (unsigned char *) buf;
  360. int cookie = desc->cookie; /* make a local copy */
  361. unsigned long ts; /* timestamp */
  362. PRINTF ("%s: Function Table:\n"
  363. "ptr:\t0x%p\n"
  364. "struct: 0x%p\n"
  365. "pgm:\t0x%p\n"
  366. "init:\t0x%p\n"
  367. "clk:\t0x%p\n"
  368. "wr:\t0x%p\n"
  369. "done:\t0x%p\n\n",
  370. __FUNCTION__, &fn, fn, fn->pgm, fn->init,
  371. fn->clk, fn->wr, fn->done);
  372. #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
  373. printf ("Loading FPGA Device %d...\n", cookie);
  374. #endif
  375. /*
  376. * Run the pre configuration function if there is one.
  377. */
  378. if (*fn->pre) {
  379. (*fn->pre) (cookie);
  380. }
  381. /* Establish the initial state */
  382. (*fn->pgm) (TRUE, TRUE, cookie); /* Assert the program, commit */
  383. /* Wait for INIT state (init low) */
  384. ts = get_timer (0); /* get current time */
  385. do {
  386. CONFIG_FPGA_DELAY ();
  387. if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
  388. puts ("** Timeout waiting for INIT to start.\n");
  389. return FPGA_FAIL;
  390. }
  391. } while (!(*fn->init) (cookie));
  392. /* Get ready for the burn */
  393. CONFIG_FPGA_DELAY ();
  394. (*fn->pgm) (FALSE, TRUE, cookie); /* Deassert the program, commit */
  395. ts = get_timer (0); /* get current time */
  396. /* Now wait for INIT to go high */
  397. do {
  398. CONFIG_FPGA_DELAY ();
  399. if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
  400. puts ("** Timeout waiting for INIT to clear.\n");
  401. return FPGA_FAIL;
  402. }
  403. } while ((*fn->init) (cookie));
  404. /* Load the data */
  405. while (bytecount < bsize) {
  406. /* Xilinx detects an error if INIT goes low (active)
  407. while DONE is low (inactive) */
  408. if ((*fn->done) (cookie) == 0 && (*fn->init) (cookie)) {
  409. puts ("** CRC error during FPGA load.\n");
  410. return (FPGA_FAIL);
  411. }
  412. val = data [bytecount ++];
  413. i = 8;
  414. do {
  415. /* Deassert the clock */
  416. (*fn->clk) (FALSE, TRUE, cookie);
  417. CONFIG_FPGA_DELAY ();
  418. /* Write data */
  419. (*fn->wr) ((val & 0x80), TRUE, cookie);
  420. CONFIG_FPGA_DELAY ();
  421. /* Assert the clock */
  422. (*fn->clk) (TRUE, TRUE, cookie);
  423. CONFIG_FPGA_DELAY ();
  424. val <<= 1;
  425. i --;
  426. } while (i > 0);
  427. #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
  428. if (bytecount % (bsize / 40) == 0)
  429. putc ('.'); /* let them know we are alive */
  430. #endif
  431. }
  432. CONFIG_FPGA_DELAY ();
  433. #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
  434. putc ('\n'); /* terminate the dotted line */
  435. #endif
  436. /* now check for done signal */
  437. ts = get_timer (0); /* get current time */
  438. ret_val = FPGA_SUCCESS;
  439. (*fn->wr) (TRUE, TRUE, cookie);
  440. while (! (*fn->done) (cookie)) {
  441. /* XXX - we should have a check in here somewhere to
  442. * make sure we aren't busy forever... */
  443. CONFIG_FPGA_DELAY ();
  444. (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */
  445. CONFIG_FPGA_DELAY ();
  446. (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */
  447. putc ('*');
  448. if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
  449. puts ("** Timeout waiting for DONE to clear.\n");
  450. ret_val = FPGA_FAIL;
  451. break;
  452. }
  453. }
  454. putc ('\n'); /* terminate the dotted line */
  455. /*
  456. * Run the post configuration function if there is one.
  457. */
  458. if (*fn->post)
  459. (*fn->post) (cookie);
  460. #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
  461. if (ret_val == FPGA_SUCCESS)
  462. puts ("Done.\n");
  463. else
  464. puts ("Fail.\n");
  465. #endif
  466. } else {
  467. printf ("%s: NULL Interface function table!\n", __FUNCTION__);
  468. }
  469. return ret_val;
  470. }
  471. static int Spartan3_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize)
  472. {
  473. /* Readback is only available through the Slave Parallel and */
  474. /* boundary-scan interfaces. */
  475. printf ("%s: Slave Serial Dumping is unavailable\n",
  476. __FUNCTION__);
  477. return FPGA_FAIL;
  478. }
  479. static int Spartan3_ss_reloc (Xilinx_desc * desc, ulong reloc_offset)
  480. {
  481. int ret_val = FPGA_FAIL; /* assume the worst */
  482. Xilinx_Spartan3_Slave_Serial_fns *fn_r, *fn =
  483. (Xilinx_Spartan3_Slave_Serial_fns *) (desc->iface_fns);
  484. if (fn) {
  485. ulong addr;
  486. /* Get the relocated table address */
  487. addr = (ulong) fn + reloc_offset;
  488. fn_r = (Xilinx_Spartan3_Slave_Serial_fns *) addr;
  489. if (!fn_r->relocated) {
  490. if (memcmp (fn_r, fn,
  491. sizeof (Xilinx_Spartan3_Slave_Serial_fns))
  492. == 0) {
  493. /* good copy of the table, fix the descriptor pointer */
  494. desc->iface_fns = fn_r;
  495. } else {
  496. PRINTF ("%s: Invalid function table at 0x%p\n",
  497. __FUNCTION__, fn_r);
  498. return FPGA_FAIL;
  499. }
  500. PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__,
  501. desc);
  502. if (fn->pre) {
  503. addr = (ulong) (fn->pre) + reloc_offset;
  504. fn_r->pre = (Xilinx_pre_fn) addr;
  505. }
  506. addr = (ulong) (fn->pgm) + reloc_offset;
  507. fn_r->pgm = (Xilinx_pgm_fn) addr;
  508. addr = (ulong) (fn->init) + reloc_offset;
  509. fn_r->init = (Xilinx_init_fn) addr;
  510. addr = (ulong) (fn->done) + reloc_offset;
  511. fn_r->done = (Xilinx_done_fn) addr;
  512. addr = (ulong) (fn->clk) + reloc_offset;
  513. fn_r->clk = (Xilinx_clk_fn) addr;
  514. addr = (ulong) (fn->wr) + reloc_offset;
  515. fn_r->wr = (Xilinx_wr_fn) addr;
  516. if (fn->post) {
  517. addr = (ulong) (fn->post) + reloc_offset;
  518. fn_r->post = (Xilinx_post_fn) addr;
  519. }
  520. fn_r->relocated = TRUE;
  521. } else {
  522. /* this table has already been moved */
  523. /* XXX - should check to see if the descriptor is correct */
  524. desc->iface_fns = fn_r;
  525. }
  526. ret_val = FPGA_SUCCESS;
  527. } else {
  528. printf ("%s: NULL Interface function table!\n", __FUNCTION__);
  529. }
  530. return ret_val;
  531. }