Blame view
common/cmd_fpga.c
6.7 KB
4a9cbbe83 Initial revision |
1 2 3 4 |
/* * (C) Copyright 2000, 2001 * Rich Ireland, Enterasys Networks, rireland@enterasys.com. * |
1a4596601 Add GPL-2.0+ SPDX... |
5 |
* SPDX-License-Identifier: GPL-2.0+ |
4a9cbbe83 Initial revision |
6 7 8 9 10 11 12 |
*/ /* * FPGA support */ #include <common.h> #include <command.h> |
8bde7f776 * Code cleanup: |
13 |
#include <fpga.h> |
c3d2b4b48 Code cleanup. |
14 |
#include <malloc.h> |
4a9cbbe83 Initial revision |
15 |
|
4a9cbbe83 Initial revision |
16 |
/* Local functions */ |
fc598412c cmd: fpga: Clean ... |
17 |
static int fpga_get_op(char *opstr); |
4a9cbbe83 Initial revision |
18 19 20 21 22 |
/* Local defines */ #define FPGA_NONE -1 #define FPGA_INFO 0 #define FPGA_LOAD 1 |
30ce5ab04 * Patch by Gleb N... |
23 |
#define FPGA_LOADB 2 |
4a9cbbe83 Initial revision |
24 |
#define FPGA_DUMP 3 |
f0ff4692f Add FPGA Altera C... |
25 |
#define FPGA_LOADMK 4 |
4a9cbbe83 Initial revision |
26 27 28 29 30 31 32 33 34 |
/* ------------------------------------------------------------------------- */ /* command form: * fpga <op> <device number> <data addr> <datasize> * where op is 'load', 'dump', or 'info' * If there is no device number field, the fpga environment variable is used. * If there is no data addr field, the fpgadata environment variable is used. * The info command requires no data address field. */ |
fc598412c cmd: fpga: Clean ... |
35 |
int do_fpga(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) |
4a9cbbe83 Initial revision |
36 |
{ |
d4ca31c40 * Cleanup lowboot... |
37 38 39 |
int op, dev = FPGA_INVALID_DEVICE; size_t data_size = 0; void *fpga_data = NULL; |
fc598412c cmd: fpga: Clean ... |
40 41 |
char *devstr = getenv("fpga"); char *datastr = getenv("fpgadata"); |
d4ca31c40 * Cleanup lowboot... |
42 |
int rc = FPGA_FAIL; |
a790b5b23 cmd_fpga: cleanup... |
43 |
int wrong_parms = 0; |
fc598412c cmd: fpga: Clean ... |
44 |
#if defined(CONFIG_FIT) |
c28c4d193 [new uImage] Add ... |
45 46 47 |
const char *fit_uname = NULL; ulong fit_addr; #endif |
d4ca31c40 * Cleanup lowboot... |
48 49 |
if (devstr) |
fc598412c cmd: fpga: Clean ... |
50 |
dev = (int) simple_strtoul(devstr, NULL, 16); |
d4ca31c40 * Cleanup lowboot... |
51 |
if (datastr) |
fc598412c cmd: fpga: Clean ... |
52 |
fpga_data = (void *)simple_strtoul(datastr, NULL, 16); |
d4ca31c40 * Cleanup lowboot... |
53 54 55 |
switch (argc) { case 5: /* fpga <op> <dev> <data> <datasize> */ |
fc598412c cmd: fpga: Clean ... |
56 |
data_size = simple_strtoul(argv[4], NULL, 16); |
c28c4d193 [new uImage] Add ... |
57 |
|
d4ca31c40 * Cleanup lowboot... |
58 |
case 4: /* fpga <op> <dev> <data> */ |
c28c4d193 [new uImage] Add ... |
59 |
#if defined(CONFIG_FIT) |
fc598412c cmd: fpga: Clean ... |
60 61 |
if (fit_parse_subimage(argv[3], (ulong)fpga_data, &fit_addr, &fit_uname)) { |
c28c4d193 [new uImage] Add ... |
62 |
fpga_data = (void *)fit_addr; |
fc598412c cmd: fpga: Clean ... |
63 64 65 66 |
debug("* fpga: subimage '%s' from FIT image ", fit_uname); debug("at 0x%08lx ", fit_addr); |
c28c4d193 [new uImage] Add ... |
67 68 69 |
} else #endif { |
fc598412c cmd: fpga: Clean ... |
70 |
fpga_data = (void *)simple_strtoul(argv[3], NULL, 16); |
06297db06 FPGA: use debug()... |
71 72 |
debug("* fpga: cmdline image address = 0x%08lx ", |
fc598412c cmd: fpga: Clean ... |
73 |
(ulong)fpga_data); |
c28c4d193 [new uImage] Add ... |
74 |
} |
fc598412c cmd: fpga: Clean ... |
75 76 |
debug("%s: fpga_data = 0x%x ", __func__, (uint)fpga_data); |
c28c4d193 [new uImage] Add ... |
77 |
|
d4ca31c40 * Cleanup lowboot... |
78 |
case 3: /* fpga <op> <dev | data addr> */ |
fc598412c cmd: fpga: Clean ... |
79 |
dev = (int)simple_strtoul(argv[2], NULL, 16); |
06297db06 FPGA: use debug()... |
80 81 |
debug("%s: device = %d ", __func__, dev); |
d4ca31c40 * Cleanup lowboot... |
82 |
/* FIXME - this is a really weak test */ |
fc598412c cmd: fpga: Clean ... |
83 84 |
if ((argc == 3) && (dev > fpga_count())) { /* must be buffer ptr */ |
06297db06 FPGA: use debug()... |
85 86 |
debug("%s: Assuming buffer pointer in arg 3 ", |
fc598412c cmd: fpga: Clean ... |
87 |
__func__); |
c28c4d193 [new uImage] Add ... |
88 89 |
#if defined(CONFIG_FIT) |
fc598412c cmd: fpga: Clean ... |
90 91 |
if (fit_parse_subimage(argv[2], (ulong)fpga_data, &fit_addr, &fit_uname)) { |
c28c4d193 [new uImage] Add ... |
92 |
fpga_data = (void *)fit_addr; |
fc598412c cmd: fpga: Clean ... |
93 94 95 96 |
debug("* fpga: subimage '%s' from FIT image ", fit_uname); debug("at 0x%08lx ", fit_addr); |
c28c4d193 [new uImage] Add ... |
97 98 99 |
} else #endif { |
fc598412c cmd: fpga: Clean ... |
100 101 102 103 |
fpga_data = (void *)dev; debug("* fpga: cmdline image addr = 0x%08lx ", (ulong)fpga_data); |
c28c4d193 [new uImage] Add ... |
104 |
} |
06297db06 FPGA: use debug()... |
105 106 |
debug("%s: fpga_data = 0x%x ", |
fc598412c cmd: fpga: Clean ... |
107 |
__func__, (uint)fpga_data); |
d4ca31c40 * Cleanup lowboot... |
108 109 |
dev = FPGA_INVALID_DEVICE; /* reset device num */ } |
c28c4d193 [new uImage] Add ... |
110 |
|
d4ca31c40 * Cleanup lowboot... |
111 |
case 2: /* fpga <op> */ |
fc598412c cmd: fpga: Clean ... |
112 |
op = (int)fpga_get_op(argv[1]); |
d4ca31c40 * Cleanup lowboot... |
113 |
break; |
c28c4d193 [new uImage] Add ... |
114 |
|
d4ca31c40 * Cleanup lowboot... |
115 |
default: |
fc598412c cmd: fpga: Clean ... |
116 117 |
debug("%s: Too many or too few args (%d) ", __func__, argc); |
d4ca31c40 * Cleanup lowboot... |
118 119 120 |
op = FPGA_NONE; /* force usage display */ break; } |
a790b5b23 cmd_fpga: cleanup... |
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
if (dev == FPGA_INVALID_DEVICE) { puts("FPGA device not specified "); op = FPGA_NONE; } switch (op) { case FPGA_NONE: case FPGA_INFO: break; case FPGA_LOAD: case FPGA_LOADB: case FPGA_DUMP: if (!fpga_data || !data_size) wrong_parms = 1; break; case FPGA_LOADMK: if (!fpga_data) wrong_parms = 1; break; } if (wrong_parms) { puts("Wrong parameters for FPGA request "); op = FPGA_NONE; } |
d4ca31c40 * Cleanup lowboot... |
148 149 |
switch (op) { case FPGA_NONE: |
4c12eeb8b Convert cmd_usage... |
150 |
return CMD_RET_USAGE; |
d4ca31c40 * Cleanup lowboot... |
151 152 |
case FPGA_INFO: |
fc598412c cmd: fpga: Clean ... |
153 |
rc = fpga_info(dev); |
d4ca31c40 * Cleanup lowboot... |
154 155 156 |
break; case FPGA_LOAD: |
fc598412c cmd: fpga: Clean ... |
157 |
rc = fpga_load(dev, fpga_data, data_size); |
d4ca31c40 * Cleanup lowboot... |
158 |
break; |
30ce5ab04 * Patch by Gleb N... |
159 160 161 |
case FPGA_LOADB: rc = fpga_loadbitstream(dev, fpga_data, data_size); break; |
f0ff4692f Add FPGA Altera C... |
162 |
case FPGA_LOADMK: |
fc598412c cmd: fpga: Clean ... |
163 |
switch (genimg_get_format(fpga_data)) { |
d5934ad77 [new uImage] Add ... |
164 165 |
case IMAGE_FORMAT_LEGACY: { |
fc598412c cmd: fpga: Clean ... |
166 167 168 |
image_header_t *hdr = (image_header_t *)fpga_data; ulong data; |
32d7cdd36 fpga: Add support... |
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
uint8_t comp; comp = image_get_comp(hdr); if (comp == IH_COMP_GZIP) { ulong image_buf = image_get_data(hdr); data = image_get_load(hdr); ulong image_size = ~0UL; if (gunzip((void *)data, ~0UL, (void *)image_buf, &image_size) != 0) { puts("GUNZIP: error "); return 1; } data_size = image_size; } else { data = (ulong)image_get_data(hdr); data_size = image_get_data_size(hdr); } |
fc598412c cmd: fpga: Clean ... |
189 |
rc = fpga_load(dev, (void *)data, data_size); |
f0ff4692f Add FPGA Altera C... |
190 |
} |
d5934ad77 [new uImage] Add ... |
191 192 193 |
break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: |
c28c4d193 [new uImage] Add ... |
194 195 196 |
{ const void *fit_hdr = (const void *)fpga_data; int noffset; |
e6a857da7 fpga: constify to... |
197 |
const void *fit_data; |
c28c4d193 [new uImage] Add ... |
198 199 |
if (fit_uname == NULL) { |
fc598412c cmd: fpga: Clean ... |
200 201 |
puts("No FIT subimage unit name "); |
c28c4d193 [new uImage] Add ... |
202 203 |
return 1; } |
fc598412c cmd: fpga: Clean ... |
204 205 206 |
if (!fit_check_format(fit_hdr)) { puts("Bad FIT image format "); |
c28c4d193 [new uImage] Add ... |
207 208 209 210 |
return 1; } /* get fpga component image node offset */ |
fc598412c cmd: fpga: Clean ... |
211 212 |
noffset = fit_image_get_node(fit_hdr, fit_uname); |
c28c4d193 [new uImage] Add ... |
213 |
if (noffset < 0) { |
fc598412c cmd: fpga: Clean ... |
214 215 216 |
printf("Can't find '%s' FIT subimage ", fit_uname); |
c28c4d193 [new uImage] Add ... |
217 218 219 220 |
return 1; } /* verify integrity */ |
b8da83665 image: Rename fit... |
221 |
if (!fit_image_verify(fit_hdr, noffset)) { |
c28c4d193 [new uImage] Add ... |
222 223 224 225 226 227 |
puts ("Bad Data Hash "); return 1; } /* get fpga subimage data address and length */ |
fc598412c cmd: fpga: Clean ... |
228 229 230 231 |
if (fit_image_get_data(fit_hdr, noffset, &fit_data, &data_size)) { puts("Fpga subimage data not found "); |
c28c4d193 [new uImage] Add ... |
232 233 |
return 1; } |
fc598412c cmd: fpga: Clean ... |
234 |
rc = fpga_load(dev, fit_data, data_size); |
c28c4d193 [new uImage] Add ... |
235 |
} |
d5934ad77 [new uImage] Add ... |
236 237 238 |
break; #endif default: |
fc598412c cmd: fpga: Clean ... |
239 240 |
puts("** Unknown image type "); |
d5934ad77 [new uImage] Add ... |
241 242 |
rc = FPGA_FAIL; break; |
f0ff4692f Add FPGA Altera C... |
243 244 |
} break; |
d4ca31c40 * Cleanup lowboot... |
245 |
case FPGA_DUMP: |
fc598412c cmd: fpga: Clean ... |
246 |
rc = fpga_dump(dev, fpga_data, data_size); |
d4ca31c40 * Cleanup lowboot... |
247 248 249 |
break; default: |
fc598412c cmd: fpga: Clean ... |
250 251 |
printf("Unknown operation "); |
4c12eeb8b Convert cmd_usage... |
252 |
return CMD_RET_USAGE; |
d4ca31c40 * Cleanup lowboot... |
253 |
} |
fc598412c cmd: fpga: Clean ... |
254 |
return rc; |
4a9cbbe83 Initial revision |
255 |
} |
4a9cbbe83 Initial revision |
256 257 258 259 |
/* * Map op to supported operations. We don't use a table since we * would just have to relocate it from flash anyway. */ |
fc598412c cmd: fpga: Clean ... |
260 |
static int fpga_get_op(char *opstr) |
4a9cbbe83 Initial revision |
261 262 |
{ int op = FPGA_NONE; |
fc598412c cmd: fpga: Clean ... |
263 |
if (!strcmp("info", opstr)) |
4a9cbbe83 Initial revision |
264 |
op = FPGA_INFO; |
fc598412c cmd: fpga: Clean ... |
265 |
else if (!strcmp("loadb", opstr)) |
30ce5ab04 * Patch by Gleb N... |
266 |
op = FPGA_LOADB; |
fc598412c cmd: fpga: Clean ... |
267 |
else if (!strcmp("load", opstr)) |
4a9cbbe83 Initial revision |
268 |
op = FPGA_LOAD; |
fc598412c cmd: fpga: Clean ... |
269 |
else if (!strcmp("loadmk", opstr)) |
f0ff4692f Add FPGA Altera C... |
270 |
op = FPGA_LOADMK; |
fc598412c cmd: fpga: Clean ... |
271 |
else if (!strcmp("dump", opstr)) |
4a9cbbe83 Initial revision |
272 |
op = FPGA_DUMP; |
4a9cbbe83 Initial revision |
273 |
|
fc598412c cmd: fpga: Clean ... |
274 275 276 |
if (op == FPGA_NONE) printf("Unknown fpga operation \"%s\" ", opstr); |
4a9cbbe83 Initial revision |
277 278 |
return op; } |
fc598412c cmd: fpga: Clean ... |
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 |
U_BOOT_CMD(fpga, 6, 1, do_fpga, "loadable FPGA image support", "[operation type] [device number] [image address] [image size] " "fpga operations: " " dump\t[dev]\t\t\tLoad device to memory buffer " " info\t[dev]\t\t\tlist known device information " " load\t[dev] [address] [size]\tLoad device from memory buffer " " loadb\t[dev] [address] [size]\t" "Load device from bitstream buffer (Xilinx only) " " loadmk [dev] [address]\tLoad device generated with mkimage" |
c28c4d193 [new uImage] Add ... |
295 |
#if defined(CONFIG_FIT) |
fc598412c cmd: fpga: Clean ... |
296 297 298 299 300 |
" " "\tFor loadmk operating on FIT format uImage address must include " "\tsubimage unit name in the form of addr:<subimg_uname>" |
c28c4d193 [new uImage] Add ... |
301 302 |
#endif ); |