1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
4 * Xilinx programming commands File: ui_xilinx.c
6 * Some routines to program on-board xilinxes.
8 * Author: Mitch Lichtenberg (mpl@broadcom.com)
10 *********************************************************************
12 * Copyright 2000,2001,2002,2003
13 * Broadcom Corporation. All rights reserved.
15 * This software is furnished under license and may be used and
16 * copied only in accordance with the following terms and
17 * conditions. Subject to these conditions, you may download,
18 * copy, install, use, modify and distribute modified or unmodified
19 * copies of this software in source and/or binary form. No title
20 * or ownership is transferred hereby.
22 * 1) Any source code used, modified or distributed must reproduce
23 * and retain this copyright notice and list of conditions
24 * as they appear in the source file.
26 * 2) No right is granted to use any trade name, trademark, or
27 * logo of Broadcom Corporation. The "Broadcom Corporation"
28 * name may not be used to endorse or promote products derived
29 * from this software without the prior written permission of
30 * Broadcom Corporation.
32 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
33 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
34 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
35 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
36 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
37 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
38 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
40 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
41 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
42 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
43 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
44 * THE POSSIBILITY OF SUCH DAMAGE.
45 ********************************************************************* */
47 #include "lib_types.h"
48 #include "lib_printf.h"
49 #include "lib_string.h"
50 #include "ui_command.h"
53 #include "cfe_device.h"
54 #include "cfe_console.h"
55 #include "cfe_devfuncs.h"
58 #include <sb1250-include/sb1250_regs.h>
61 #include "cfe_flashimage.h"
62 #include "carmel_env.h"
64 /* *********************************************************************
66 ********************************************************************* */
68 xpgminfo_t xilinxinfo
= {
78 xpgminfo_t xilinxinfo_convoluted
= {
88 #define XILINX_STAGING_BUFFER (256*1024)
89 #define XILINX_DEVICE_SIZE 130012
91 #define FPGA_IMAGE_SEAL "FPGA"
93 /* *********************************************************************
95 ********************************************************************* */
97 static int ui_cmd_xload(ui_cmdline_t
*cmd
,int argc
,char *argv
[]) ;
98 static int ui_cmd_xlist(ui_cmdline_t
*cmd
,int argc
,char *argv
[]) ;
99 int ui_init_xpgmcmds(void);
101 static char *xload_devname
= "flash0.fpga";
103 /* *********************************************************************
106 * Add Xilinx commands to the command table
113 ********************************************************************* */
116 int ui_init_xpgmcmds(void)
121 "Load a bitstream stored in a flash device into the Xilinx FPGA",
123 "By default, xload loads the appropriate bitstream according to data\n"
124 "in the ID EEPROM. xload first looks at M_FPGA, and then looks\n"
125 "at M_BOARDTYPE to determine the key.\n",
131 "List Xilinx bitstreams stored in flash.",
137 static int ui_cmd_xlist(ui_cmdline_t
*cmd
,int argc
,char *argv
[])
140 cfe_flashimage_t header
;
141 cfe_offset_t offset
= 0;
147 fh
= cfe_open(xload_devname
);
148 if (fh
< 0) return ui_showerror(fh
,"Could not open device %s",xload_devname
);
151 res
= cfe_readblk(fh
,offset
,(unsigned char *)&header
,sizeof(header
));
152 if (res
!= sizeof(header
)) break;
154 if (memcmp(header
.seal
,FPGA_IMAGE_SEAL
,4) != 0) break;
156 len
= ((uint32_t) header
.size
[0] << 24) |
157 ((uint32_t) header
.size
[1] << 16) |
158 ((uint32_t) header
.size
[2] << 8) |
159 ((uint32_t) header
.size
[3] << 0);
161 offset
+= sizeof(header
);
166 printf("FPGA Key Version Size\n");
167 printf("---------------- -------- ------\n");
170 sprintf(vbuf
,"%d.%d.%d",header
.majver
,header
.minver
,header
.ecover
);
171 printf("%16s %8s %d\n",header
.boardname
,vbuf
,len
);
176 if (cnt
== 0) printf("No FPGA bitstreams found on device %s\n",xload_devname
);
183 /* *********************************************************************
184 * fpga_crc32(buf,len)
186 * Yes, this is an Ethernet CRC. I'm lazy.
189 * buf - buffer to CRC
190 * len - length of data
194 ********************************************************************* */
196 #define CRC32_POLY 0xEDB88320UL /* CRC-32 Poly */
198 fpga_crc32(const unsigned char *databuf
, unsigned int datalen
)
200 unsigned int idx
, bit
, data
, crc
= 0xFFFFFFFFUL
;
202 for (idx
= 0; idx
< datalen
; idx
++) {
203 for (data
= *databuf
++, bit
= 0; bit
< 8; bit
++, data
>>= 1) {
204 crc
= (crc
>> 1) ^ (((crc
^ data
) & 1) ? CRC32_POLY
: 0);
211 static int ui_cmd_xload(ui_cmdline_t
*cmd
,int argc
,char *argv
[])
213 uint8_t *xbuffer
= (uint8_t *) PHYS_TO_K0(XILINX_STAGING_BUFFER
);
215 uint32_t hdrcrc
,calccrc
;
218 cfe_flashimage_t header
;
219 cfe_offset_t offset
= 0;
225 key
= cmd_getarg(cmd
,0);
227 key
= carmel_getenv("M_FPGA");
228 if (!key
) key
= carmel_getenv("M_BOARDTYPE");
230 printf("Cannot determine which FPGA to load. Use 'xlist' for a list of available FPGAs.\n\n");
231 return ui_showusage(cmd
);
235 fh
= cfe_open(xload_devname
);
236 if (fh
< 0) return ui_showerror(fh
,"Could not open device %s",xload_devname
);
242 res
= cfe_readblk(fh
,offset
,(unsigned char *)&header
,sizeof(header
));
243 if (res
!= sizeof(header
)) break;
245 if (memcmp(header
.seal
,FPGA_IMAGE_SEAL
,4) != 0) break;
247 len
= ((uint32_t) header
.size
[0] << 24) |
248 ((uint32_t) header
.size
[1] << 16) |
249 ((uint32_t) header
.size
[2] << 8) |
250 ((uint32_t) header
.size
[3] << 0);
252 hdrcrc
= ((uint32_t) header
.crc
[0] << 24) |
253 ((uint32_t) header
.crc
[1] << 16) |
254 ((uint32_t) header
.crc
[2] << 8) |
255 ((uint32_t) header
.crc
[3] << 0);
257 offset
+= sizeof(header
);
261 if (strcmpi(header
.boardname
,key
) == 0) {
270 printf("Cannot find FPGA key '%s' in device '%s'\n",key
,xload_devname
);
275 res
= cfe_readblk(fh
,offset
,xbuffer
,len
);
277 printf("Could not read data from device %s\n",xload_devname
);
284 calccrc
= fpga_crc32(xbuffer
,len
);
285 if (calccrc
!= hdrcrc
) {
286 printf("FPGA CRC does not match header. FPGA image may be invalid.\n");
289 xilinx
= &xilinxinfo
;
290 conv
= carmel_getenv("M_FPGACONVOLUTED");
291 if (conv
&& (strcmp(conv
,"YES") == 0)) xilinx
= &xilinxinfo_convoluted
;
293 res
= xilinx_program(xilinx
,xbuffer
,len
*8);
296 printf("Xilinx programming failure: ");
299 case XPGM_ERR_INIT_NEVER_LOW
:
300 printf("INIT never went low\n");
302 case XPGM_ERR_INIT_NEVER_HIGH
:
303 printf("INIT never went high\n");
305 case XPGM_ERR_INIT_NOT_HIGH
:
306 printf("INIT not high\n");
308 case XPGM_ERR_DONE_NOT_HIGH
:
309 printf("DONE not high\n");
311 case XPGM_ERR_OPEN_FAILED
:
312 printf("OPEN failed\n");
314 case XPGM_ERR_CLOSE_FAILED
:
315 printf("CLOSE failed\n");
320 return (res
< 0) ? -1 : 0;