source: SVN/rincon/u-boot/common/cmd_fpga.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 22 months ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 9.3 KB
Line 
1/*
2 * (C) Copyright 2000, 2001
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/*
26 *  FPGA support
27 */
28#include <common.h>
29#include <command.h>
30#if defined(CONFIG_CMD_NET)
31#include <net.h>
32#endif
33#include <fpga.h>
34#include <malloc.h>
35
36#if 0
37#define FPGA_DEBUG
38#endif
39
40#ifdef  FPGA_DEBUG
41#define PRINTF(fmt,args...)     printf (fmt ,##args)
42#else
43#define PRINTF(fmt,args...)
44#endif
45
46/* Local functions */
47static void fpga_usage (cmd_tbl_t * cmdtp);
48static int fpga_get_op (char *opstr);
49
50/* Local defines */
51#define FPGA_NONE   -1
52#define FPGA_INFO   0
53#define FPGA_LOAD   1
54#define FPGA_LOADB  2
55#define FPGA_DUMP   3
56#define FPGA_LOADMK 4
57
58/* Convert bitstream data and load into the fpga */
59int fpga_loadbitstream(unsigned long dev, char* fpgadata, size_t size)
60{
61#if defined(CONFIG_FPGA_XILINX)
62        unsigned int length;
63        unsigned int swapsize;
64        char buffer[80];
65        unsigned char *dataptr;
66        unsigned int i;
67        int rc;
68
69        dataptr = (unsigned char *)fpgadata;
70
71        /* skip the first bytes of the bitsteam, their meaning is unknown */
72        length = (*dataptr << 8) + *(dataptr+1);
73        dataptr+=2;
74        dataptr+=length;
75
76        /* get design name (identifier, length, string) */
77        length = (*dataptr << 8) + *(dataptr+1);
78        dataptr+=2;
79        if (*dataptr++ != 0x61) {
80                PRINTF ("%s: Design name identifier not recognized in bitstream\n",
81                        __FUNCTION__ );
82                return FPGA_FAIL;
83        }
84
85        length = (*dataptr << 8) + *(dataptr+1);
86        dataptr+=2;
87        for(i=0;i<length;i++)
88                buffer[i] = *dataptr++;
89
90        printf("  design filename = \"%s\"\n", buffer);
91
92        /* get part number (identifier, length, string) */
93        if (*dataptr++ != 0x62) {
94                printf("%s: Part number identifier not recognized in bitstream\n",
95                        __FUNCTION__ );
96                return FPGA_FAIL;
97        }
98
99        length = (*dataptr << 8) + *(dataptr+1);
100        dataptr+=2;
101        for(i=0;i<length;i++)
102                buffer[i] = *dataptr++;
103        printf("  part number = \"%s\"\n", buffer);
104
105        /* get date (identifier, length, string) */
106        if (*dataptr++ != 0x63) {
107                printf("%s: Date identifier not recognized in bitstream\n",
108                       __FUNCTION__);
109                return FPGA_FAIL;
110        }
111
112        length = (*dataptr << 8) + *(dataptr+1);
113        dataptr+=2;
114        for(i=0;i<length;i++)
115                buffer[i] = *dataptr++;
116        printf("  date = \"%s\"\n", buffer);
117
118        /* get time (identifier, length, string) */
119        if (*dataptr++ != 0x64) {
120                printf("%s: Time identifier not recognized in bitstream\n",__FUNCTION__);
121                return FPGA_FAIL;
122        }
123
124        length = (*dataptr << 8) + *(dataptr+1);
125        dataptr+=2;
126        for(i=0;i<length;i++)
127                buffer[i] = *dataptr++;
128        printf("  time = \"%s\"\n", buffer);
129
130        /* get fpga data length (identifier, length) */
131        if (*dataptr++ != 0x65) {
132                printf("%s: Data length identifier not recognized in bitstream\n",
133                        __FUNCTION__);
134                return FPGA_FAIL;
135        }
136        swapsize = ((unsigned int) *dataptr     <<24) +
137                   ((unsigned int) *(dataptr+1) <<16) +
138                   ((unsigned int) *(dataptr+2) <<8 ) +
139                   ((unsigned int) *(dataptr+3)     ) ;
140        dataptr+=4;
141        printf("  bytes in bitstream = %d\n", swapsize);
142
143        rc = fpga_load(dev, dataptr, swapsize);
144        return rc;
145#else
146        printf("Bitstream support only for Xilinx devices\n");
147        return FPGA_FAIL;
148#endif
149}
150
151/* ------------------------------------------------------------------------- */
152/* command form:
153 *   fpga <op> <device number> <data addr> <datasize>
154 * where op is 'load', 'dump', or 'info'
155 * If there is no device number field, the fpga environment variable is used.
156 * If there is no data addr field, the fpgadata environment variable is used.
157 * The info command requires no data address field.
158 */
159int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
160{
161        int op, dev = FPGA_INVALID_DEVICE;
162        size_t data_size = 0;
163        void *fpga_data = NULL;
164        char *devstr = getenv ("fpga");
165        char *datastr = getenv ("fpgadata");
166        int rc = FPGA_FAIL;
167#if defined (CONFIG_FIT)
168        const char *fit_uname = NULL;
169        ulong fit_addr;
170#endif
171
172        if (devstr)
173                dev = (int) simple_strtoul (devstr, NULL, 16);
174        if (datastr)
175                fpga_data = (void *) simple_strtoul (datastr, NULL, 16);
176
177        switch (argc) {
178        case 5:         /* fpga <op> <dev> <data> <datasize> */
179                data_size = simple_strtoul (argv[4], NULL, 16);
180
181        case 4:         /* fpga <op> <dev> <data> */
182#if defined(CONFIG_FIT)
183                if (fit_parse_subimage (argv[3], (ulong)fpga_data,
184                                        &fit_addr, &fit_uname)) {
185                        fpga_data = (void *)fit_addr;
186                        debug ("*  fpga: subimage '%s' from FIT image at 0x%08lx\n",
187                                        fit_uname, fit_addr);
188                } else
189#endif
190                {
191                        fpga_data = (void *) simple_strtoul (argv[3], NULL, 16);
192                        debug ("*  fpga: cmdline image address = 0x%08lx\n", (ulong)fpga_data);
193                }
194                PRINTF ("%s: fpga_data = 0x%x\n", __FUNCTION__, (uint) fpga_data);
195
196        case 3:         /* fpga <op> <dev | data addr> */
197                dev = (int) simple_strtoul (argv[2], NULL, 16);
198                PRINTF ("%s: device = %d\n", __FUNCTION__, dev);
199                /* FIXME - this is a really weak test */
200                if ((argc == 3) && (dev > fpga_count ())) {     /* must be buffer ptr */
201                        PRINTF ("%s: Assuming buffer pointer in arg 3\n",
202                                __FUNCTION__);
203
204#if defined(CONFIG_FIT)
205                        if (fit_parse_subimage (argv[2], (ulong)fpga_data,
206                                                &fit_addr, &fit_uname)) {
207                                fpga_data = (void *)fit_addr;
208                                debug ("*  fpga: subimage '%s' from FIT image at 0x%08lx\n",
209                                                fit_uname, fit_addr);
210                        } else
211#endif
212                        {
213                                fpga_data = (void *) dev;
214                                debug ("*  fpga: cmdline image address = 0x%08lx\n", (ulong)fpga_data);
215                        }
216
217                        PRINTF ("%s: fpga_data = 0x%x\n",
218                                __FUNCTION__, (uint) fpga_data);
219                        dev = FPGA_INVALID_DEVICE;      /* reset device num */
220                }
221
222        case 2:         /* fpga <op> */
223                op = (int) fpga_get_op (argv[1]);
224                break;
225
226        default:
227                PRINTF ("%s: Too many or too few args (%d)\n",
228                        __FUNCTION__, argc);
229                op = FPGA_NONE; /* force usage display */
230                break;
231        }
232
233        switch (op) {
234        case FPGA_NONE:
235                fpga_usage (cmdtp);
236                break;
237
238        case FPGA_INFO:
239                rc = fpga_info (dev);
240                break;
241
242        case FPGA_LOAD:
243                rc = fpga_load (dev, fpga_data, data_size);
244                break;
245
246        case FPGA_LOADB:
247                rc = fpga_loadbitstream(dev, fpga_data, data_size);
248                break;
249
250        case FPGA_LOADMK:
251                switch (genimg_get_format (fpga_data)) {
252                case IMAGE_FORMAT_LEGACY:
253                        {
254                                image_header_t *hdr = (image_header_t *)fpga_data;
255                                ulong   data;
256
257                                data = (ulong)image_get_data (hdr);
258                                data_size = image_get_data_size (hdr);
259                                rc = fpga_load (dev, (void *)data, data_size);
260                        }
261                        break;
262#if defined(CONFIG_FIT)
263                case IMAGE_FORMAT_FIT:
264                        {
265                                const void *fit_hdr = (const void *)fpga_data;
266                                int noffset;
267                                void *fit_data;
268
269                                if (fit_uname == NULL) {
270                                        puts ("No FIT subimage unit name\n");
271                                        return 1;
272                                }
273
274                                if (!fit_check_format (fit_hdr)) {
275                                        puts ("Bad FIT image format\n");
276                                        return 1;
277                                }
278
279                                /* get fpga component image node offset */
280                                noffset = fit_image_get_node (fit_hdr, fit_uname);
281                                if (noffset < 0) {
282                                        printf ("Can't find '%s' FIT subimage\n", fit_uname);
283                                        return 1;
284                                }
285
286                                /* verify integrity */
287                                if (!fit_image_check_hashes (fit_hdr, noffset)) {
288                                        puts ("Bad Data Hash\n");
289                                        return 1;
290                                }
291
292                                /* get fpga subimage data address and length */
293                                if (fit_image_get_data (fit_hdr, noffset, &fit_data, &data_size)) {
294                                        puts ("Could not find fpga subimage data\n");
295                                        return 1;
296                                }
297
298                                rc = fpga_load (dev, fit_data, data_size);
299                        }
300                        break;
301#endif
302                default:
303                        puts ("** Unknown image type\n");
304                        rc = FPGA_FAIL;
305                        break;
306                }
307                break;
308
309        case FPGA_DUMP:
310                rc = fpga_dump (dev, fpga_data, data_size);
311                break;
312
313        default:
314                printf ("Unknown operation\n");
315                fpga_usage (cmdtp);
316                break;
317        }
318        return (rc);
319}
320
321static void fpga_usage (cmd_tbl_t * cmdtp)
322{
323        printf ("Usage:\n%s\n", cmdtp->usage);
324}
325
326/*
327 * Map op to supported operations.  We don't use a table since we
328 * would just have to relocate it from flash anyway.
329 */
330static int fpga_get_op (char *opstr)
331{
332        int op = FPGA_NONE;
333
334        if (!strcmp ("info", opstr)) {
335                op = FPGA_INFO;
336        } else if (!strcmp ("loadb", opstr)) {
337                op = FPGA_LOADB;
338        } else if (!strcmp ("load", opstr)) {
339                op = FPGA_LOAD;
340        } else if (!strcmp ("loadmk", opstr)) {
341                op = FPGA_LOADMK;
342        } else if (!strcmp ("dump", opstr)) {
343                op = FPGA_DUMP;
344        }
345
346        if (op == FPGA_NONE) {
347                printf ("Unknown fpga operation \"%s\"\n", opstr);
348        }
349        return op;
350}
351
352U_BOOT_CMD (fpga, 6, 1, do_fpga,
353            "fpga    - loadable FPGA image support\n",
354            "fpga [operation type] [device number] [image address] [image size]\n"
355            "fpga operations:\n"
356            "\tinfo\tlist known device information\n"
357            "\tload\tLoad device from memory buffer\n"
358            "\tloadb\tLoad device from bitstream buffer (Xilinx devices only)\n"
359            "\tloadmk\tLoad device generated with mkimage\n"
360            "\tdump\tLoad device to memory buffer\n"
361#if defined(CONFIG_FIT)
362            "\tFor loadmk operating on FIT format uImage address must include\n"
363            "\tsubimage unit name in the form of addr:<subimg_uname>\n"
364#endif
365);
Note: See TracBrowser for help on using the repository browser.