RT-AC66 3.0.0.4.374.130 core
[tomato.git] / release / src-rt-6.x / cfe / cfe / arch / mips / board / carmel / src / ui_xilinx.c
blob1c6ff8798ee9418844ac6d66f4f768ed9b58c4d1
1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
3 *
4 * Xilinx programming commands File: ui_xilinx.c
5 *
6 * Some routines to program on-board xilinxes.
7 *
8 * Author: Mitch Lichtenberg (mpl@broadcom.com)
9 *
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"
51 #include "cfe.h"
52 #include "cfe_iocb.h"
53 #include "cfe_device.h"
54 #include "cfe_console.h"
55 #include "cfe_devfuncs.h"
57 #include "sbmips.h"
58 #include <sb1250-include/sb1250_regs.h>
59 #include "carmel.h"
60 #include "xilinx.h"
61 #include "cfe_flashimage.h"
62 #include "carmel_env.h"
64 /* *********************************************************************
65 * Globals
66 ********************************************************************* */
68 xpgminfo_t xilinxinfo = {
69 M_GPIO_FPGA_INIT,
70 M_GPIO_FPGA_DONE,
71 M_GPIO_FPGA_PGM,
72 M_GPIO_FPGA_DIN,
73 M_GPIO_FPGA_DOUT,
74 M_GPIO_FPGA_CCLK,
78 xpgminfo_t xilinxinfo_convoluted = {
79 M_GPIO_FPGACONV_INIT,
80 M_GPIO_FPGACONV_DONE,
81 M_GPIO_FPGACONV_PGM,
82 M_GPIO_FPGACONV_DIN,
84 M_GPIO_FPGACONV_CCLK,
88 #define XILINX_STAGING_BUFFER (256*1024)
89 #define XILINX_DEVICE_SIZE 130012
91 #define FPGA_IMAGE_SEAL "FPGA"
93 /* *********************************************************************
94 * prototypes
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 /* *********************************************************************
104 * ui_init_xpgmcmds()
106 * Add Xilinx commands to the command table
108 * Input parameters:
109 * nothing
111 * Return value:
113 ********************************************************************* */
116 int ui_init_xpgmcmds(void)
118 cmd_addcmd("xload",
119 ui_cmd_xload,
120 NULL,
121 "Load a bitstream stored in a flash device into the Xilinx FPGA",
122 "xload [key]\n\n"
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",
126 "");
128 cmd_addcmd("xlist",
129 ui_cmd_xlist,
130 NULL,
131 "List Xilinx bitstreams stored in flash.",
132 "xlist",
133 "");
134 return 0;
137 static int ui_cmd_xlist(ui_cmdline_t *cmd,int argc,char *argv[])
139 int fh;
140 cfe_flashimage_t header;
141 cfe_offset_t offset = 0;
142 int res;
143 uint32_t len;
144 int cnt = 0;
145 char vbuf[32];
147 fh = cfe_open(xload_devname);
148 if (fh < 0) return ui_showerror(fh,"Could not open device %s",xload_devname);
150 for (;;) {
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);
163 if (len == 0) break;
165 if (cnt == 0) {
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);
172 cnt++;
173 offset += len;
176 if (cnt == 0) printf("No FPGA bitstreams found on device %s\n",xload_devname);
178 cfe_close(fh);
179 return 0;
183 /* *********************************************************************
184 * fpga_crc32(buf,len)
186 * Yes, this is an Ethernet CRC. I'm lazy.
188 * Input parameters:
189 * buf - buffer to CRC
190 * len - length of data
192 * Return value:
193 * CRC-32
194 ********************************************************************* */
196 #define CRC32_POLY 0xEDB88320UL /* CRC-32 Poly */
197 static unsigned int
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);
208 return crc;
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);
214 int res;
215 uint32_t hdrcrc,calccrc;
216 int found = 0;
217 int fh;
218 cfe_flashimage_t header;
219 cfe_offset_t offset = 0;
220 uint32_t len;
221 char *key;
222 char *conv;
223 xpgminfo_t *xilinx;
225 key = cmd_getarg(cmd,0);
226 if (!key) {
227 key = carmel_getenv("M_FPGA");
228 if (!key) key = carmel_getenv("M_BOARDTYPE");
229 if (!key) {
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);
238 len = 0;
239 hdrcrc = 0;
241 for (;;) {
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);
259 if (len == 0) break;
261 if (strcmpi(header.boardname,key) == 0) {
262 found = 1;
263 break;
265 offset += len;
269 if (!found) {
270 printf("Cannot find FPGA key '%s' in device '%s'\n",key,xload_devname);
271 cfe_close(fh);
272 return -1;
275 res = cfe_readblk(fh,offset,xbuffer,len);
276 if (res != len) {
277 printf("Could not read data from device %s\n",xload_devname);
278 cfe_close(fh);
279 return -1;
282 cfe_close(fh);
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);
295 if (res < 0) {
296 printf("Xilinx programming failure: ");
298 switch (res) {
299 case XPGM_ERR_INIT_NEVER_LOW:
300 printf("INIT never went low\n");
301 break;
302 case XPGM_ERR_INIT_NEVER_HIGH:
303 printf("INIT never went high\n");
304 break;
305 case XPGM_ERR_INIT_NOT_HIGH:
306 printf("INIT not high\n");
307 break;
308 case XPGM_ERR_DONE_NOT_HIGH:
309 printf("DONE not high\n");
310 break;
311 case XPGM_ERR_OPEN_FAILED:
312 printf("OPEN failed\n");
313 break;
314 case XPGM_ERR_CLOSE_FAILED:
315 printf("CLOSE failed\n");
316 break;
320 return (res < 0) ? -1 : 0;