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