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...)
47 static void fpga_usage (cmd_tbl_t * cmdtp);
48 static int fpga_get_op (char *opstr);
58 /* Convert bitstream data and load into the fpga */
59 int fpga_loadbitstream(unsigned long dev, char* fpgadata, size_t size)
61 #if (CONFIG_FPGA & CFG_FPGA_XILINX)
63 unsigned char* swapdata;
64 unsigned int swapsize;
67 unsigned char *dataptr;
72 dataptr = (unsigned char *)fpgadata;
74 /* skip the first bytes of the bitsteam, their meaning is unknown */
75 length = (*dataptr << 8) + *(dataptr+1);
79 /* get design name (identifier, length, string) */
80 length = (*dataptr << 8) + *(dataptr+1);
82 if (*dataptr++ != 0x61) {
83 PRINTF ("%s: Design name identifier not recognized in bitstream\n",
88 length = (*dataptr << 8) + *(dataptr+1);
93 printf(" design filename = \"%s\"\n", buffer);
95 /* get part number (identifier, length, string) */
96 if (*dataptr++ != 0x62) {
97 printf("%s: Part number identifier not recognized in bitstream\n",
102 length = (*dataptr << 8) + *(dataptr+1);
104 for(i=0;i<length;i++)
105 buffer[i]=*dataptr++;
106 printf(" part number = \"%s\"\n", buffer);
108 /* get date (identifier, length, string) */
109 if (*dataptr++ != 0x63) {
110 printf("%s: Date identifier not recognized in bitstream\n",
115 length = (*dataptr << 8) + *(dataptr+1);
117 for(i=0;i<length;i++)
118 buffer[i]=*dataptr++;
119 printf(" date = \"%s\"\n", buffer);
121 /* get time (identifier, length, string) */
122 if (*dataptr++ != 0x64) {
123 printf("%s: Time identifier not recognized in bitstream\n",__FUNCTION__);
127 length = (*dataptr << 8) + *(dataptr+1);
129 for(i=0;i<length;i++)
130 buffer[i]=*dataptr++;
131 printf(" time = \"%s\"\n", buffer);
133 /* get fpga data length (identifier, length) */
134 if (*dataptr++ != 0x65) {
135 printf("%s: Data length identifier not recognized in bitstream\n",
139 swapsize = ((unsigned int) *dataptr <<24) +
140 ((unsigned int) *(dataptr+1) <<16) +
141 ((unsigned int) *(dataptr+2) <<8 ) +
142 ((unsigned int) *(dataptr+3) ) ;
144 printf(" bytes in bitstream = %d\n", swapsize);
146 /* check consistency of length obtained */
147 if (swapsize >= size) {
148 printf("%s: Could not find right length of data in bitstream\n",
153 /* allocate memory */
154 swapdata = (unsigned char *)malloc(swapsize);
155 if (swapdata == NULL) {
156 printf("%s: Could not allocate %d bytes memory !\n",
157 __FUNCTION__, swapsize);
161 /* read data into memory and swap bits */
163 for (i = 0; i < swapsize; i++) {
165 data |= (*dataptr & 0x01) << 7;
166 data |= (*dataptr & 0x02) << 5;
167 data |= (*dataptr & 0x04) << 3;
168 data |= (*dataptr & 0x08) << 1;
169 data |= (*dataptr & 0x10) >> 1;
170 data |= (*dataptr & 0x20) >> 3;
171 data |= (*dataptr & 0x40) >> 5;
172 data |= (*dataptr & 0x80) >> 7;
177 rc = fpga_load(dev, swapdata, swapsize);
181 printf("Bitstream support only for Xilinx devices\n");
186 /* ------------------------------------------------------------------------- */
188 * fpga <op> <device number> <data addr> <datasize>
189 * where op is 'load', 'dump', or 'info'
190 * If there is no device number field, the fpga environment variable is used.
191 * If there is no data addr field, the fpgadata environment variable is used.
192 * The info command requires no data address field.
194 int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
196 int op, dev = FPGA_INVALID_DEVICE;
197 size_t data_size = 0;
198 void *fpga_data = NULL;
199 char *devstr = getenv ("fpga");
200 char *datastr = getenv ("fpgadata");
204 dev = (int) simple_strtoul (devstr, NULL, 16);
206 fpga_data = (void *) simple_strtoul (datastr, NULL, 16);
209 case 5: /* fpga <op> <dev> <data> <datasize> */
210 data_size = simple_strtoul (argv[4], NULL, 16);
211 case 4: /* fpga <op> <dev> <data> */
212 fpga_data = (void *) simple_strtoul (argv[3], NULL, 16);
213 PRINTF ("%s: fpga_data = 0x%x\n", __FUNCTION__, (uint) fpga_data);
214 case 3: /* fpga <op> <dev | data addr> */
215 dev = (int) simple_strtoul (argv[2], NULL, 16);
216 PRINTF ("%s: device = %d\n", __FUNCTION__, dev);
217 /* FIXME - this is a really weak test */
218 if ((argc == 3) && (dev > fpga_count ())) { /* must be buffer ptr */
219 PRINTF ("%s: Assuming buffer pointer in arg 3\n",
221 fpga_data = (void *) dev;
222 PRINTF ("%s: fpga_data = 0x%x\n",
223 __FUNCTION__, (uint) fpga_data);
224 dev = FPGA_INVALID_DEVICE; /* reset device num */
226 case 2: /* fpga <op> */
227 op = (int) fpga_get_op (argv[1]);
230 PRINTF ("%s: Too many or too few args (%d)\n",
232 op = FPGA_NONE; /* force usage display */
242 rc = fpga_info (dev);
246 rc = fpga_load (dev, fpga_data, data_size);
250 rc = fpga_loadbitstream(dev, fpga_data, data_size);
255 image_header_t header;
256 image_header_t *hdr = &header;
259 memmove (&header, (char *)fpga_data, sizeof(image_header_t));
260 if (ntohl(hdr->ih_magic) != IH_MAGIC) {
261 puts ("Bad Magic Number\n");
264 data = ((ulong)fpga_data + sizeof(image_header_t));
265 data_size = ntohl(hdr->ih_size);
266 rc = fpga_load (dev, (void *)data, data_size);
271 rc = fpga_dump (dev, fpga_data, data_size);
275 printf ("Unknown operation\n");
282 static void fpga_usage (cmd_tbl_t * cmdtp)
284 printf ("Usage:\n%s\n", cmdtp->usage);
288 * Map op to supported operations. We don't use a table since we
289 * would just have to relocate it from flash anyway.
291 static int fpga_get_op (char *opstr)
295 if (!strcmp ("info", opstr)) {
297 } else if (!strcmp ("loadb", opstr)) {
299 } else if (!strcmp ("load", opstr)) {
301 } else if (!strcmp ("loadmk", opstr)) {
303 } else if (!strcmp ("dump", opstr)) {
307 if (op == FPGA_NONE) {
308 printf ("Unknown fpga operation \"%s\"\n", opstr);
313 U_BOOT_CMD (fpga, 6, 1, do_fpga,
314 "fpga - loadable FPGA image support\n",
315 "fpga [operation type] [device number] [image address] [image size]\n"
317 "\tinfo\tlist known device information\n"
318 "\tload\tLoad device from memory buffer\n"
319 "\tloadb\tLoad device from bitstream buffer (Xilinx devices only)\n"
320 "\tloadmk\tLoad device generated with mkimage\n"
321 "\tdump\tLoad device to memory buffer\n");