]>
Commit | Line | Data |
---|---|---|
5d3207da WD |
1 | /* |
2 | * (C) Copyright 2002 | |
3 | * Rich Ireland, Enterasys Networks, [email protected]. | |
4 | * Keith Outwater, [email protected] | |
5 | * | |
6 | * See file CREDITS for list of people who contributed to this | |
7 | * project. | |
8 | * | |
9 | * This program is free software; you can redistribute it and/or | |
10 | * modify it under the terms of the GNU General Public License as | |
11 | * published by the Free Software Foundation; either version 2 of | |
12 | * the License, or (at your option) any later version. | |
13 | * | |
14 | * This program is distributed in the hope that it will be useful, | |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | * GNU General Public License for more details. | |
18 | * | |
19 | * You should have received a copy of the GNU General Public License | |
20 | * along with this program; if not, write to the Free Software | |
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
22 | * MA 02111-1307 USA | |
23 | * | |
24 | */ | |
25 | ||
26 | /* | |
27 | * Configuration support for Xilinx Virtex2 devices. Based | |
28 | * on spartan2.c (Rich Ireland, [email protected]). | |
29 | */ | |
30 | ||
31 | #include <common.h> | |
32 | #include <virtex2.h> | |
33 | ||
34 | #if (CONFIG_FPGA & (CFG_XILINX | CFG_VIRTEX2)) | |
35 | ||
36 | #ifdef FPGA_DEBUG | |
37 | #define PRINTF(fmt,args...) printf (fmt ,##args) | |
38 | #else | |
39 | #define PRINTF(fmt,args...) | |
40 | #endif | |
41 | ||
42 | /* | |
43 | * If the SelectMap interface can be overrun by the processor, define | |
44 | * CFG_FPGA_CHECK_BUSY and/or CONFIG_FPGA_DELAY in the board configuration | |
45 | * file and add board-specific support for checking BUSY status. By default, | |
46 | * assume that the SelectMap interface cannot be overrun. | |
47 | */ | |
48 | #ifndef CFG_FPGA_CHECK_BUSY | |
49 | #undef CFG_FPGA_CHECK_BUSY | |
50 | #endif | |
51 | ||
52 | #ifndef CONFIG_FPGA_DELAY | |
53 | #define CONFIG_FPGA_DELAY() | |
54 | #endif | |
55 | ||
56 | #ifndef CFG_FPGA_PROG_FEEDBACK | |
57 | #define CFG_FPGA_PROG_FEEDBACK | |
58 | #endif | |
59 | ||
60 | /* | |
61 | * Don't allow config cycle to be interrupted | |
62 | */ | |
63 | #ifndef CFG_FPGA_CHECK_CTRLC | |
64 | #undef CFG_FPGA_CHECK_CTRLC | |
65 | #endif | |
66 | ||
67 | /* | |
68 | * Check for errors during configuration by default | |
69 | */ | |
70 | #ifndef CFG_FPGA_CHECK_ERROR | |
71 | #define CFG_FPGA_CHECK_ERROR | |
72 | #endif | |
73 | ||
74 | /* | |
75 | * The default timeout in mS for INIT_B to deassert after PROG_B has | |
76 | * been deasserted. Per the latest Virtex II Handbook (page 347), the | |
77 | * max time from PORG_B deassertion to INIT_B deassertion is 4uS per | |
78 | * data frame for the XC2V8000. The XC2V8000 has 2860 data frames | |
79 | * which yields 11.44 mS. So let's make it bigger in order to handle | |
80 | * an XC2V1000, if anyone can ever get ahold of one. | |
81 | */ | |
82 | #ifndef CFG_FPGA_WAIT_INIT | |
11dadd54 | 83 | #define CFG_FPGA_WAIT_INIT CFG_HZ/2 /* 500 ms */ |
5d3207da WD |
84 | #endif |
85 | ||
86 | /* | |
87 | * The default timeout for waiting for BUSY to deassert during configuration. | |
88 | * This is normally not necessary since for most reasonable configuration | |
89 | * clock frequencies (i.e. 66 MHz or less), BUSY monitoring is unnecessary. | |
90 | */ | |
91 | #ifndef CFG_FPGA_WAIT_BUSY | |
11dadd54 | 92 | #define CFG_FPGA_WAIT_BUSY CFG_HZ/200 /* 5 ms*/ |
5d3207da WD |
93 | #endif |
94 | ||
95 | /* Default timeout for waiting for FPGA to enter operational mode after | |
96 | * configuration data has been written. | |
97 | */ | |
98 | #ifndef CFG_FPGA_WAIT_CONFIG | |
11dadd54 | 99 | #define CFG_FPGA_WAIT_CONFIG CFG_HZ/5 /* 200 ms */ |
5d3207da WD |
100 | #endif |
101 | ||
102 | static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize); | |
103 | static int Virtex2_ssm_dump (Xilinx_desc * desc, void *buf, size_t bsize); | |
104 | static int Virtex2_ssm_reloc (Xilinx_desc * desc, ulong reloc_offset); | |
105 | ||
106 | static int Virtex2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize); | |
107 | static int Virtex2_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize); | |
108 | static int Virtex2_ss_reloc (Xilinx_desc * desc, ulong reloc_offset); | |
109 | ||
110 | int Virtex2_load (Xilinx_desc * desc, void *buf, size_t bsize) | |
111 | { | |
112 | int ret_val = FPGA_FAIL; | |
113 | ||
114 | switch (desc->iface) { | |
115 | case slave_serial: | |
116 | PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__); | |
117 | ret_val = Virtex2_ss_load (desc, buf, bsize); | |
118 | break; | |
119 | ||
120 | case slave_selectmap: | |
121 | PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__); | |
122 | ret_val = Virtex2_ssm_load (desc, buf, bsize); | |
123 | break; | |
124 | ||
125 | default: | |
126 | printf ("%s: Unsupported interface type, %d\n", | |
127 | __FUNCTION__, desc->iface); | |
128 | } | |
129 | return ret_val; | |
130 | } | |
131 | ||
132 | int Virtex2_dump (Xilinx_desc * desc, void *buf, size_t bsize) | |
133 | { | |
134 | int ret_val = FPGA_FAIL; | |
135 | ||
136 | switch (desc->iface) { | |
137 | case slave_serial: | |
138 | PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__); | |
139 | ret_val = Virtex2_ss_dump (desc, buf, bsize); | |
140 | break; | |
141 | ||
142 | case slave_parallel: | |
143 | PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__); | |
144 | ret_val = Virtex2_ssm_dump (desc, buf, bsize); | |
145 | break; | |
146 | ||
147 | default: | |
148 | printf ("%s: Unsupported interface type, %d\n", | |
149 | __FUNCTION__, desc->iface); | |
150 | } | |
151 | return ret_val; | |
152 | } | |
153 | ||
154 | int Virtex2_info (Xilinx_desc * desc) | |
155 | { | |
156 | return FPGA_SUCCESS; | |
157 | } | |
158 | ||
159 | int Virtex2_reloc (Xilinx_desc * desc, ulong reloc_offset) | |
160 | { | |
161 | int ret_val = FPGA_FAIL; | |
162 | ||
163 | if (desc->family != Xilinx_Virtex2) { | |
164 | printf ("%s: Unsupported family type, %d\n", | |
165 | __FUNCTION__, desc->family); | |
166 | return FPGA_FAIL; | |
167 | } else | |
168 | switch (desc->iface) { | |
169 | case slave_serial: | |
170 | ret_val = Virtex2_ss_reloc (desc, reloc_offset); | |
171 | break; | |
172 | ||
173 | case slave_selectmap: | |
174 | ret_val = Virtex2_ssm_reloc (desc, reloc_offset); | |
175 | break; | |
176 | ||
177 | default: | |
178 | printf ("%s: Unsupported interface type, %d\n", | |
179 | __FUNCTION__, desc->iface); | |
180 | } | |
181 | return ret_val; | |
182 | } | |
183 | ||
184 | /* | |
185 | * Virtex-II Slave SelectMap configuration loader. Configuration via | |
186 | * SelectMap is as follows: | |
187 | * 1. Set the FPGA's PROG_B line low. | |
188 | * 2. Set the FPGA's PROG_B line high. Wait for INIT_B to go high. | |
189 | * 3. Write data to the SelectMap port. If INIT_B goes low at any time | |
190 | * this process, a configuration error (most likely CRC failure) has | |
191 | * ocurred. At this point a status word may be read from the | |
192 | * SelectMap interface to determine the source of the problem (You | |
193 | * could, for instance, put this in you 'abort' function handler). | |
194 | * 4. After all data has been written, test the state of the FPGA | |
195 | * INIT_B and DONE lines. If both are high, configuration has | |
196 | * succeeded. Congratulations! | |
197 | */ | |
198 | static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize) | |
199 | { | |
200 | int ret_val = FPGA_FAIL; | |
201 | Xilinx_Virtex2_Slave_SelectMap_fns *fn = desc->iface_fns; | |
202 | ||
203 | PRINTF ("%s:%d: Start with interface functions @ 0x%p\n", | |
204 | __FUNCTION__, __LINE__, fn); | |
205 | ||
206 | if (fn) { | |
207 | size_t bytecount = 0; | |
208 | unsigned char *data = (unsigned char *) buf; | |
209 | int cookie = desc->cookie; | |
210 | unsigned long ts; | |
211 | ||
212 | /* Gotta split this one up (so the stack won't blow??) */ | |
213 | PRINTF ("%s:%d: Function Table:\n" | |
214 | " base 0x%p\n" | |
215 | " struct 0x%p\n" | |
216 | " pre 0x%p\n" | |
217 | " prog 0x%p\n" | |
218 | " init 0x%p\n" | |
219 | " error 0x%p\n", | |
220 | __FUNCTION__, __LINE__, | |
221 | &fn, fn, fn->pre, fn->pgm, fn->init, fn->err); | |
222 | PRINTF (" clock 0x%p\n" | |
223 | " cs 0x%p\n" | |
224 | " write 0x%p\n" | |
225 | " rdata 0x%p\n" | |
226 | " wdata 0x%p\n" | |
227 | " busy 0x%p\n" | |
228 | " abort 0x%p\n" | |
229 | " post 0x%p\n\n", | |
230 | fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, | |
231 | fn->busy, fn->abort, fn->post); | |
232 | ||
233 | #ifdef CFG_FPGA_PROG_FEEDBACK | |
234 | printf ("Initializing FPGA Device %d...\n", cookie); | |
235 | #endif | |
236 | /* | |
237 | * Run the pre configuration function if there is one. | |
238 | */ | |
239 | if (*fn->pre) { | |
240 | (*fn->pre) (cookie); | |
241 | } | |
242 | ||
243 | /* | |
244 | * Assert the program line. The minimum pulse width for | |
245 | * Virtex II devices is 300 nS (Tprogram parameter in datasheet). | |
246 | * There is no maximum value for the pulse width. Check to make | |
247 | * sure that INIT_B goes low after assertion of PROG_B | |
248 | */ | |
249 | (*fn->pgm) (TRUE, TRUE, cookie); | |
250 | udelay (10); | |
251 | ts = get_timer (0); | |
252 | do { | |
253 | if (get_timer (ts) > CFG_FPGA_WAIT_INIT) { | |
254 | printf ("%s:%d: ** Timeout after %d mS waiting for INIT" | |
255 | " to assert.\n", __FUNCTION__, __LINE__, | |
256 | CFG_FPGA_WAIT_INIT); | |
257 | (*fn->abort) (cookie); | |
258 | return FPGA_FAIL; | |
259 | } | |
260 | } while (!(*fn->init) (cookie)); | |
261 | ||
262 | (*fn->pgm) (FALSE, TRUE, cookie); | |
263 | CONFIG_FPGA_DELAY (); | |
264 | (*fn->clk) (TRUE, TRUE, cookie); | |
265 | ||
266 | /* | |
267 | * Start a timer and wait for INIT_B to go high | |
268 | */ | |
269 | ts = get_timer (0); | |
270 | do { | |
271 | CONFIG_FPGA_DELAY (); | |
272 | if (get_timer (ts) > CFG_FPGA_WAIT_INIT) { | |
273 | printf ("%s:%d: ** Timeout after %d mS waiting for INIT" | |
274 | " to deassert.\n", __FUNCTION__, __LINE__, | |
275 | CFG_FPGA_WAIT_INIT); | |
276 | (*fn->abort) (cookie); | |
277 | return FPGA_FAIL; | |
278 | } | |
279 | } while ((*fn->init) (cookie) && (*fn->busy) (cookie)); | |
280 | ||
281 | (*fn->wr) (TRUE, TRUE, cookie); | |
282 | (*fn->cs) (TRUE, TRUE, cookie); | |
283 | ||
284 | udelay (10000); | |
285 | ||
286 | /* | |
287 | * Load the data byte by byte | |
288 | */ | |
289 | while (bytecount < bsize) { | |
290 | #ifdef CFG_FPGA_CHECK_CTRLC | |
291 | if (ctrlc ()) { | |
292 | (*fn->abort) (cookie); | |
293 | return FPGA_FAIL; | |
294 | } | |
295 | #endif | |
296 | #ifdef CFG_FPGA_CHECK_ERROR | |
297 | if ((*fn->init) (cookie)) { | |
298 | printf ("%s:%d: ** Error: INIT asserted during" | |
299 | " configuration\n", __FUNCTION__, __LINE__); | |
300 | (*fn->abort) (cookie); | |
301 | return FPGA_FAIL; | |
302 | } | |
303 | #endif | |
304 | (*fn->wdata) (data[bytecount++], TRUE, cookie); | |
305 | CONFIG_FPGA_DELAY (); | |
306 | ||
307 | /* | |
308 | * Cycle the clock pin | |
309 | */ | |
310 | (*fn->clk) (FALSE, TRUE, cookie); | |
311 | CONFIG_FPGA_DELAY (); | |
312 | (*fn->clk) (TRUE, TRUE, cookie); | |
313 | ||
314 | #ifdef CFG_FPGA_CHECK_BUSY | |
315 | ts = get_timer (0); | |
316 | while ((*fn->busy) (cookie)) { | |
317 | if (get_timer (ts) > CFG_FPGA_WAIT_BUSY) { | |
318 | printf ("%s:%d: ** Timeout after %d mS waiting for" | |
319 | " BUSY to deassert\n", | |
320 | __FUNCTION__, __LINE__, CFG_FPGA_WAIT_BUSY); | |
321 | (*fn->abort) (cookie); | |
322 | return FPGA_FAIL; | |
323 | } | |
324 | } | |
325 | #endif | |
326 | ||
327 | #ifdef CFG_FPGA_PROG_FEEDBACK | |
328 | if (bytecount % (bsize / 40) == 0) | |
329 | putc ('.'); | |
330 | #endif | |
331 | } | |
332 | ||
333 | /* | |
334 | * Finished writing the data; deassert FPGA CS_B and WRITE_B signals. | |
335 | */ | |
336 | CONFIG_FPGA_DELAY (); | |
337 | (*fn->cs) (FALSE, TRUE, cookie); | |
338 | (*fn->wr) (FALSE, TRUE, cookie); | |
339 | ||
340 | #ifdef CFG_FPGA_PROG_FEEDBACK | |
341 | putc ('\n'); | |
342 | #endif | |
343 | ||
344 | /* | |
345 | * Check for successful configuration. FPGA INIT_B and DONE should | |
346 | * both be high upon successful configuration. | |
347 | */ | |
348 | ts = get_timer (0); | |
349 | ret_val = FPGA_SUCCESS; | |
350 | while (((*fn->done) (cookie) == FPGA_FAIL) || (*fn->init) (cookie)) { | |
351 | if (get_timer (ts) > CFG_FPGA_WAIT_CONFIG) { | |
352 | printf ("%s:%d: ** Timeout after %d mS waiting for DONE to" | |
353 | "assert and INIT to deassert\n", | |
354 | __FUNCTION__, __LINE__, CFG_FPGA_WAIT_CONFIG); | |
355 | (*fn->abort) (cookie); | |
356 | ret_val = FPGA_FAIL; | |
357 | break; | |
358 | } | |
359 | } | |
360 | ||
361 | if (ret_val == FPGA_SUCCESS) { | |
362 | #ifdef CFG_FPGA_PROG_FEEDBACK | |
363 | printf ("Initialization of FPGA device %d complete\n", cookie); | |
364 | #endif | |
365 | /* | |
366 | * Run the post configuration function if there is one. | |
367 | */ | |
368 | if (*fn->post) { | |
369 | (*fn->post) (cookie); | |
370 | } | |
371 | } else { | |
372 | #ifdef CFG_FPGA_PROG_FEEDBACK | |
373 | printf ("** Initialization of FPGA device %d FAILED\n", | |
374 | cookie); | |
375 | #endif | |
376 | } | |
377 | } else { | |
378 | printf ("%s:%d: NULL Interface function table!\n", | |
379 | __FUNCTION__, __LINE__); | |
380 | } | |
381 | return ret_val; | |
382 | } | |
383 | ||
384 | /* | |
385 | * Read the FPGA configuration data | |
386 | */ | |
387 | static int Virtex2_ssm_dump (Xilinx_desc * desc, void *buf, size_t bsize) | |
388 | { | |
389 | int ret_val = FPGA_FAIL; | |
390 | Xilinx_Virtex2_Slave_SelectMap_fns *fn = desc->iface_fns; | |
391 | ||
392 | if (fn) { | |
393 | unsigned char *data = (unsigned char *) buf; | |
394 | size_t bytecount = 0; | |
395 | int cookie = desc->cookie; | |
396 | ||
397 | printf ("Starting Dump of FPGA Device %d...\n", cookie); | |
398 | ||
399 | (*fn->cs) (TRUE, TRUE, cookie); | |
400 | (*fn->clk) (TRUE, TRUE, cookie); | |
401 | ||
402 | while (bytecount < bsize) { | |
403 | #ifdef CFG_FPGA_CHECK_CTRLC | |
404 | if (ctrlc ()) { | |
405 | (*fn->abort) (cookie); | |
406 | return FPGA_FAIL; | |
407 | } | |
408 | #endif | |
409 | /* | |
410 | * Cycle the clock and read the data | |
411 | */ | |
412 | (*fn->clk) (FALSE, TRUE, cookie); | |
413 | (*fn->clk) (TRUE, TRUE, cookie); | |
414 | (*fn->rdata) (&(data[bytecount++]), cookie); | |
415 | #ifdef CFG_FPGA_PROG_FEEDBACK | |
416 | if (bytecount % (bsize / 40) == 0) | |
417 | putc ('.'); | |
418 | #endif | |
419 | } | |
420 | ||
421 | /* | |
422 | * Deassert CS_B and cycle the clock to deselect the device. | |
423 | */ | |
424 | (*fn->cs) (FALSE, FALSE, cookie); | |
425 | (*fn->clk) (FALSE, TRUE, cookie); | |
426 | (*fn->clk) (TRUE, TRUE, cookie); | |
427 | ||
428 | #ifdef CFG_FPGA_PROG_FEEDBACK | |
429 | putc ('\n'); | |
430 | #endif | |
431 | puts ("Done.\n"); | |
432 | } else { | |
433 | printf ("%s:%d: NULL Interface function table!\n", | |
434 | __FUNCTION__, __LINE__); | |
435 | } | |
436 | return ret_val; | |
437 | } | |
438 | ||
439 | /* | |
440 | * Relocate the addresses in the function table from FLASH (or ROM, | |
441 | * or whatever) to RAM. | |
442 | */ | |
443 | static int Virtex2_ssm_reloc (Xilinx_desc * desc, ulong reloc_offset) | |
444 | { | |
445 | ulong addr; | |
446 | int ret_val = FPGA_FAIL; | |
447 | Xilinx_Virtex2_Slave_SelectMap_fns *fn_r, *fn = | |
448 | (Xilinx_Virtex2_Slave_SelectMap_fns *) (desc->iface_fns); | |
449 | ||
450 | if (fn) { | |
451 | /* | |
452 | * Get the relocated table address | |
453 | */ | |
454 | addr = (ulong) fn + reloc_offset; | |
455 | fn_r = (Xilinx_Virtex2_Slave_SelectMap_fns *) addr; | |
456 | ||
457 | /* | |
458 | * Check to see if the table has already been relocated. If not, do | |
459 | * a sanity check to make sure there is a faithful copy of the | |
460 | * FLASH based function table in RAM, then adjust the table. | |
461 | */ | |
462 | if (!fn_r->relocated) { | |
463 | if (memcmp | |
464 | (fn_r, fn, sizeof (Xilinx_Virtex2_Slave_SelectMap_fns)) | |
465 | == 0) { | |
466 | desc->iface_fns = fn_r; | |
467 | } else { | |
468 | PRINTF ("%s:%d: Invalid function table at 0x%p\n", | |
469 | __FUNCTION__, __LINE__, fn_r); | |
470 | return FPGA_FAIL; | |
471 | } | |
472 | ||
473 | PRINTF ("%s:%d: Relocating descriptor at 0x%p\n", | |
474 | __FUNCTION__, __LINE__, desc); | |
475 | ||
476 | addr = (ulong) (fn->pre) + reloc_offset; | |
477 | fn_r->pre = (Xilinx_pre_fn) addr; | |
478 | addr = (ulong) (fn->pgm) + reloc_offset; | |
479 | fn_r->pgm = (Xilinx_pgm_fn) addr; | |
480 | addr = (ulong) (fn->init) + reloc_offset; | |
481 | fn_r->init = (Xilinx_init_fn) addr; | |
482 | addr = (ulong) (fn->done) + reloc_offset; | |
483 | fn_r->done = (Xilinx_done_fn) addr; | |
484 | addr = (ulong) (fn->err) + reloc_offset; | |
485 | fn_r->err = (Xilinx_err_fn) addr; | |
486 | addr = (ulong) (fn->clk) + reloc_offset; | |
487 | fn_r->clk = (Xilinx_clk_fn) addr; | |
488 | addr = (ulong) (fn->cs) + reloc_offset; | |
489 | fn_r->cs = (Xilinx_cs_fn) addr; | |
490 | addr = (ulong) (fn->wr) + reloc_offset; | |
491 | fn_r->wr = (Xilinx_wr_fn) addr; | |
492 | addr = (ulong) (fn->rdata) + reloc_offset; | |
493 | fn_r->rdata = (Xilinx_rdata_fn) addr; | |
494 | addr = (ulong) (fn->wdata) + reloc_offset; | |
495 | fn_r->wdata = (Xilinx_wdata_fn) addr; | |
496 | addr = (ulong) (fn->busy) + reloc_offset; | |
497 | fn_r->busy = (Xilinx_busy_fn) addr; | |
498 | addr = (ulong) (fn->abort) + reloc_offset; | |
499 | fn_r->abort = (Xilinx_abort_fn) addr; | |
500 | addr = (ulong) (fn->post) + reloc_offset; | |
501 | fn_r->post = (Xilinx_post_fn) addr; | |
502 | fn_r->relocated = TRUE; | |
503 | } else { | |
504 | printf ("%s:%d: Function table @0x%p has already been relocated\n", __FUNCTION__, __LINE__, fn_r); | |
505 | desc->iface_fns = fn_r; | |
506 | } | |
507 | ret_val = FPGA_SUCCESS; | |
508 | } else { | |
509 | printf ("%s: NULL Interface function table!\n", __FUNCTION__); | |
510 | } | |
511 | return ret_val; | |
512 | } | |
513 | ||
514 | static int Virtex2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize) | |
515 | { | |
516 | printf ("%s: Slave Serial Loading is unsupported\n", __FUNCTION__); | |
517 | return FPGA_FAIL; | |
518 | } | |
519 | ||
520 | static int Virtex2_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize) | |
521 | { | |
522 | printf ("%s: Slave Serial Dumping is unsupported\n", __FUNCTION__); | |
523 | return FPGA_FAIL; | |
524 | } | |
525 | ||
526 | static int Virtex2_ss_reloc (Xilinx_desc * desc, ulong reloc_offset) | |
527 | { | |
528 | int ret_val = FPGA_FAIL; | |
529 | Xilinx_Virtex2_Slave_Serial_fns *fn = | |
530 | (Xilinx_Virtex2_Slave_Serial_fns *) (desc->iface_fns); | |
531 | ||
532 | if (fn) { | |
533 | printf ("%s:%d: Slave Serial Loading is unsupported\n", | |
534 | __FUNCTION__, __LINE__); | |
535 | } else { | |
536 | printf ("%s:%d: NULL Interface function table!\n", | |
537 | __FUNCTION__, __LINE__); | |
538 | } | |
539 | return ret_val; | |
540 | } | |
541 | #endif | |
542 | ||
543 | /* vim: set ts=4 tw=78: */ |