]> git.sur5r.net Git - u-boot/blob - common/cmd_fpga.c
* Patch by Andreas Engel, 12 Jul 2004:
[u-boot] / common / cmd_fpga.c
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 (CONFIG_COMMANDS & CFG_CMD_NET)
31 #include <net.h>
32 #endif
33 #include <fpga.h>
34
35 #if 0
36 #define FPGA_DEBUG
37 #endif
38
39 #ifdef  FPGA_DEBUG
40 #define PRINTF(fmt,args...)     printf (fmt ,##args)
41 #else
42 #define PRINTF(fmt,args...)
43 #endif
44
45 #if defined (CONFIG_FPGA) && ( CONFIG_COMMANDS & CFG_CMD_FPGA )
46
47 /* Local functions */
48 static void fpga_usage (cmd_tbl_t * cmdtp);
49 static int fpga_get_op (char *opstr);
50
51 /* Local defines */
52 #define FPGA_NONE   -1
53 #define FPGA_INFO   0
54 #define FPGA_LOAD   1
55 #define FPGA_DUMP   3
56
57 /* ------------------------------------------------------------------------- */
58 /* command form:
59  *   fpga <op> <device number> <data addr> <datasize>
60  * where op is 'load', 'dump', or 'info'
61  * If there is no device number field, the fpga environment variable is used.
62  * If there is no data addr field, the fpgadata environment variable is used.
63  * The info command requires no data address field.
64  */
65 int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
66 {
67         int op, dev = FPGA_INVALID_DEVICE;
68         size_t data_size = 0;
69         void *fpga_data = NULL;
70         char *devstr = getenv ("fpga");
71         char *datastr = getenv ("fpgadata");
72         int rc = FPGA_FAIL;
73
74         if (devstr)
75                 dev = (int) simple_strtoul (devstr, NULL, 16);
76         if (datastr)
77                 fpga_data = (void *) simple_strtoul (datastr, NULL, 16);
78
79         switch (argc) {
80         case 5:         /* fpga <op> <dev> <data> <datasize> */
81                 data_size = simple_strtoul (argv[4], NULL, 16);
82         case 4:         /* fpga <op> <dev> <data> */
83                 fpga_data = (void *) simple_strtoul (argv[3], NULL, 16);
84                 PRINTF (__FUNCTION__ ": fpga_data = 0x%x\n",
85                         (uint) fpga_data);
86         case 3:         /* fpga <op> <dev | data addr> */
87                 dev = (int) simple_strtoul (argv[2], NULL, 16);
88                 PRINTF (__FUNCTION__ ": device = %d\n", dev);
89                 /* FIXME - this is a really weak test */
90                 if ((argc == 3) && (dev > fpga_count ())) {     /* must be buffer ptr */
91                         PRINTF (__FUNCTION__
92                                 ": Assuming buffer pointer in arg 3\n");
93                         fpga_data = (void *) dev;
94                         PRINTF (__FUNCTION__ ": fpga_data = 0x%x\n",
95                                 (uint) fpga_data);
96                         dev = FPGA_INVALID_DEVICE;      /* reset device num */
97                 }
98         case 2:         /* fpga <op> */
99                 op = (int) fpga_get_op (argv[1]);
100                 break;
101         default:
102                 PRINTF (__FUNCTION__ ": Too many or too few args (%d)\n",
103                         argc);
104                 op = FPGA_NONE; /* force usage display */
105                 break;
106         }
107
108         switch (op) {
109         case FPGA_NONE:
110                 fpga_usage (cmdtp);
111                 break;
112
113         case FPGA_INFO:
114                 rc = fpga_info (dev);
115                 break;
116
117         case FPGA_LOAD:
118                 rc = fpga_load (dev, fpga_data, data_size);
119                 break;
120
121         case FPGA_DUMP:
122                 rc = fpga_dump (dev, fpga_data, data_size);
123                 break;
124
125         default:
126                 printf ("Unknown operation.\n");
127                 fpga_usage (cmdtp);
128                 break;
129         }
130         return (rc);
131 }
132
133 static void fpga_usage (cmd_tbl_t * cmdtp)
134 {
135         printf ("Usage:\n%s\n", cmdtp->usage);
136 }
137
138 /*
139  * Map op to supported operations.  We don't use a table since we
140  * would just have to relocate it from flash anyway.
141  */
142 static int fpga_get_op (char *opstr)
143 {
144         int op = FPGA_NONE;
145
146         if (!strcmp ("info", opstr)) {
147                 op = FPGA_INFO;
148         } else if (!strcmp ("load", opstr)) {
149                 op = FPGA_LOAD;
150         } else if (!strcmp ("dump", opstr)) {
151                 op = FPGA_DUMP;
152         }
153
154         if (op == FPGA_NONE) {
155                 printf ("Unknown fpga operation \"%s\"\n", opstr);
156         }
157         return op;
158 }
159
160 U_BOOT_CMD (fpga, 6, 1, do_fpga,
161             "fpga    - loadable FPGA image support\n",
162             "fpga [operation type] [device number] [image address] [image size]\n"
163             "fpga operations:\n"
164             "\tinfo\tlist known device information.\n"
165             "\tload\tLoad device from memory buffer.\n"
166             "\tdump\tLoad device to memory buffer.\n");
167 #endif /* CONFIG_FPGA && CONFIG_COMMANDS & CFG_CMD_FPGA */