2 * (C) Copyright 2000, 2001
3 * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
5 * See file CREDITS for list of people who contributed to this
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.
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.
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,
30 #if defined(CONFIG_CMD_NET)
41 #define PRINTF(fmt,args...) printf (fmt ,##args)
43 #define PRINTF(fmt,args...)
46 #if defined (CONFIG_FPGA) && defined(CONFIG_CMD_FPGA)
49 static void fpga_usage (cmd_tbl_t * cmdtp);
50 static int fpga_get_op (char *opstr);
60 /* Convert bitstream data and load into the fpga */
61 int fpga_loadbitstream(unsigned long dev, char* fpgadata, size_t size)
64 unsigned char* swapdata;
65 unsigned int swapsize;
68 unsigned char *dataptr;
73 dataptr = (unsigned char *)fpgadata;
76 /* skip the first bytes of the bitsteam, their meaning is unknown */
77 length = (*dataptr << 8) + *(dataptr+1);
81 /* get design name (identifier, length, string) */
82 length = (*dataptr << 8) + *(dataptr+1);
84 if (*dataptr++ != 0x61) {
85 PRINTF ("%s: Design name identifier not recognized in bitstream\n",
90 length = (*dataptr << 8) + *(dataptr+1);
95 printf(" design filename = \"%s\"\n", buffer);
97 /* get part number (identifier, length, string) */
98 if (*dataptr++ != 0x62) {
99 printf("%s: Part number identifier not recognized in bitstream\n",
104 length = (*dataptr << 8) + *(dataptr+1);
106 for(i=0;i<length;i++)
107 buffer[i]=*dataptr++;
108 printf(" part number = \"%s\"\n", buffer);
110 /* get date (identifier, length, string) */
111 if (*dataptr++ != 0x63) {
112 printf("%s: Date identifier not recognized in bitstream\n",
117 length = (*dataptr << 8) + *(dataptr+1);
119 for(i=0;i<length;i++)
120 buffer[i]=*dataptr++;
121 printf(" date = \"%s\"\n", buffer);
123 /* get time (identifier, length, string) */
124 if (*dataptr++ != 0x64) {
125 printf("%s: Time identifier not recognized in bitstream\n",__FUNCTION__);
129 length = (*dataptr << 8) + *(dataptr+1);
131 for(i=0;i<length;i++)
132 buffer[i]=*dataptr++;
133 printf(" time = \"%s\"\n", buffer);
135 /* get fpga data length (identifier, length) */
136 if (*dataptr++ != 0x65) {
137 printf("%s: Data length identifier not recognized in bitstream\n",
141 swapsize = ((unsigned int) *dataptr <<24) +
142 ((unsigned int) *(dataptr+1) <<16) +
143 ((unsigned int) *(dataptr+2) <<8 ) +
144 ((unsigned int) *(dataptr+3) ) ;
146 printf(" bytes in bitstream = %d\n", swapsize);
148 /* check consistency of length obtained */
149 if (swapsize >= size) {
150 printf("%s: Could not find right length of data in bitstream\n",
155 /* allocate memory */
156 swapdata = (unsigned char *)malloc(swapsize);
157 if (swapdata == NULL) {
158 printf("%s: Could not allocate %d bytes memory !\n",
159 __FUNCTION__, swapsize);
163 /* read data into memory and swap bits */
165 for (i = 0; i < swapsize; i++) {
167 data |= (*dataptr & 0x01) << 7;
168 data |= (*dataptr & 0x02) << 5;
169 data |= (*dataptr & 0x04) << 3;
170 data |= (*dataptr & 0x08) << 1;
171 data |= (*dataptr & 0x10) >> 1;
172 data |= (*dataptr & 0x20) >> 3;
173 data |= (*dataptr & 0x40) >> 5;
174 data |= (*dataptr & 0x80) >> 7;
179 rc = fpga_load(dev, swapdata, swapsize);
183 printf("Bitstream support only for Xilinx devices\n");
188 /* ------------------------------------------------------------------------- */
190 * fpga <op> <device number> <data addr> <datasize>
191 * where op is 'load', 'dump', or 'info'
192 * If there is no device number field, the fpga environment variable is used.
193 * If there is no data addr field, the fpgadata environment variable is used.
194 * The info command requires no data address field.
196 int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
198 int op, dev = FPGA_INVALID_DEVICE;
199 size_t data_size = 0;
200 void *fpga_data = NULL;
201 char *devstr = getenv ("fpga");
202 char *datastr = getenv ("fpgadata");
206 dev = (int) simple_strtoul (devstr, NULL, 16);
208 fpga_data = (void *) simple_strtoul (datastr, NULL, 16);
211 case 5: /* fpga <op> <dev> <data> <datasize> */
212 data_size = simple_strtoul (argv[4], NULL, 16);
213 case 4: /* fpga <op> <dev> <data> */
214 fpga_data = (void *) simple_strtoul (argv[3], NULL, 16);
215 PRINTF ("%s: fpga_data = 0x%x\n", __FUNCTION__, (uint) fpga_data);
216 case 3: /* fpga <op> <dev | data addr> */
217 dev = (int) simple_strtoul (argv[2], NULL, 16);
218 PRINTF ("%s: device = %d\n", __FUNCTION__, dev);
219 /* FIXME - this is a really weak test */
220 if ((argc == 3) && (dev > fpga_count ())) { /* must be buffer ptr */
221 PRINTF ("%s: Assuming buffer pointer in arg 3\n",
223 fpga_data = (void *) dev;
224 PRINTF ("%s: fpga_data = 0x%x\n",
225 __FUNCTION__, (uint) fpga_data);
226 dev = FPGA_INVALID_DEVICE; /* reset device num */
228 case 2: /* fpga <op> */
229 op = (int) fpga_get_op (argv[1]);
232 PRINTF ("%s: Too many or too few args (%d)\n",
234 op = FPGA_NONE; /* force usage display */
244 rc = fpga_info (dev);
248 rc = fpga_load (dev, fpga_data, data_size);
252 rc = fpga_loadbitstream(dev, fpga_data, data_size);
257 image_header_t header;
258 image_header_t *hdr = &header;
261 memmove (&header, (char *)fpga_data, sizeof(image_header_t));
262 if (ntohl(hdr->ih_magic) != IH_MAGIC) {
263 puts ("Bad Magic Number\n");
266 data = ((ulong)fpga_data + sizeof(image_header_t));
267 data_size = ntohl(hdr->ih_size);
268 rc = fpga_load (dev, (void *)data, data_size);
273 rc = fpga_dump (dev, fpga_data, data_size);
277 printf ("Unknown operation\n");
284 static void fpga_usage (cmd_tbl_t * cmdtp)
286 printf ("Usage:\n%s\n", cmdtp->usage);
290 * Map op to supported operations. We don't use a table since we
291 * would just have to relocate it from flash anyway.
293 static int fpga_get_op (char *opstr)
297 if (!strcmp ("info", opstr)) {
299 } else if (!strcmp ("loadb", opstr)) {
301 } else if (!strcmp ("load", opstr)) {
303 } else if (!strcmp ("loadmk", opstr)) {
305 } else if (!strcmp ("dump", opstr)) {
309 if (op == FPGA_NONE) {
310 printf ("Unknown fpga operation \"%s\"\n", opstr);
315 U_BOOT_CMD (fpga, 6, 1, do_fpga,
316 "fpga - loadable FPGA image support\n",
317 "fpga [operation type] [device number] [image address] [image size]\n"
319 "\tinfo\tlist known device information\n"
320 "\tload\tLoad device from memory buffer\n"
321 "\tloadb\tLoad device from bitstream buffer (Xilinx devices only)\n"
322 "\tloadmk\tLoad device generated with mkimage\n"
323 "\tdump\tLoad device to memory buffer\n");